Stop putting LLM API keys in .env files.
AgentKMS is a cryptographic proxy and credential vending service that keeps secrets out of your code, off your disk, and away from attackers. Works as an MCP server for AI coding tools or as a standalone REST API.
That's it. Claude Code can now securely fetch LLM keys, sign payloads, and encrypt data — all over mTLS, zero secrets on disk.
Also works with Cursor, Windsurf, and any MCP-compatible tool.
AI Tool ──MCP/stdio──▶ agentkms-mcp ──mTLS──▶ AgentKMS ──▶ Vault Backend
│
├── session token (15-min TTL)
├── short-lived LLM API keys
├── sign / encrypt / decrypt
└── full audit trail
Private key material never leaves the backend. No exceptions.
| Tool | What it does |
|---|---|
agentkms_get_credential |
Fetch a short-lived LLM API key (Anthropic, OpenAI, Google, etc.) |
agentkms_list_providers |
List providers with stored credentials |
agentkms_get_secret |
Fetch any generic secret by path |
agentkms_sign |
Sign data — returns signature only, private key stays in vault |
agentkms_encrypt |
Encrypt data — returns ciphertext only |
agentkms_decrypt |
Decrypt data — returns plaintext only |
Every team using LLMs has the same problem: API keys in environment variables, .env files, or config maps. One compromised laptop, one leaked container image, one careless git push — and those keys are gone.
AgentKMS eliminates this by design:
- Zero secrets on disk — credentials are vended at runtime, held in memory, and revoked when done
- mTLS everywhere — every connection is mutually authenticated
- Short-lived tokens — 15-minute session TTL, per-request credential scoping
- Deny-by-default policy — no operation succeeds without an explicit allow rule
- Full audit trail — every credential vend, every crypto operation, signed and logged
# Clone and build
git clone https://github.com/catalyst9ai/agentkms.git
cd agentkms
go build ./cmd/dev
# Enroll (generates local dev PKI — CA, server cert, client cert)
./dev enroll
# Store an LLM API key securely
./dev secrets set llm/anthropic api_key=sk-ant-your-key-here
./dev secrets set llm/openai api_key=sk-your-key-here
# Start the server (mTLS on 127.0.0.1:8443)
./dev serveThat's it. Your keys are now vended over mTLS, not sitting in a file.
# Authenticate (uses client cert from ~/.agentkms/dev/)
TOKEN=$(curl -s --cert ~/.agentkms/dev/clients/default/client.crt \
--key ~/.agentkms/dev/clients/default/client.key \
--cacert ~/.agentkms/dev/ca.crt \
-X POST https://127.0.0.1:8443/auth/session | jq -r .token)
# Fetch a credential
curl -s --cert ~/.agentkms/dev/clients/default/client.crt \
--key ~/.agentkms/dev/clients/default/client.key \
--cacert ~/.agentkms/dev/ca.crt \
-H "Authorization: Bearer $TOKEN" \
https://127.0.0.1:8443/credentials/llm/anthropic
# {"provider":"anthropic","api_key":"sk-ant-...","expires_at":"..."}AgentKMS uses dependency injection for its vault backend. Swap backends without changing your application code.
| Tier | Backend | Use Case |
|---|---|---|
| Dev | In-memory (built-in) | Local development, testing, CI |
| Self-Hosted | OpenBao | Open source server deployments |
| Enterprise | HashiCorp Vault | Production with existing Vault infrastructure |
| Cloud | AWS KMS, GCP Cloud KMS, Azure Key Vault | Cloud-native deployments (coming soon) |
All backends implement the same 5-method interface:
type Backend interface {
Sign(ctx, keyID, payloadHash, alg) → signature only
Encrypt(ctx, keyID, plaintext) → ciphertext only
Decrypt(ctx, keyID, ciphertext) → plaintext only
ListKeys(ctx, scope) → metadata only
RotateKey(ctx, keyID) → metadata only
}No method ever returns key material. This is enforced at the type level.
- mTLS with TLS 1.3 — client certificate required on every connection
- Session tokens — HMAC-signed, 15-minute TTL, revocable
- Deny-by-default policy engine — YAML rules with team, scope, key, and operation constraints
- Credential path protection — blocks reads to
.env, private keys, auth files - Rate limiting — per-caller, per-provider sliding window
- Anomaly detection — statistical outlier flagging for unusual access patterns
- LLM providers — Anthropic, OpenAI, Google, Azure, Bedrock, Mistral, Groq, xAI
- Generic secrets — vend any key/value secret via
GET /credentials/generic/{path} - Auto-rotation — master key rotation on configurable schedule
- Zero persistence — credentials exist in memory only, zeroed after HTTP response
- HMAC-signed audit events — tamper-evident logging on every operation
- Multiple sinks — File (NDJSON), Elasticsearch, Splunk HEC, Datadog, generic SIEM webhook
- SOC 2 evidence export — automated compliance report generation
- GDPR/CCPA endpoints — data export, deletion, and anonymization
- Helm chart — deploy to Kubernetes with
helm install - Health checks —
/healthzand/readyzfor liveness/readiness probes - Prometheus metrics — built-in
/metricsendpoint - Dual-run mode — migrate between backends with zero downtime
| Method | Endpoint | Description |
|---|---|---|
POST |
/auth/session |
Authenticate via mTLS → receive session token |
POST |
/auth/refresh |
Refresh expiring session token |
POST |
/auth/revoke |
Revoke session token |
POST |
/auth/delegate |
Mint scoped sub-agent token |
| Method | Endpoint | Description |
|---|---|---|
GET |
/credentials/llm |
List supported LLM providers |
GET |
/credentials/llm/{provider} |
Vend short-lived LLM API key |
POST |
/credentials/llm/{provider}/refresh |
Refresh expiring credential |
GET |
/credentials/generic/{path} |
Vend arbitrary secret |
| Method | Endpoint | Description |
|---|---|---|
POST |
/sign/{key-id} |
Sign payload hash → returns signature |
POST |
/encrypt/{key-id} |
Encrypt plaintext → returns ciphertext |
POST |
/decrypt/{key-id} |
Decrypt ciphertext → returns plaintext |
GET |
/keys |
List key metadata (never key material) |
POST |
/rotate/{key-id} |
Rotate key, retain historical versions |
┌─────────────┐ mTLS ┌──────────────┐ ┌─────────────────┐
│ Your App │──────────────▶│ AgentKMS │───────────▶│ Vault Backend │
│ (any lang) │◀──────────────│ │◀───────────│ (OpenBao/HC/…) │
└─────────────┘ tokens + │ ┌─────────┐ │ Transit └─────────────────┘
credentials │ │ Policy │ │ API only
│ │ Engine │ │
│ └─────────┘ │
│ ┌─────────┐ │
│ │ Audit │ │──▶ SIEM / ELK / Splunk
│ │ Trail │ │
│ └─────────┘ │
└──────────────┘
# Deploy OpenBao (Helm)
helm repo add openbao https://openbao.github.io/openbao-helm
helm install openbao openbao/openbao --set server.ha.enabled=true
# Deploy AgentKMS
helm install agentkms ./deploy/helm/agentkms/ \
--set backend.type=openbao \
--set backend.address=http://openbao:8200helm install agentkms ./deploy/helm/agentkms/ \
--set backend.type=vault \
--set backend.address=https://vault.example.com:8200AgentKMS exposes a standard REST API over mTLS. Integrate from any language:
- Go — see
examples/go-client/ - Python — see
examples/python-client/ - curl — see Quick Start above
- AI Agent Frameworks — optional extensions available for specific frameworks
docs/architecture.md— design decisions and security modeldocs/compliance-controls.md— SOC 2 / PCI-DSS / GDPR evidencedocs/security-runbook.md— incident response proceduresdocs/rotation-runbook.md— key rotation guide
AgentKMS enforces these invariants at every layer:
- No backend method returns, logs, or exposes private key material
- No credential is written to disk — in-memory only, zeroed after use
- No operation succeeds without mTLS authentication + valid session token + policy allow
- Every operation is audit-logged with HMAC signature before the response is sent
- Error messages contain only key IDs and status codes — never key bytes
Found a vulnerability? Email security@catalyst9.ai.
Apache License 2.0 — see LICENSE.
AgentKMS is built and maintained by @TheGenXCoder. It serves as the security foundation for Catalyst9, an AI security platform for regulated industries.
Enterprise support and professional services available — get in touch.