Why this doesn’t need a new policy contract per user
agent-policy.configure(wallet, allow_list, cap) is authenticated by the
wallet, not by an admin on the policy contract — see
Deploying a Policy. One agent-policy
instance already serves any number of wallets, each with its own
allow-list and cap. stellar agentgate init points new wallets at the
canonical testnet deployment
by default, so onboarding is a single local command instead of a contract
deployment.
One command
1
Reads your owner key transiently
Via
stellar keys secret owner — never written to .env or anywhere on disk by this command. Only used in-process for the four setup calls below, then discarded.2
Generates and funds a fresh agent-signer
A brand-new Ed25519 key, funded via friendbot — it needs its own balance because
stellar agentgate mcp later uses it to pay fees on every real tool call.3
Deploys a smart wallet, if you didn't pass --wallet
Using your owner key as the wallet’s initial signer.
4
Wires the policy gate
add_signer(agent-signer) → add_signer(agent-policy) → agent-policy.configure(...) → update_signer(agent-signer, limits=scoped to the target + policy) — the exact sequence Deploying a Policy describes by hand.AGENT_SIGNER_SECRET (and the wallet/policy IDs) to paste into
your own .env — never OWNER_SECRET. That key is deliberately low-value:
it’s powerless alone, bounded entirely by the policy’s allow-list, so it’s a
much smaller trust ask than pasting a real account’s secret. See
Why the raw secret has to be local.
Flags
--target and --allow currently scope to one contract per wallet — matching everything this project’s SignerLimits helper supports today. Gating multiple contracts from one wallet needs a small encoder addition, not yet built.Why the raw secret has to be local
Apasskey-kit smart wallet’s __check_auth expects a custom-encoded
Signatures argument that only a process holding the actual private key
can build — stellar-cli’s OS-keychain-backed secure store can’t be used
here because it never exposes the raw key material (see the
Security Model). That’s true for both the human
owner’s key and the agent’s key alike — there’s no version of this signing
path where a hosted service or a keychain-backed key could sign on the
agent’s behalf instead. What init controls is which secret ends up on
disk: OWNER_SECRET (full authority over the wallet) is fetched, used, and
discarded in-memory; only AGENT_SIGNER_SECRET (policy-bounded, replaceable,
low blast radius even if it leaked) gets written anywhere.