decisionshared last reviewed 2026-05-21

Aspire Hub Secrets Vault is the default credential store

Context

Aspire's credential sprawl was historically painful: API keys in 1Password, system passwords in macOS Keychain, deploy secrets in Coolify env vars, third-party tokens in ~/.claude.json, and ad-hoc credentials in chat history. Result: no audit trail, no shared access for the team, slow onboarding for new staff, and unclear "where is THIS credential" answers.

Detail

Decision

Aspire Hub Secrets Vault is the default for any new credential storage. Existing credentials migrate to Hub vault as they're rotated. Hub is built inside the existing Aspire Staff Portal monorepo (apps/aspire-staff-portal/).

What goes in the Hub Vault

What does NOT go in the Hub Vault

Architecture

Standard usage pattern

  1. Service needs a new credential
  2. Operator adds to Hub vault via /secrets UI
  3. Service reads via Hub reveal API (with its service auth)
  4. Operator rotates โ†’ Hub UI โ†’ service auto-picks-up

Per-consumer credential isolation

Hub vault enforces per-consumer credentials for shared services. Example: BizDB API (per aspire-hub โ€” to be created):

Rotation hygiene rules (per MEMORY.md reference_aspire_credential_rotation)

Credential classRotation urgency
Coolify-VPS-resident credentials (compromised host)High
Control-plane (Coolify token, GitLab token)High
Paid-usage (ElevenLabs, Twilio, Stripe live)High
Auth secrets (JWT_SECRET, DB pwd)High
OAuth-subscription credentials (Claude Max, ChatGPT Pro, Gemini Pro)LOW โ€” these live on OpenClaw VPS only, flat-rate billing, not exfil-urgent
Free LiteLLM keyHygiene-only (no real-money risk)

Constraints we accepted

Revisit trigger

Actions

Related

๐Ÿ”— Relationships

graph LR aspire_hub_secrets_vault_default["aspire-hub-secrets-vault-default"]:::self aspire_hub_secrets_vault_default --> aspire_hub["aspire-hub"] aspire_hub_secrets_vault_default --> coolify_deployment_default["coolify-deployment-default"] aspire_hub_secrets_vault_default --> aspire_llm_gateway_only_egress["aspire-llm-gateway-only-egress"] classDef self fill:#715EE3,color:#fff,stroke:#291F50;