Credential Vault
The agent-id-vault plugin provides encrypted storage for external service credentials (GitHub, AWS, Slack, etc.). Each credential is encrypted with a key derived from the agent’s Ed25519 private key — credentials are only readable on the same machine as the bound agent.
Why a Vault
AI agents need credentials to interact with external services. Without a vault, humans end up pasting API keys into chat, hardcoding secrets in configs, or giving agents unrestricted access. The vault solves this:
- Store once, use later — Human provides the credential once; the agent retrieves it in any future session
- Encrypted at rest — AES-256-GCM encryption, key never leaves the agent’s machine
- Bound to the agent key — Decryption requires the agent’s private key, so credentials are only readable where that key lives
- Irrecoverable by design — If the agent’s keypair is deleted, the credentials are gone
Encryption Model
The encryption key is derived deterministically from the agent’s main private key, then used with AES-256-GCM and a fresh IV per write:
Agent's Ed25519 private key (raw PKCS8 DER bytes)
│
▼ HKDF-SHA256 (salt: "agent-id-vault-v1", info: "vault-encryption")
│
▼ 256-bit symmetric key
│
▼ AES-256-GCM (fresh 96-bit IV per write)
│
▼ Ciphertext + 128-bit authentication tagThe ciphertext, IV, and tag are stored hex-encoded inside an encrypted block of a per-service JSON record (see File Format).
Storing Credentials
Run the vault plugin’s store subcommand. There are several ways to provide the secret; the vault reads them in this fixed order and uses the first one present:
--credential-file <path>— read from a file (most secure; never touches the command line)--credential-env <VAR>— read from an environment variable- stdin — piped in, e.g.
echo 'secret' | ... store ... --credential <value>— inline flag (fallback; visible in the process list)
Option A: From File (Most Secure)
The secret never appears on the command line or in chat logs:
echo 'ghp_xxx' > /tmp/tok && chmod 600 /tmp/tok
node plugins/agent-id-vault/bin/cli.mjs store --service github --type api-key --credential-file /tmp/tok
rm /tmp/tokOption B: From Environment Variable
GITHUB_TOKEN=ghp_xxx node plugins/agent-id-vault/bin/cli.mjs store \
--service github --type api-key --credential-env GITHUB_TOKENOption C: Via Stdin Pipe
echo 'ghp_xxx' | node plugins/agent-id-vault/bin/cli.mjs store --service githubA successful store prints:
{ "ok": true, "service": "github", "type": "api-key", "updated": false }updated is true when an existing credential for the same service was replaced.
Security Guidance
Never accept a secret pasted into chat — transcripts persist. Prefer --credential-file or --credential-env. The --credential flag puts the secret in the process argument list, where it is visible via ps.
| Method | Secret in ps? | In shell history? | In chat log? |
|---|---|---|---|
--credential-file | No | No | No |
--credential-env | No | Depends on shell | No |
| stdin pipe | No | The echo line, yes | No |
--credential flag | Yes | Yes | No |
| Paste in chat | No | No | Yes |
Credential Types
Use --type to tag what kind of credential it is. The flag is a free-form descriptive tag — it is stored verbatim and defaults to api-key if omitted. The values below are conventions, not a validated enum:
| Type | Description | Notes |
|---|---|---|
api-key | API key / personal access token | Default |
password | Username + password pair | Use with --username |
oauth | OAuth access/refresh token | |
bearer | Bearer token | |
custom | Anything else |
--username and --url are optional metadata hints that can be attached to any type.
Store Examples
# GitHub personal access token (from file)
echo 'ghp_abc123' > /tmp/cred && chmod 600 /tmp/cred
node plugins/agent-id-vault/bin/cli.mjs store --service github --type api-key --credential-file /tmp/cred
rm /tmp/cred
# AWS credentials (from env)
node plugins/agent-id-vault/bin/cli.mjs store --service aws --type api-key \
--credential-env AWS_SECRET_ACCESS_KEY \
--username "$AWS_ACCESS_KEY_ID" \
--url "https://aws.amazon.com"
# Service with username + password (piped)
echo 'mypassword' | node plugins/agent-id-vault/bin/cli.mjs store --service docker-hub \
--type password --username "myuser" --url "https://hub.docker.com"
# OAuth token
node plugins/agent-id-vault/bin/cli.mjs store --service slack --type oauth --credential-env SLACK_BOT_TOKENRetrieving Credentials
node plugins/agent-id-vault/bin/cli.mjs get --service githubReturns:
{
"ok": true,
"service": "github",
"type": "api-key",
"credential": "ghp_xxx...",
"url": null,
"username": null
}url and username are always present, defaulting to null when unset.
Use the credential value in API calls:
TOKEN=$(node plugins/agent-id-vault/bin/cli.mjs get --service github | jq -r .credential)
curl -H "Authorization: Bearer $TOKEN" https://api.github.com/userThe credential is decrypted in memory and never written to disk in plaintext.
Listing Credentials
node plugins/agent-id-vault/bin/cli.mjs listReturns service metadata only — the credential values are never decrypted or returned:
{
"ok": true,
"credentials": [
{
"service": "github",
"type": "api-key",
"url": null,
"username": null,
"createdAt": 1700000000000,
"updatedAt": 1700000000000
}
]
}Removing Credentials
node plugins/agent-id-vault/bin/cli.mjs remove --service githubUpdating Credentials
Run store again with the same --service name. The existing credential is replaced and the response reports "updated": true; the original createdAt timestamp is preserved while updatedAt advances.
File Format
Each credential is stored as its own JSON file under the agent state directory at vault/<service>.json (the vault/ directory is created with mode 0700; each file is written with mode 0600). The file is a metadata record wrapping the encrypted secret:
{
"version": 1,
"service": "github",
"type": "api-key",
"url": null,
"username": null,
"encrypted": { "iv": "…hex…", "data": "…hex…", "tag": "…hex…" },
"createdAt": 1700000000000,
"updatedAt": 1700000000000
}Only the encrypted block holds the secret; the surrounding metadata is plaintext.
Next Steps
- External Services Auth — Use vault credentials with external services
- CLI Reference — Full vault command reference