Skip to main content

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

This:
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.
It prints an 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

A passkey-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.