Credential Vault
AES-256-GCM encrypted secret storage with a proxy pattern that keeps credentials out of agent context entirely. Agents never see secrets — the infrastructure resolves, injects, and sanitizes on their behalf.
Overview Architecture
The credential vault stores secrets encrypted at rest using AES-256-GCM. Agents never have access to credentials directly. The vault key lives in the tool executor process. When a tool needs credentials, the infrastructure resolves them from the vault and injects them into the API call.
This architecture ensures that even if an agent's context is leaked or logged, no secrets are exposed. The entire credential lifecycle — decryption, injection, and cleanup — happens in a layer the agent cannot observe.
How It Works Proxy Pattern
The credential vault uses a proxy pattern to keep secrets out of agent context. The agent only sees business parameters in and a sanitized result out. At no point does the agent have access to any token, API key, or credential. The entire credential lifecycle happens in the tool executor layer.
Agent -> tool("create_issue", { repo, title }) -> Tool Executor -> Vault.resolve("github_token") -> HTTP call with token -> sanitized result -> Agent
Setup Configuration
Environment Variable
Set MAXIMUS_VAULT_KEY as an environment variable. This is the master key used to derive the encryption key (via scrypt) for encrypting and decrypting credentials.
# Linux/macOS export MAXIMUS_VAULT_KEY="your-secure-vault-key-here" # Or in a .env file (never commit to git) MAXIMUS_VAULT_KEY=your-secure-vault-key-here
Storage Recommendations
.env file (add to .gitignore) or export in shell profileInteractive Fallback
For local development, if MAXIMUS_VAULT_KEY is not set and the process is running in an interactive terminal (TTY), the engine will prompt for the vault key. This fallback is disabled in non-interactive environments (CI, background processes) where stdin.isTTY is false.
Enter vault key (MAXIMUS_VAULT_KEY): _
Adding Credentials API
Create & Populate a Vault
Use the CredentialVault API to add credentials programmatically:
import { CredentialVault } from "@maximus/vault"; // Create or open a vault const vault = new CredentialVault(process.env.MAXIMUS_VAULT_KEY!); // Add credentials vault.set("github_token", "ghp_your_token_here", { description: "GitHub PAT with repo scope", }); vault.set("slack_webhook", "https://hooks.slack.com/services/T00/B00/xxx", { description: "Slack webhook for #engineering channel", }); // Save encrypted vault to disk vault.save("config/credentials.enc");
Load & Manage
Load an existing vault, list stored credentials (metadata only), check existence, or remove entries:
const vault = CredentialVault.load("config/credentials.enc", process.env.MAXIMUS_VAULT_KEY!); // List stored credentials (metadata only, no values) const creds = vault.list(); // [{ name: "github_token", description: "...", createdAt: "...", updatedAt: "..." }] // Check if a credential exists vault.has("github_token"); // true // Remove a credential vault.delete("github_token");
Referencing in Skills YAML
Skills reference credentials by name. The ref must match the name used in vault.set(). At tool execution time, template variables are replaced with decrypted values from the vault. The agent never sees the actual token value.
# In a skill YAML file credentials: - ref: github_token inject_as: GITHUB_TOKEN tools: - name: github_create_issue credentials: - ref: github_token inject_as: GITHUB_TOKEN action: type: http method: POST url: "https://api.github.com/repos/{{repo}}/issues" headers: Authorization: "Bearer {{GITHUB_TOKEN}}"
Output Sanitization PostToolUse
Tool output is automatically sanitized to strip leaked secrets before being returned to the agent. The sanitizer runs as a PostToolUse hook on every SDK session. Patterns are ordered from specific to generic to minimize false positives.
| Pattern | Replacement | Example |
|---|---|---|
Anthropic API keys sk-ant-... |
[REDACTED_ANTHROPIC_KEY] |
sk-ant-abc123... |
OpenAI API keys sk-... |
[REDACTED_API_KEY] |
sk-proj-abc123... |
GitHub tokens ghp_ gho_ ghu_ ghs_ ghr_ |
[REDACTED_GH_TOKEN] |
ghp_abc123... |
AWS access keys AKIA... |
[REDACTED_AWS_KEY] |
AKIAIOSFODNN7EXAMPLE |
| Bearer / token / key assignments | [REDACTED] |
Bearer eyJ... |
| Connection strings | [REDACTED_CONN_STRING] |
postgres://user:pass@host/db |
| Authorization headers | Authorization: [REDACTED] |
Authorization: Basic abc... |
| Long hex strings (40+ chars) | [REDACTED_HASH] |
SHA hashes, hex-encoded tokens |
Security Model Defense in Depth
The credential vault implements a three-layer defense ensuring credentials remain secure throughout the entire agent lifecycle: at rest, during execution, and in output.
AES-256-GCM
Credentials are encrypted using AES-256-GCM with a key derived from the vault key via scrypt (with a random salt). Each credential gets its own random initialization vector (IV), preventing identical plaintext from producing identical ciphertext.
RUNTIME
Credentials are never present in the agent's context. The CredentialProxy resolves credentials from the vault only at tool execution time, in the tool executor process. The vault key itself is blocked from the SDK subprocess environment.
Strips sensitive environment variables before spawning agent processes. Blocked keys include: MAXIMUS_VAULT_KEY, VAULT_KEY, ENCRYPTION_KEY, and MASTER_KEY.
filterEnvForSdk strips vault keys from subprocess env before spawningPOSTTOOLUSE
Even if a credential somehow appears in a tool's output (e.g., an error message containing a token), the PostToolUse sanitizer hook catches and redacts it before the output reaches the agent. The regex pipeline processes patterns from most-specific to most-generic to minimize false positives.
PostToolUse — runs on every SDK session after every tool callTogether, these three layers ensure that credentials remain secure throughout the entire agent lifecycle: at rest (encrypted on disk), during execution (proxy pattern isolates the agent), and in output (sanitizer catches any leaks before they reach the context window).