Skip to main content

Security and keys for agents

An AI assistant with a signing key can move real assets on your behalf, on the strength of text it read somewhere: a web page, a token description, a chat message. Treat the key as the only thing standing between that text and your wallet, and give the assistant as little as the task needs.

Rules​

  1. Start without a key. Every read tool works without PRIVATE_KEY: pools, prices, balances, quotes, documentation. A server without a key cannot sign, whatever the assistant is told.
  2. Never paste a private key into a chat, a prompt, a command line or a file the assistant can read. Anything in the conversation is sent to the model provider and kept in transcripts. A key belongs in the server process's environment (see below), nowhere else.
  3. Use a dedicated wallet. Fund it with what the task needs and no more, and use a key made for testing while you try workflows on stage.
  4. Learn on stage, the test network. ENVIRONMENT is prod (the default) or stage, nothing else. Production writes are real. A server started without ENVIRONMENT is on prod.
  5. Quote, read the quote, then write. Ask the assistant to run the quote or calculate tool of an action first and to show you the result before it signs anything. Review each write; do not grant blanket approval to a tool in your client's permission settings for a server that can sign.
  6. Select only the toolsets the task needs. A server with GALA_TOOLSETS=core,gswap has no way to create a Launchpad token. Be clear about what this does not do: toolsets narrow the tools, they do not make a toolset read-only. core still contains the GALA transfer, so only leaving out PRIVATE_KEY makes the server read-only.

Where a key may live​

PlaceAcceptable?
The server's env block in a configuration file only you can read, for a test walletYes, with care: the file holds a secret in clear text. Do not commit it or sync it.
An environment variable of your shell, referenced from the client configuration (${NAME} in a project .mcp.json)Yes: nothing secret is in the file you commit.
A secret manager that launches the client with the variable setYes.
A chat message, a prompt, a README, an example or a shared fileNo.
A tool argument (see set_wallet below)Avoid.

set_wallet puts the key in the conversation​

The tool gala_launchpad_set_wallet takes the private key as an argument, so calling it means the key passes through the model and into the transcript. It exists for the case where a person at the keyboard configures a session on a machine they control. When you can, set PRIVATE_KEY in the server's environment instead and never call it:

gala_launchpad_has_wallet({})
gala_launchpad_get_wallet({})

Those two report whether a wallet is configured and which address it is, without a key in either call.

Addresses​

A GalaChain user is written eth|<40 hex digits> (the checksummed spelling), or client|<id>. The server also accepts a checksummed 0x<40 hex> and converts it. eth|0x<hex> is refused: it is not an address form, and the refusal names the correct spelling. When an assistant composes an address, the server validates it before anything is signed, and a refused address is a prompt to look the address up, not to try another spelling. Amounts are whole tokens as decimal strings, so '1.5' is one and a half tokens.

What the code enforces​

These statements are held by tests of this package, not by this page:

  • The environment is prod (the default) or stage; anything else is refused. Enforced by packages/gala-mcp-server/src/session/__tests__/session.test.ts ("ENVIRONMENT is prod (default) or stage; anything else is refused").
  • A malformed key is refused and changes nothing. Enforced by packages/gala-mcp-server/src/session/__tests__/session.test.ts ("refuses a malformed key and changes nothing").
  • The server refuses eth|0x<hex>: its address checks take exactly the forms the Launchpad SDK takes. Enforced by packages/gala-mcp-server/src/__tests__/address-forms-sync.test.ts ("the server address checks take exactly the forms launchpad-sdk takes").
  • A toolset that is not selected is never loaded. Enforced by packages/gala-mcp-server/src/toolsets/__tests__/module-graph.test.ts ("module graph per selection").
  • Switching the environment changes nothing if any client cannot be built. Enforced by packages/gala-mcp-server/src/session/__tests__/session.test.ts ("one participant that cannot be built refuses the switch: the others are aborted, nothing changes").

If a key was exposed​

Treat it as lost: move the funds to a new wallet and stop using the old key. Removing it from a file or a transcript does not undo that it was sent.