Skip to content

Secrets Management

StackSolo provides seamless integration with GCP Secret Manager for handling sensitive configuration values like API keys, database passwords, and other credentials.

Reference secrets in your environment variables using the @secret/secret-name syntax:

{
"project": {
"networks": [{
"name": "main",
"functions": [{
"name": "api",
"env": {
"OPENAI_API_KEY": "@secret/openai-api-key",
"STRIPE_SECRET_KEY": "@secret/stripe-secret-key",
"DATABASE_URL": "@secret/database-url"
}
}]
}]
}
}

During deployment, StackSolo:

  1. Generates CDKTF code that references secrets from Secret Manager
  2. Grants the function’s service account roles/secretmanager.secretAccessor
  3. Injects secrets as environment variables at runtime

When you run stacksolo deploy, the CLI automatically:

  1. Scans your config for all @secret/ references
  2. Checks which secrets exist in GCP Secret Manager
  3. Creates missing secrets interactively

The easiest way to manage secrets is with a .env.production file:

Terminal window
# .env.production (add to .gitignore!)
OPENAI_API_KEY=sk-...
STRIPE_SECRET_KEY=sk_live_...
DATABASE_URL=postgres://user:pass@host/db

When deploying, StackSolo checks this file first:

Terminal window
$ stacksolo deploy
[1/3] Checking secrets
database-url exists
openai-api-key missing
stripe-secret-key missing
Missing secrets:
- openai-api-key (OPENAI_API_KEY in function:api)
- stripe-secret-key (STRIPE_SECRET_KEY in function:api)
? Create missing secrets now? (Y/n)
Found OPENAI_API_KEY in .env.production
? Use this value? (Y/n) y
Creating secret: openai-api-key...
Created: openai-api-key
Found STRIPE_SECRET_KEY in .env.production
? Use this value? (Y/n) y
Creating secret: stripe-secret-key...
Created: stripe-secret-key
Created 2 secret(s) successfully
[2/3] Pre-flight checks
...

If a secret isn’t in .env.production, you’ll be prompted to enter it:

Terminal window
api-key missing
? Enter value for API_KEY (api-key): ********
Creating secret: api-key...
Created: api-key

StackSolo uses a consistent mapping between environment variable names and secret names:

Environment VariableSecret Name
OPENAI_API_KEYopenai-api-key
DATABASE_URLdatabase-url
STRIPE_SECRET_KEYstripe-secret-key

The convention is:

  • Lowercase
  • Underscores become hyphens
  • No @secret/ prefix in the secret name

To skip the secret checking phase:

Terminal window
stacksolo deploy --skip-secrets

Note: Deployment will fail if referenced secrets don’t exist in Secret Manager.

You can also manage secrets directly with gcloud:

Terminal window
# Create a secret
echo -n "your-secret-value" | gcloud secrets create secret-name --data-file=-
# List secrets
gcloud secrets list
# View a secret value
gcloud secrets versions access latest --secret=secret-name
# Update a secret
echo -n "new-value" | gcloud secrets versions add secret-name --data-file=-

Keep your secrets in .env.production for easy local development and deployment:

.env.production
OPENAI_API_KEY=sk-dev-key-for-development
STRIPE_SECRET_KEY=sk_test_xxx

Never commit secrets to version control:

.gitignore
.env.production
.env.local
*.env

For production vs staging, use different GCP projects with their own secrets.

Update secrets by adding new versions:

Terminal window
echo -n "new-api-key" | gcloud secrets versions add openai-api-key --data-file=-

The new version is automatically used on the next Cloud Function deployment.

  1. Check if the secret exists: gcloud secrets list
  2. Verify the secret name matches the @secret/ reference
  3. Run stacksolo deploy (without --skip-secrets) to auto-create

”Permission denied” when accessing secrets

Section titled “”Permission denied” when accessing secrets”

Ensure the function’s service account has the secretAccessor role. StackSolo grants this automatically when using @secret/ references.

Cloud Functions cache secrets. Redeploy to pick up new secret versions:

Terminal window
stacksolo deploy