Secrets

Per-agent environment variables — API keys, webhook secrets, and other credentials a single agent needs to call out to its tools.

Overview

Secrets are per-agent environment variables. A single agent gets exactly the credential it needs — a Stripe API key, a webhook signing secret, a third-party token — and no other agent in the same project can read it.

A secret is a (key, value, description) triple scoped to one agent. The platform encrypts the value at rest and never returns it to a client after you save it. The only path back to the value is the agent itself, at runtime, through the tools it's calling.

That isolation is the point. One agent's credential is one agent's credential — by the platform's design, not by convention.

Use secrets to:

  • give one agent access to a credential another agent in the same project doesn't need
  • rotate a value without redeploying the agent
  • keep API keys out of agent.yaml and routine source

For project-wide configuration shared across every agent, use app environment variables instead.


When to use secrets vs other primitives

Need Use
Per-agent API key (Stripe, Twilio, custom service) Secrets (this page)
Per-agent OAuth token to GitHub or Slack Installations
Org-wide Slack bot or GitHub App Org-wide integrations
Project-wide config used by every agent App environment variables

The simplest test: one agent needs the value, the value is sensitive — it belongs in Secrets.


Security model

Three guarantees the platform makes:

  1. Write-only. Once you save a value, the platform never returns it to a client. The list view shows a masked preview (****1234) so you can confirm which credential is which without exposing cleartext.
  2. Per-agent scope. Secrets are owned by one agent. Other agents in the same project — including ones owned by the same user — have no read path.
  3. Modify gate. Only the agent's owner or an org admin can list, create, update, or delete secrets. The portal hides the section from anyone else; the API returns 403.

To verify a value, rotate the secret and re-paste it. The platform never returns plaintext after creation — that's the property that protects you.


Manage from the CLI

The CLI commands take --agent <id> for the create/list paths and the secret's own ID for describe/update/delete:

# list secrets attached to an agent (values come back masked)
archastro list agentenvvars --agent <agent_id>

# create one
archastro create agentenvvar \
  --agent <agent_id> \
  --key STRIPE_API_KEY \
  --value sk_live_... \
  --description "Live Stripe key for Customer Success Helper"

# rotate the value (description stays as-is unless you pass it too)
archastro update agentenvvar <secret_id> --value sk_live_rotated_...

# update only the description
archastro update agentenvvar <secret_id> --description "Rotated 2026-05-05"

# inspect one secret
archastro describe agentenvvar <secret_id>

# remove
archastro delete agentenvvar <secret_id>

describe returns the cleartext value only when the caller is the agent's owner or an org admin invoking the platform-level read endpoint. The list view always returns masked previews, regardless of caller.


Use a secret from an agent

The platform surfaces secrets to the agent at runtime as environment variables. The key you set in the portal or CLI is the variable name the agent's tools see.

For example, after creating STRIPE_API_KEY on an agent, a script tool reads it from its process environment the same way it reads any other env var:

const stripeKey = process.env.STRIPE_API_KEY;

You don't declare the secret in agent.yaml. The platform resolves it by ID at run time, so you rotate or replace the value without redeploying the agent definition.


A concrete example

Customer Success Helper needs to look up a Stripe customer to answer a support question. No other agent in your project needs the Stripe key.

The flow:

  1. Create the secret on the helper agent only:

    archastro create agentenvvar \
      --agent <helper_agent_id> \
      --key STRIPE_API_KEY \
      --value sk_live_... \
      --description "Read-only restricted key for support lookups"
    
  2. Confirm it's there with the masked value:

    archastro list agentenvvars --agent <helper_agent_id>
    
  3. The agent's Stripe-lookup tool reads process.env.STRIPE_API_KEY and goes about its business.

  4. When the key rotates 90 days later, run update — no redeploy:

    archastro update agentenvvar <secret_id> --value sk_live_new_...
    

A second agent in the same project that doesn't have its own Stripe secret has no access. It can't see the key, can't list it, can't call out with it.


Best practices

  1. Restrict the credential before you store it. Use the narrowest scopes that still let the agent do its job — read-only Stripe key for lookups, channel-restricted Slack token, single-repo GitHub PAT. The platform isolates per-agent; restricted scopes shrink the blast radius further.
  2. Use the description field. The next operator (or future you) needs to know what a key is for and whether it's safe to rotate. Live Stripe key for support lookups, rotated 2026-05-05 is the kind of description that pays for itself the first time someone audits an agent.
  3. Rotate on suspicion. A value that might have leaked is a value to rotate. Reset it at the provider, then update agentenvvar --value <new>. Pasting the original back wastes the rotation.
  4. Keep secret values out of agent.yaml. Reference the idea of the secret in agent docs or comments if it helps a reader. The actual value lives only in Secrets.
  5. Audit by listing. archastro list agentenvvars --agent <id> is the cheapest read on what credentials an agent currently carries. Run it before sharing an agent across teams.

Where to go next

  1. Read Installations when the credential you need is a managed OAuth token (GitHub, Slack) rather than a raw API key.
  2. Read Tools for how the agent invokes external systems with these credentials.
  3. Read Portal for the broader operator workflow that the Secrets tab fits into.