Overview
The broker currently stores OAuth client_id and client_secret directly in PostgreSQL. While encrypted at rest, this is incompatible with enterprise environments that mandate external secret managers (HashiCorp Vault, AWS Secrets Manager, GCP Secret Manager).
Problem
- Provider credentials live in Postgres alongside metadata, creating a dual-concern
- Enterprise security policies often require credentials to live exclusively in approved vaults
- Nexus competes with existing secret management infrastructure instead of integrating with it
Proposed Solution
Add a SECRET_BACKEND configuration option:
# Option A: Internal Postgres (current behavior, default)
SECRET_BACKEND=internal
# Option B: HashiCorp Vault
SECRET_BACKEND=hashicorp-vault
VAULT_ADDR=https://vault.acme.com
VAULT_TOKEN=s.xxxxx
VAULT_MOUNT=secret
VAULT_PATH_PREFIX=nexus/providers
# Option C: AWS Secrets Manager
SECRET_BACKEND=aws-secrets-manager
AWS_REGION=us-east-1
AWS_SECRET_PREFIX=nexus/providers
# Option D: GCP Secret Manager
SECRET_BACKEND=gcp-secret-manager
GCP_PROJECT_ID=acme-prod
GCP_SECRET_PREFIX=nexus-providers
Behavior when SECRET_BACKEND != internal
POST /providers stores only metadata in Postgres (name, auth URLs, scopes) — not credentials
client_id and client_secret are written to the configured vault at <prefix>/<provider_name>/client_id and <prefix>/<provider_name>/client_secret
- At OAuth flow time, the broker reads credentials from the vault backend
- Nexus stores only the resulting tokens — never the input credentials
Architecture
This should be implemented as a SecretBackend interface:
type SecretBackend interface {
Get(ctx context.Context, key string) (string, error)
Set(ctx context.Context, key, value string) error
Delete(ctx context.Context, key string) error
}
With implementations: InternalBackend (current), VaultBackend, AWSBackend, GCPBackend.
Acceptance Criteria
Priority
P5 — Large effort
Reference
AGENT_AUTH_PROPOSAL.md — Proposal 4
Overview
The broker currently stores OAuth
client_idandclient_secretdirectly in PostgreSQL. While encrypted at rest, this is incompatible with enterprise environments that mandate external secret managers (HashiCorp Vault, AWS Secrets Manager, GCP Secret Manager).Problem
Proposed Solution
Add a
SECRET_BACKENDconfiguration option:Behavior when
SECRET_BACKEND != internalPOST /providersstores only metadata in Postgres (name, auth URLs, scopes) — not credentialsclient_idandclient_secretare written to the configured vault at<prefix>/<provider_name>/client_idand<prefix>/<provider_name>/client_secretArchitecture
This should be implemented as a
SecretBackendinterface:With implementations:
InternalBackend(current),VaultBackend,AWSBackend,GCPBackend.Acceptance Criteria
SecretBackendinterface defined in nexus-brokerinternalbackend preserves current behavior (no breaking change)SECRET_BACKENDconfig validated at startupPriority
P5 — Large effort
Reference
AGENT_AUTH_PROPOSAL.md — Proposal 4