Reference

Security and keys

Evergreen signs transactions, so it holds a key. This page says where that key may live, what constrains it, and what protection is not implemented.

It holds a key

The engine’s implemented execution path uses a plain funded Ed25519 account that you supply. It is a testnet payer, and it pays the fee for the TTL extension. There is no arrangement in which the tool extends a TTL without a key that can sign.

This is worth stating plainly because the opposite is easy to imply. A design export for this project once carried a “Zero-Privilege Node · No Keys” panel; it was removed because it was not true.

Where a secret may live

RuleWhy
Environment variable, named in configThe config stores the variable’s NAME. A config carrying a key would be committed by someone, eventually, so the loader rejects anything that looks like one.
Never an argumentArguments appear in shell history and in process lists. --secret-env takes a name.
No .env auto-loadingA tool that silently reads a file from the working directory will one day read the wrong one.
Diagnostics never echo itError messages report shapes and outcomes, never file contents or credentials — so output is safe to paste into an issue.

What constrains the key

These controls apply on the normal execution path and are what stands between a misconfiguration and an unintended submission.

  • Explicit-submit gating — nothing is sent without --submit or an explicit live mode.
  • Selected-key and target checks — only the entries named are touched.
  • Network validation by passphrase comparison, not by label.
  • Configured fee caps, applied per bump.
  • Protected-subject guards, which refuse regardless of configuration.
  • Signed-envelope validation before submission.
  • Post-state checks, so a result is verified rather than assumed.

What is not built

There is no policy signer. A policy signer is represented in the config and type seam for future adapters, and the current engine rejects that payer kind. It is not an activation switch for an implemented provider.

The planned direct adapter was investigated and found not to deliver the protection it promised: Evergreen signs a native ExtendFootprintTTL transaction whose fee payer is a Stellar G-address, while passkey-style wallet policies authorize contract invocations through a wallet’s __check_auth. Those are different authorization paths, so installing that wallet does not constrain the separate transaction key that pays the native fee.

The recorded disposition is no-go for the direct adapter, no automatic pivot to another framework, and full scoping deferred to the next scope of work. No alternative signing architecture becomes approved merely because the original path failed.

What this means for you

Fund the payer with what you are willing to spend on rent and nothing more. The fee caps bound a single bump; the account balance is what bounds the total. Everything above constrains correct operation — none of it is a substitute for a payer that cannot afford a mistake.

The full record, including the feasibility report and the decision that closed it, is in docs/POLICY-SIGNER.md and ADR-002.