Secrets
cuenv provides a flexible secret management system that integrates with various secret providers. Secrets are resolved at runtime using exec-based resolvers, keeping sensitive values out of your configuration files.
How Secrets Work
Section titled “How Secrets Work”cuenv uses an exec-based resolver pattern: instead of storing secrets directly in configuration, you define a command that retrieves the secret at runtime. This approach:
- Keeps secrets out of version control
- Integrates with any CLI-based secret provider
- Allows runtime secret rotation without config changes
- Works with existing secret management infrastructure
Basic Secret Structure
Section titled “Basic Secret Structure”The base #Secret type defines the resolver pattern:
package cuenv
import "github.com/cuenv/cuenv/schema"
schema.#Cuenv
env: { MY_SECRET: schema.#Secret & { resolver: "exec" command: "echo" args: ["my-secret-value"] }}When cuenv loads the environment, it executes the command and uses its output as the secret value.
Built-in Secret Providers
Section titled “Built-in Secret Providers”1Password
Section titled “1Password”cuenv includes a built-in 1Password resolver using the op CLI:
package cuenv
import "github.com/cuenv/cuenv/schema"
schema.#Cuenv
env: { // Reference a 1Password item DATABASE_PASSWORD: schema.#OnePasswordRef & { ref: "op://vault-name/item-name/password" }
// Another 1Password secret API_KEY: schema.#OnePasswordRef & { ref: "op://Development/API Keys/production" }}Prerequisites:
- Install the 1Password CLI
- Sign in with
op signinor use a service account
How it works:
The #OnePasswordRef expands to:
command: "op"args: ["read", "op://vault-name/item-name/password"]Google Cloud Secret Manager
Section titled “Google Cloud Secret Manager”Use GCP Secret Manager for cloud-native secret storage:
package cuenv
import "github.com/cuenv/cuenv/schema"
schema.#Cuenv
env: { // GCP secret with default "latest" version DB_PASSWORD: schema.#GcpSecret & { project: "my-gcp-project" secret: "database-password" }
// Specific version API_KEY: schema.#GcpSecret & { project: "my-gcp-project" secret: "api-key" version: "5" }}Prerequisites:
- Install the Google Cloud CLI
- Authenticate with
gcloud auth login - Ensure the account has
secretmanager.versions.accesspermission
How it works:
The #GcpSecret expands to:
command: "gcloud"args: ["secrets", "versions", "access", "latest", "--secret", "database-password", "--project", "my-gcp-project"]Custom Secret Providers
Section titled “Custom Secret Providers”Create custom resolvers for any secret provider with a CLI:
AWS Secrets Manager
Section titled “AWS Secrets Manager”import "github.com/cuenv/cuenv/schema"
#AwsSecret: schema.#Secret & { region: string name: string command: "aws" args: [ "secretsmanager", "get-secret-value", "--region", region, "--secret-id", name, "--query", "SecretString", "--output", "text" ]}
env: { DB_PASSWORD: #AwsSecret & { region: "us-west-2" name: "prod/database/password" }}HashiCorp Vault
Section titled “HashiCorp Vault”import "github.com/cuenv/cuenv/schema"
#VaultSecret: schema.#Secret & { path: string field: string command: "vault" args: ["kv", "get", "-field=\(field)", path]}
env: { API_KEY: #VaultSecret & { path: "secret/myapp/api" field: "key" }}Azure Key Vault
Section titled “Azure Key Vault”import "github.com/cuenv/cuenv/schema"
#AzureSecret: schema.#Secret & { vault: string name: string command: "az" args: [ "keyvault", "secret", "show", "--vault-name", vault, "--name", name, "--query", "value", "--output", "tsv" ]}
env: { CONNECTION_STRING: #AzureSecret & { vault: "my-keyvault" name: "db-connection-string" }}Doppler
Section titled “Doppler”import "github.com/cuenv/cuenv/schema"
#DopplerSecret: schema.#Secret & { project: string config: string name: string command: "doppler" args: ["secrets", "get", name, "--project", project, "--config", config, "--plain"]}
env: { STRIPE_KEY: #DopplerSecret & { project: "backend" config: "production" name: "STRIPE_SECRET_KEY" }}Best Practices
Section titled “Best Practices”1. Never Commit Secrets
Section titled “1. Never Commit Secrets”Always use secret references, never hardcode values:
// WRONG - secret in configenv: { API_KEY: "sk-1234567890abcdef"}
// CORRECT - secret referenceenv: { API_KEY: schema.#OnePasswordRef & { ref: "op://API/Production/key" }}2. Use Descriptive References
Section titled “2. Use Descriptive References”Make secret paths self-documenting:
env: { // Clear path structure STRIPE_SECRET: schema.#OnePasswordRef & { ref: "op://Payments/Stripe-Production/secret-key" }}3. Create Reusable Definitions
Section titled “3. Create Reusable Definitions”Define organization-specific secret patterns:
package shared
import "github.com/cuenv/cuenv/schema"
#ProdOnePassword: schema.#OnePasswordRef & { // Override ref in usage ref: string & =~"^op://Production/"}
#ProdGcpSecret: schema.#GcpSecret & { project: "my-company-prod"}4. Test Secret Access
Section titled “4. Test Secret Access”Verify secrets resolve correctly:
# Check environment with secretscuenv env print
# Test specific task's accesscuenv task migrateTroubleshooting
Section titled “Troubleshooting”Secret Not Resolving
Section titled “Secret Not Resolving”error: secret resolution failed DB_PASSWORD: command 'op' failed with exit code 1Fixes:
- Verify the CLI tool is installed and in PATH
- Check authentication status (e.g.,
op signin,gcloud auth login) - Verify the secret reference/path is correct
- Test the command manually
Slow Secret Resolution
Section titled “Slow Secret Resolution”If secrets take too long to resolve:
- Consider caching strategies at the provider level
- Batch related secrets where possible
- Use local development secrets for non-production environments
See Also
Section titled “See Also”- Configuration Guide - General configuration patterns
- Examples - Complete configuration examples
- Environments - Environment variable management