Skip to main content
Glama
nyx-builds

agent-secrets

by nyx-builds
README.md
# agent-secrets

Encrypted secrets management MCP server for AI agents. Store, retrieve, rotate, audit, auto-rotate, backup, and restore API keys, tokens, and credentials — all encrypted at rest with AES-128 (Fernet).

## Why

AI agents need access to API keys, tokens, and credentials. Hardcoding them or passing via env vars is insecure and unmanageable at scale. `agent-secrets` provides a single encrypted vault with audit trails, access policies, versioning, expiration, rotation scheduling, auto-rotation, strength auditing, and backup/restore — exposed as **43 MCP tools** any agent can call.

## Features

### Core (v0.1.0)
- **AES-128 encryption at rest** (Fernet: AES-128-CBC + HMAC-SHA256)
- **Full audit log**: every access tracked
- **Access policies**: allow/deny patterns, type restrictions
- **Secret rotation**: rotate with history
- **CLI + MCP server**: use from terminal or any MCP-compatible agent

### v0.2.0 — Lifecycle Management
- **Secret versioning**: every update/rotation creates a version record. Roll back to any previous version, view history, retrieve old values.
- **Auto-expiration (TTL)**: set `expires_at` on secrets. Sweep expired secrets in batch, or check expiry status with configurable "expiring soon" thresholds.
- **Rotation scheduling**: set interval-based rotation policies per secret. Check which secrets are overdue for rotation.
- **Auto-rotation execution**: `run_auto_rotation` generates new values and rotates all due secrets with `auto_rotate=True` in one call — designed for cron/scheduled execution.
- **Secret strength auditing**: decrypt and analyze entropy of all stored secrets. Flag weak secrets below a configurable entropy threshold.
- **Vault backup/restore**: export the entire vault (encrypted values stay encrypted) as JSON. Restore in merge or replace mode. Same key required for decryption.
- **CSPRNG secret generator**: generate strong passwords, API keys, tokens, passphrases, and UUIDs with entropy estimation and strength classification.

### v0.3.0 — Zero-Exposure Access
- **Read-once secrets**: values cryptographically destroyed after first read (ciphertext + all versions overwritten). `get_secret` refuses read-once secrets; `consume_secret` is the explicit, intentional path.
- **Secret leases**: time-boxed, use-limited, revocable access tokens (`asl_...`) — hand a token to a subprocess instead of the raw secret.
- **Vault-side templates**: render `{{secret.NAME}}` placeholders inside the vault; plaintext never enters agent context until render time.
- **Secret redaction**: scan any outgoing text for known secret values and replace with `[REDACTED:name]` before sharing.

## Quick start

```bash
pip install agent-secrets

# CLI — basic operations
agent-secrets store OPENAI_API_KEY sk-... --type api_key --tag prod
agent-secrets get OPENAI_API_KEY --show
agent-secrets list
agent-secrets rotate OPENAI_API_KEY
agent-secrets audit

# v0.2.0 CLI — lifecycle management
agent-secrets generate password --length 32 --store new-db-password
agent-secrets generate api-key --prefix sk --store client-key
agent-secrets generate passphrase --words 5

agent-secrets versioning list OPENAI_API_KEY
agent-secrets versioning rollback OPENAI_API_KEY 2

agent-secrets expiry check --within 48
agent-secrets expiry sweep

agent-secrets rotation set OPENAI_API_KEY 30 --auto
agent-secrets rotation list
agent-secrets rotation due
agent-secrets rotation auto-rotate --kind password

agent-secrets security strength --min-entropy 80
agent-secrets security strength --weak-only

agent-secrets backup export --output vault-backup.json
agent-secrets backup import vault-backup.json --mode merge

# MCP server
agent-secrets serve --db ~/.agent-secrets/vault.db
```

## MCP tools (43)

### Core Operations (14)
| Tool | Description |
|------|-------------|
| `store_secret` | Store a new encrypted secret |
| `get_secret` | Retrieve a secret value |
| `list_secrets` | List all secrets (metadata only) |
| `update_secret` | Update value/metadata |
| `rotate_secret` | Rotate to new value |
| `revoke_secret` | Revoke a secret |
| `delete_secret` | Permanently delete |
| `search_secrets` | Search by name/description/tag |
| `get_audit_log` | View access history |
| `create_policy` | Create access policy |
| `list_policies` | List policies |
| `check_access` | Check policy permission |
| `batch_store` | Store multiple secrets |
| `vault_stats` | Vault statistics |

### Secret Versioning (4)
| Tool | Description |
|------|-------------|
| `get_versions` | Version history for a secret |
| `get_version_value` | Retrieve plaintext of a specific version |
| `rollback_version` | Roll back to a previous version's value |
| `delete_version` | Delete a historical version (not current) |

