Secrets Migration Plan¶
Current State¶
Secrets are managed via .env files in app/ and storefront/. SecretSpec is configured with the dotenv provider as a bridge — it reads secrets from .env files and injects them into the devenv shell via config.secretspec.secrets.*.
Declared secrets (in secretspec.toml):
| Secret | Default Profile | Production Profile |
|---|---|---|
JWT_SECRET |
required, default: "supersecret" | required |
COOKIE_SECRET |
required, default: "supersecret" | required |
RESEND_API_KEY |
optional | required |
S3_ACCESS_KEY_ID |
— | required |
S3_SECRET_ACCESS_KEY |
— | required |
Migration Steps¶
Phase 1: Switch to Keyring Provider (Local Dev)¶
Move secrets from plaintext .env files into the macOS system keychain.
-
Update
devenv.yaml: -
Enter the devenv shell — SecretSpec will prompt for each missing secret:
-
Verify secrets are loaded:
-
Remove secrets from
app/.env— keep only non-secret config if any remains that isn't indevenv.nixenv.*declarations. -
Verify Medusa still starts:
Phase 2: 1Password Provider (Team/Shared)¶
When onboarding additional developers, switch to 1Password for shared secret management.
- Create a 1Password vault named
rr-bizops-devwith the secrets - Update
devenv.yaml: - Team members authenticate via
op signinand secrets auto-populate
Phase 3: Production Secrets¶
Production secrets are managed separately via NixOS configuration and Docker environment variables on the Hetzner server. The production profile in secretspec.toml documents what's required but is not used by devenv directly.
For production secret rotation:
- SSH to server: ssh root@89.167.73.23
- Update secrets in /etc/nixos/app-server.nix environment blocks
- nixos-rebuild switch
- Restart containers: systemctl restart docker-medusa-server docker-medusa-worker
Rollback¶
If issues arise, revert to dotenv:
Or bypass SecretSpec entirely by removing the secretspec block from devenv.yaml and restoring app/.env.