Worked Examples

Two end-to-end walkthroughs — an agent resolving a GitHub token to open an issue, and an agent resolving a Stripe key to create a charge.

Both walkthroughs follow the same shape: a config or prompt written with a placeholder, an agent that resolves the real value only at the moment it's needed, and a genuine authenticated API call made with it. Neither example ever writes the resolved secret to disk.

Example 1: Claude Code opens a GitHub issue

Goal: Claude Code, connected via MCP, resolves a GitHub token from the Agent Vault and uses it to open an issue on a real repository — without the token ever appearing in your prompt, your shell history, or a file.

Setup

  1. In SecretStash, store your GitHub personal access token as a variable named GITHUB_PROD_TOKEN in the production environment of the relevant application.
  2. Create an agent of type Claude Code, authorize it for that environment, and connect it as described in MCP Integration → Claude Code.
  3. In your project, reference the credential by placeholder — for example, in a NOTES.md or your prompt itself:
    Open a GitHub issue on dniccum/secret-stash titled "Agent Vault demo" using
    __SECRETSTASH_GITHUB_PROD_TOKEN__ for authentication. Resolve the token
    through the agent-vault MCP server; do not ask me for it.
    

Walkthrough

Claude Code recognizes the placeholder

Being connected to the agent-vault MCP server doesn't by itself teach Claude Code the __SECRETSTASH_*__ syntax — that's why the prompt above explicitly tells it to resolve the placeholder through the vault. With that instruction in place, Claude Code sees __SECRETSTASH_GITHUB_PROD_TOKEN__ and knows to call the MCP server for the real value instead of asking you for it.

The agent calls resolve_secret

{
  "tool": "resolve_secret",
  "arguments": { "variable": "GITHUB_PROD_TOKEN", "environment": "production" }
}

The Agent Vault checks the agent's authorized environments, unseals the production DEK, decrypts the variable, and returns the plaintext token in the tool result — visible only within that single tool call's context.

The agent makes the real call

Claude Code uses the resolved token to call the GitHub API directly:

curl -X POST \
  -H "Authorization: Bearer <resolved GITHUB_PROD_TOKEN>" \
  -H "Accept: application/vnd.github+json" \
  https://api.github.com/repos/dniccum/secret-stash/issues \
  -d '{"title": "Agent Vault demo"}'

GitHub creates the issue and returns its number and URL.

The resolution is audited

SecretStash records a secret_resolved entry: which agent, which environment, which variable, and when. See Verification & Operations.

Example 2: A script resolves a Stripe key to create a charge

Goal: A small Python script — not an MCP client — uses the REST fallback to resolve a Stripe secret key at runtime and creates a real charge, demonstrating the fallback path end-to-end.

Setup

  1. Store your Stripe secret key as a variable named STRIPE_SECRET_KEY in the production environment.
  2. Create an agent of type Custom, authorize it for that environment, and copy its API key.
  3. Write the script so the key only ever exists in memory, resolved right before use:
import os
import requests

AGENT_ID = os.environ["AGENT_ID"]
AGENT_TOKEN = os.environ["AGENT_API_KEY"]


def resolve_secret(name: str, environment: str) -> str:
    response = requests.get(
        f"https://secretstash.cloud/api/v1/agents/{AGENT_ID}/secrets/{name}",
        params={"environment": environment},
        headers={"Authorization": f"Bearer {AGENT_TOKEN}"},
        timeout=10,
    )
    response.raise_for_status()
    return response.json()["data"][name]


def create_charge(amount_cents: int, currency: str, source: str) -> dict:
    stripe_key = resolve_secret("STRIPE_SECRET_KEY", "production")

    response = requests.post(
        "https://api.stripe.com/v1/charges",
        auth=(stripe_key, ""),  # Stripe uses HTTP Basic auth with the secret key as the username
        data={"amount": amount_cents, "currency": currency, "source": source},
        timeout=10,
    )
    response.raise_for_status()
    return response.json()


if __name__ == "__main__":
    charge = create_charge(2000, "usd", "tok_visa")
    print(f"Created charge {charge['id']} for {charge['amount']} {charge['currency']}")

What happens

  1. create_charge calls resolve_secret, which hits GET /api/v1/agents/{agent}/secrets/STRIPE_SECRET_KEY?environment=production — the same endpoint documented in the REST API reference.
  2. The resolved key lives only in the stripe_key local variable, used immediately as the Basic-auth username on the Stripe request, and goes out of scope once create_charge returns.
  3. Stripe processes the charge and returns a charge object; the script prints its id, never the key.
  4. SecretStash records the resolution in the audit log, the same as the MCP example above.

Next steps