### Auto-Expiration / TTL (2)
| Tool | Description |
|------|-------------|
| `expire_secrets` | Sweep: mark all expired secrets |
| `check_expiry` | Check expiry status with alerts |

### Rotation Scheduling (4)
| Tool | Description |
|------|-------------|
| `set_rotation_policy` | Set interval-based rotation schedule |
| `list_rotation_policies` | List all rotation policies |
| `check_rotation_due` | Check which secrets are overdue |
| `delete_rotation_policy` | Remove a rotation policy |

### Secret Generator (2)
| Tool | Description |
|------|-------------|
| `generate_secret` | Generate password/api_key/token/passphrase/uuid |
| `generate_and_store` | Generate + store atomically |

### Auto-Rotation, Audit & Backup (4) — NEW in v0.2.0
| Tool | Description |
|------|-------------|
| `run_auto_rotation` | Execute auto-rotation for all due secrets with auto_rotate enabled |
| `audit_strength` | Audit entropy/strength of all secrets, flag weak ones |
| `backup_vault` | Export entire vault as encrypted JSON backup |
| `restore_vault` | Restore from backup (merge or replace mode) |

### Zero-Exposure Access (13) — NEW in v0.3.0
| Tool | Description |
|------|-------------|
| `store_secret_read_once` | Store a secret that self-destructs after its first read |
| `consume_secret` | Explicitly consume a read-once secret (get_secret refuses them) |
| `grant_lease` | Grant a time-boxed, revocable lease token (`asl_...`) for a secret |
| `redeem_lease` | Redeem a lease token for the value (single-use by default) |
| `revoke_lease` | Kill a lease immediately, before expiry |
| `extend_lease` | Renew an active lease — push its expiry out (Vault-style renewal; never shortens) |
| `list_leases` | List leases (filter by secret, status) |
| `expire_leases` | Sweep overdue active leases to expired |
| `render_template` | Render `{{secret.NAME}}` placeholders vault-side (adhoc text or saved template) |
| `redact_text` | Scan text for leaked secret values, replace with `[REDACTED:name]` |
| `create_template` | Create a reusable secret-substitution template |
| `list_templates` | List saved templates |
| `delete_template` | Delete a template |

## v0.3.0 — Zero-Exposure Access

The theme of v0.3.0: **secret values should only exist where they are actually needed.**

1. **Read-once secrets** — store enrollment tokens, OTPs, recovery codes that are
   cryptographically destroyed (ciphertext + all versions overwritten) on first read.
   The MCP `get_secret` tool *refuses* read-once secrets and points the caller at
   `consume_secret`, so an agent can never accidentally burn a one-time token by
   just "checking" it. `engine.get_meta()` inspects status without consuming.

2. **Secret leases** — time-boxed (`ttl_seconds`), use-limited (`max_uses`), revocable
   access tokens (`asl_...`). Hand a lease to a subprocess or another agent instead of
   the raw value; revoke it any time, or **renew** it with `extend_lease` when a task
   runs long (new expiry = later of now/current expiry + added seconds — renewal never
   shortens a lease; only active leases are renewable). Every grant/redeem/revoke/renew
   is audited.

3. **Templates** — store config skeletons like
   `postgres://admin:{{secret.db-password}}@{{secret.db-host}}:5432/prod` and render
   them vault-side. The plaintext never touches agent context until render time, and
   render is audited without recording rendered values.

4. **Redaction** — the safety net. Scan any text for known secret *values* and replace
   them with `[REDACTED:name]` before the text leaves your control (logs, tickets,
   model prompts). Revoked and consumed secrets are excluded from scanning.

## Architecture

```
┌──────────────────────────────────────────────┐
│  MCP Server (43 tools) / CLI                 │
├──────────────────────────────────────────────┤
│  SecretsEngine (business logic)              │
├──────────────────────────────────────────────┤
│  Vault (encrypted storage — SQLite + Fernet) │
│  Generator (CSPRNG secret generation)        │
└──────────────────────────────────────────────┘
```

- **Encryption**: Fernet symmetric encryption (AES-128-CBC + HMAC-SHA256). Master key derived via PBKDF2HMAC (480,000 iterations).
- **Storage**: SQLite with WAL mode for concurrent reads. Eight tables: secrets, audit_log, policies, secret_versions, rotation_policies, leases, templates (+ lease audit in audit_log).
- **Generator**: Uses Python's `secrets` module (CSPRNG) for all generation. Includes curated EFF-style word list for passphrases.

## Test coverage

300 tests covering storage, engine, server, versioning, expiry, rotation, auto-rotation, strength auditing, backup/restore, the generator, read-once destruction (including direct-DB recovery attempts), leases, templates, and redaction.

## License

MIT