Skip to main content

Vault Integration Architecture

Vault integration is a planned architecture, not a current feature. This page documents the design for future implementation.

Why Credential Rotation Matters

MCP proxies like ThornGuard hold upstream bearer tokens — the credentials used to authenticate with backend MCP servers on behalf of clients. Static tokens present a security liability:
  • Leaked tokens grant indefinite access until manually revoked
  • No audit trail of when credentials were last rotated
  • Blast radius is unbounded — a single compromised token can be used until discovery
Automated credential rotation limits exposure by ensuring tokens have a bounded lifetime and are regularly replaced without manual intervention.

Current State

ThornGuard currently stores upstream OAuth tokens in D1 with AES-256-GCM encryption via the oauth-crypto.ts module:
  • Each proxy-issued JWT maps to encrypted upstream credentials via JTI (JWT ID)
  • Encryption uses a 256-bit key stored as a Cloudflare Worker secret (OAUTH_TOKEN_ENCRYPTION_KEY)
  • Token refresh is handled during the proxy flow — when an upstream access token expires, ThornGuard uses the encrypted refresh token to obtain a new one
This approach is adequate for the current scope but lacks:
  • Automated rotation — refresh happens reactively (on expiry), not proactively
  • Centralized secret management — credentials are spread across D1 rows
  • Dynamic secret generation — all credentials are static, obtained via OAuth flows
  • Independent access audit — credential access is only logged within ThornGuard’s audit trail

Proposed Architecture

Vault as Secrets Backend

┌─────────────┐     ┌──────────────────┐     ┌─────────────┐
│  MCP Client │────▶│    ThornGuard    │────▶│  Upstream    │
│             │     │   (CF Worker)     │     │  MCP Server  │
└─────────────┘     └────────┬─────────┘     └─────────────┘

                    ┌────────▼─────────┐
                    │  HashiCorp Vault  │
                    │  ┌─────────────┐ │
                    │  │ KV v2       │ │  Static secrets with versioning
                    │  ├─────────────┤ │
                    │  │ Transit     │ │  Encryption-as-a-service
                    │  ├─────────────┤ │
                    │  │ Database    │ │  Dynamic credential generation
                    │  └─────────────┘ │
                    └──────────────────┘

Secrets Engines

KV v2 (Key-Value with Versioning)
  • Store upstream bearer tokens, API keys, and refresh tokens
  • Version history enables rollback if a rotated credential causes issues
  • Metadata tracks rotation timestamps and source
Transit Engine
  • Encryption-as-a-service replaces the current OAUTH_TOKEN_ENCRYPTION_KEY approach
  • ThornGuard sends plaintext to Vault for encryption; Vault returns ciphertext
  • Key rotation is handled entirely by Vault — no secret redistribution needed
  • Supports key versioning: new data encrypted with latest key, old data decryptable with previous versions
Database Engine (Future)
  • Dynamic credential generation for database-backed upstream services
  • Vault creates short-lived credentials on demand with automatic revocation
  • Eliminates static credentials entirely for supported backends

Integration with OAuth Token Store

The current oauth-store.ts manages token lifecycle in D1. With Vault integration:
ComponentCurrent (D1 + AES)With Vault
JTI → token mappingD1 oauth_tokens tableD1 (unchanged)
Upstream access tokenAES-256-GCM encrypted in D1Vault KV v2 path
Upstream refresh tokenAES-256-GCM encrypted in D1Vault KV v2 path
EncryptionWorker secret (OAUTH_TOKEN_ENCRYPTION_KEY)Vault Transit engine
Token refreshReactive (on upstream 401)Proactive (Vault lease expiry)
D1 retains the JTI mapping, metadata, and proxy-side token information. Only the encrypted upstream credentials move to Vault.

When to Use Vault vs. Current Storage

FactorD1 + AES-256-GCMVault
Deployment complexityMinimal — built into ThornGuardRequires Vault cluster or HCP Vault subscription
Credential rotationManual / reactive on expiryAutomated via leases and TTLs
Access audit trailThornGuard audit logs onlyVault audit log + ThornGuard audit logs
Dynamic secretsNot supportedSupported (database, cloud provider credentials)
Key rotationRequires secret redeploymentTransparent — Vault handles internally
CostIncluded with ThornGuardHCP Vault: ~$0.03/secret/month, or self-hosted
Best forIndividual users, small teamsEnterprise with compliance or rotation requirements
The current D1 + AES-256-GCM approach remains the default. Vault integration is an optional enterprise feature for organizations that require centralized secret management or automated rotation.

Implementation Phases

Phase 1: Vault KV v2 Read-Only

  • ThornGuard reads upstream credentials from Vault at proxy time
  • Credentials are written to Vault manually or via a provisioning API
  • D1 stores a Vault path reference instead of encrypted credential blobs
  • Fallback: if Vault is unreachable, use cached credential from previous successful read

Phase 2: Vault Transit for Encryption

  • Replace OAUTH_TOKEN_ENCRYPTION_KEY with Vault Transit encrypt/decrypt operations
  • All credential encryption handled by Vault — no encryption keys stored in Worker secrets
  • Transparent key rotation: Vault manages key versions, ThornGuard just calls encrypt/decrypt

Phase 3: Vault-Managed Rotation

  • Vault proactively rotates upstream credentials based on configurable TTLs
  • ThornGuard subscribes to Vault lease renewal events
  • When a credential is rotated, ThornGuard’s KV cache is invalidated and refreshed
  • Full lifecycle management: creation → rotation → revocation handled by Vault
Each phase is additive — organizations can adopt Phase 1 without committing to the full lifecycle. D1 + AES-256-GCM remains available for deployments without Vault.

Worker-to-Vault Connectivity

Cloudflare Workers can reach Vault over HTTPS. The connectivity approach depends on the Vault deployment:
DeploymentConnectivityNotes
HCP Vault (recommended)Direct HTTPSPublic endpoint with TLS, no tunnel required
Self-hosted (public)Direct HTTPSRequires TLS certificate and firewall rules
Self-hosted (private)Cloudflare TunnelTunnel exposes Vault to Workers without public endpoint
Authentication: ThornGuard authenticates to Vault using AppRole with a role_id stored in Worker environment variables and a secret_id rotated via Vault’s own mechanisms.
HCP Vault is recommended for most deployments — it eliminates Vault cluster management overhead and provides a stable HTTPS endpoint that Workers can reach directly.

Security Considerations

  • Vault access tokens must be short-lived and scoped to specific KV paths
  • Network policy should restrict Vault access to ThornGuard’s Worker IPs (via Cloudflare’s published IP ranges)
  • Audit logging should be enabled on both Vault and ThornGuard for correlation
  • Disaster recovery — Vault’s built-in snapshot and replication features protect against data loss; HCP Vault includes automated backups