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
- Third-party API keys (Stripe, Twilio, SendGrid, etc.)
- Shared service passwords (admin@aspiredigital, etc.)
- Aspire-issued tokens (Hub OIDC client secrets, BizDB API keys per consumer)
- Deploy webhook secrets (Coolify webhooks, GitLab CI tokens)
What does NOT go in the Hub Vault
- Per-user personal credentials (those stay in 1Password)
- Single-environment ephemeral secrets (those stay in Coolify env vars for the specific app)
- LLM Gateway master key (lives in
aspire-llm-gateway/_STATUS.md, NOT a tracked file due to gitleaks)
Architecture
SecretVaultPrisma model inapps/aspire-staff-portal//secretsUI for browsing + revealing (role-gated)- Reveal API for programmatic access by other Aspire services
- Audit log on every reveal
Standard usage pattern
- Service needs a new credential
- Operator adds to Hub vault via
/secretsUI - Service reads via Hub reveal API (with its service auth)
- 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):
- One credential per consuming app
- Stored under
bizdb-api/<consumer>in Hub vault - Audit log shows which consumer revealed/used what
Rotation hygiene rules (per MEMORY.md reference_aspire_credential_rotation)
| Credential class | Rotation 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 key | Hygiene-only (no real-money risk) |
Constraints we accepted
- Hub vault is a single point of failure for the credentials in it. Mitigation: Hub has its own backup/restore + multiple staff with admin access.
- Hub vault requires the Hub Staff Portal to be running (which IS the canonical hub.aspiredigital.group). Down = no new secret access.
Revisit trigger
- A regulated tenant requires HashiCorp Vault or AWS Secrets Manager.
- Hub vault scales to >500 secrets and UX becomes painful.
Actions
- [x] Hub Secrets Vault LIVE (per aspire-hub)
- [x] BizDB API consumer keys migrated (per MEMORY.md
reference_bizdb_api) - [ ] Migrate Stripe Connect platform keys for alby-studio when production launch happens
- [ ] Migrate cloud-first.ai LiteLLM keys (currently stored in OpenClaw secret store)
Related
- aspire-hub โ the Staff Portal where the vault lives
- coolify-deployment-default โ Coolify env vars are still used per-app, vault is the source of truth
- aspire-llm-gateway-only-egress โ exception: master key lives in gateway project _STATUS.md (gitleaks-protected)
๐ 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;