Agent Secret Store DocsSign up
🔑 Concepts

Scoped Tokens

Short-lived, least-privilege credentials for your agents — never expose your master key.

Why scoped tokens?

Your master agent key (ASS_AGENT_KEY) can read, write, and manage all secrets in your tenant. Sharing it with every agent is the equivalent of giving every employee a copy of the master safe combination.

Scoped tokens solve this with the principle of least privilege: each agent gets a token that expires, is limited to specific actions, and only covers the specific secrets it needs.

TOKEN LIFECYCLE

1
Orchestrator requests tokenUsing master key + scope + TTL
2
Vault validates + issues tokenApproval check if tier = sensitive/critical
3
Token passed to agentVia env var, message queue, or API response
4
Agent reads secret with tokenVault enforces scope + TTL + IP allowlist
5
Token expires / burnsAfter TTL or max_uses reached — no revocation needed

Scope format

Scopes use a three-part format:

secretsResource type (always "secrets")
:
actionread | write | delete | *
:
namespace/key_patternPath with optional glob (*)

Examples:

Shell
# Read any key in production/openai/*
secrets:read:production/openai/*

# Read a specific single key
secrets:read:production/stripe/webhook-secret

# Write secrets in a staging namespace
secrets:write:staging/*

# Read-write access to everything in a namespace
secrets:*:myapp/*

# Admin — full access (use sparingly)
secrets:*:*

Requesting a token

Python

request_token.py
import asyncio
from agentsecretstore import AgentVault

async def main():
    vault = AgentVault()  # Master key from ASS_AGENT_KEY

    # Minimal scope for a read-only inference agent
    token = await vault.request_token(
        scope="secrets:read:production/openai/*",
        ttl_seconds=3600,               # 1 hour; max 86400 (24h)
        description="GPT-4 inference agent",
        allowed_ips=["10.0.1.50"],      # Optional IP allowlist
        max_uses=None,                  # None = unlimited within TTL
    )

    print(token.value)      # "ast_tok_abc123..."
    print(token.expires_at) # 2025-01-15T11:30:00Z
    print(token.scope)      # "secrets:read:production/openai/*"

asyncio.run(main())

TypeScript

requestToken.ts
import { AgentVault } from '@agentsecretstore/sdk';

const vault = new AgentVault(); // reads ASS_AGENT_KEY

const token = await vault.requestToken({
  scope: 'secrets:read:production/openai/*',
  ttlSeconds: 3600,
  description: 'GPT-4 inference agent',
  allowedIps: ['10.0.1.50'],
});

console.log(token.value);     // "ast_tok_abc123..."
console.log(token.expiresAt); // "2025-01-15T11:30:00Z"

curl

Shell
curl -X POST https://api.agentsecretstore.com/v1/tokens \
  -H "Authorization: Bearer $ASS_AGENT_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "scope": "secrets:read:production/openai/*",
    "ttl_seconds": 3600,
    "description": "GPT-4 inference agent",
    "allowed_ips": ["10.0.1.50"]
  }'

Token parameters

ParameterTypeDefaultDescription
scopestringrequiredPermission scope string (see format above)
ttl_secondsint3600Token lifetime: 300 – 86400 seconds (5m – 24h)
descriptionstringnullHuman-readable label for audit trail
allowed_ipsstring[]nullOptional IP allowlist; null = any IP
max_usesint | nullnullMaximum retrieval count; null = unlimited within TTL
require_approvalboolfalseForce manual approval even for standard-tier secrets

Single-use tokens

Set max_uses=1 to create a burn-after-reading token. After the agent retrieves the secret once, the token is invalidated server-side.

Python
# Single-use token — expires after first successful retrieval
token = await vault.request_token(
    scope="secrets:read:production/stripe/api-key",
    ttl_seconds=300,   # 5 minutes
    max_uses=1,        # Burns after one use
    description="One-time payment processing token",
)

Use case: payment processing

Single-use tokens are ideal for one-time operations like payment processing, where you want to ensure the credential can only be used once per task invocation.

Using a scoped token

An agent uses a scoped token identically to the master key — just pass it as agent_key. The vault enforces scope restrictions server-side.

agent_usage.py
from agentsecretstore import AgentVault

# Agent receives scoped token from orchestrator
agent_token = "ast_tok_received_from_orchestrator"

# Use the token — NOT the master key
agent_vault = AgentVault(agent_key=agent_token)

secret = await agent_vault.get_secret("production/openai/api-key")
# Works if scope allows it

# This will raise AgentVaultPermissionError:
await agent_vault.get_secret("production/stripe/api-key")
# Scope "secrets:read:production/openai/*" doesn't cover stripe

Scope violations raise errors

Attempting to read a path outside the token's scope raises AgentVaultPermissionError (HTTP 403). Design your agents to catch this and request a new token with appropriate scope rather than silently failing.

IP allowlisting

Tokens can be restricted to specific source IP addresses. If a request arrives from an IP not in the allowlist, the vault returns HTTP 403 regardless of token validity. This provides defense in depth — even a stolen token is useless from the wrong host.

Both IPv4 and IPv6 are supported. CIDR notation (e.g. 10.0.0.0/24) is accepted for specifying subnets.

Approval Workflows

Set up approval gates for sensitive token requests.

Python SDK

Complete reference for request_token() and all parameters.