Cloud Secrets
In production, tsdevstack integrates with cloud secret managers instead of using local files. Your code uses the same SecretsService interface, but secrets are fetched from your cloud provider.
Supported Providers
tsdevstack supports three cloud secret managers:
- Google Cloud Platform - Google Cloud Secret Manager
- AWS - AWS Secrets Manager
- Azure - Azure Key Vault
How Cloud Secrets Work
When your services run in the cloud:
- The
SECRETS_PROVIDERenvironment variable is set togcp,aws, orazure SecretsServicedetects this and fetches secrets from the cloud provider- Secrets are cached for performance (5-minute cache)
- Your code works exactly as it does locally
Setting Up Cloud Secrets
1. Initialize Your Cloud Provider
This command verifies your credentials, enables necessary APIs, and creates required resources.
2. Push Secrets to Cloud
This command:
- Generates and pushes framework secrets automatically (JWT keys, API keys, token TTLs, email provider)
- Prompts you for 3 values:
DOMAIN,RESEND_API_KEY, andEMAIL_FROM. Resend is an email delivery service used for transactional emails (account confirmation, password reset) - Auth template projects: asks for
ADMIN_EMAILS(the first admins, optional) when it has a value in your local.secrets.user.json, and pushes it to the auth-service scope. Otherwise it prints thecloud-secrets:set ADMIN_EMAILS --service auth-service --env <env>command to run later. See Managing Users - Includes your custom secrets from
.secrets.user.json— prompts you for each one interactively (you can skip any by leaving the value empty) - Auto-derives the rest from your domain:
API_URL,APP_URL,KONG_CORS_ORIGINS - Skips infrastructure secrets (
DATABASE_URL,REDIS_*) — these are synced from Terraform outputs during deployment
Custom secrets are pushed to the shared scope (available to all services). If a secret already exists in cloud, you won't be prompted again.
Important: Cloud secrets are generated fresh and never copied from local development. This ensures production uses unique, secure values.
You can also set secrets directly in your cloud provider's console (GCP Secret Manager, AWS Secrets Manager, Azure Key Vault). The CLI provides convenience — it's not the only way.
3. Deploy Your Services
This deploys infrastructure (databases, VPCs, etc.) and all services. Service URLs are automatically synced to the secret manager after deployment.
Environment Isolation
Each environment (dev, staging, prod) must use separate cloud resources:
The framework validates this and will fail if you try to reuse credentials across environments.
Managing Cloud Secrets
List All Secrets
Set a Single Secret
Compare Local vs Cloud
Remove a Secret
Secret Naming in Cloud
Secrets are stored with a naming convention:
Examples:
myapp-shared-STRIPE_KEY- Shared across all servicesmyapp-auth-service-DATABASE_URL- Specific to auth-service
Scopes
- shared - Available to all services (most secrets)
- {service-name} - Service-specific secrets (primarily DATABASE_URL)
When a service requests a secret, tsdevstack checks the shared scope first, then falls back to the service scope. Nearly every runtime secret lives in shared, so this resolves in a single lookup. If the same key exists in both scopes, the shared value wins.
Azure Key Vault Naming
Azure Key Vault only allows alphanumeric characters and hyphens. tsdevstack automatically transforms secret names:
DATABASE_URLbecomesDATABASE-URLJWT_PRIVATE_KEYbecomesJWT-PRIVATE-KEY
This happens transparently. Your code still uses underscores.
Full secret names in Azure Key Vault:
myapp-shared-STRIPE-KEY(notSTRIPE_KEY)myapp-auth-service-DATABASE-URL(notDATABASE_URL)
Service URLs
Service URLs are automatically managed using deterministic internal URLs:
During infra:deploy, service URLs are synced to the secret store before any containers start. This means all services can discover each other on the first deploy — no ordering, no restarts, no placeholders.
You never need to set *_URL secrets manually.
Runtime Configuration
For services running in the cloud, these environment variables are required:
These are automatically configured during deployment.
Best Practices
- Never copy local secrets to production - Always use
cloud-secrets:pushto generate fresh values - Use separate environments - Keep dev, staging, and prod completely isolated
- Rotate credentials regularly - Use
cloud-secrets:set --overwriteto update secrets - Monitor access - Use your cloud provider's audit logs to track secret access
- Verify before deployment - Run
cloud-secrets:diffto check secrets are in sync