Learn how to configure withsecrets with the ws.yaml file and understand advanced features
like variable interpolation and secret paths.
Initialize Configuration
Start by creating a configuration file using the ws init command:
ws initThis will generate a default ws.yaml file that you can customize for your
needs.
default). When you run ws init without a template name,
withsecrets will use the default template automatically. See Create Template.You can also create a configuration file by importing existing environment variables
from a .env file using the following command:
ws convert --from dotenv --infile .envSee ws convert --help for more options on importing from different formats.
If you're running on Cloud Run / Knative, you can generate a ws.yaml from an existing Knative Service manifest. withsecrets will read the container env entries, convert hard-coded values to value mappings and valueFrom.secretKeyRef entries to secret-key mappings.
ws convert --from ksvc --infile service.yaml --env productionYou can also import a deployed service directly from your cloud provider (no --infile required). This is useful when you want to bootstrap a ws.yaml from an existing service definition.
ws convert --from ksvc \
--provider gcp \
--project 1337 \
--name my-service \
--env productionFor AWS, --name expects service.region.
ws convert --from ksvc \
--provider aws \
--project 123456789012 \
--name my-service.us-east-1 \
--env productionFor Azure, --name expects app.resource-group.
ws convert --from ksvc \
--provider azure \
--project 00000000-0000-0000-0000-000000000000 \
--name my-app.my-resource-group \
--env productionFor Knative Services running on GCP, the environment will default to provider gcp and use the Service's metadata.namespace as the project (which is typically the GCP project number for Cloud Run).
Basic Structure
The ws.yaml file is organized into environment sections, each with its own
provider and env:
# yaml-language-server: $schema=https://withsecrets.com/ws.schema.json
---
default:
provider: gcp
project: 1337
env:
DATABASE_URL:
secret-key: "database-connection-string"
API_KEY:
secret-key: "external-api-key"
development:
provider: gcp
project: 1337
env:
DEV_DATABASE_URL:
secret-key: "dev-database-connection-string"
production:
provider: gcp
project: 1337
env:
PROD_DATABASE_URL:
secret-key: "prod-database-connection-string"Environment Sections
Each top-level section (like default, development, production) represents a different environment configuration.
Provider Configuration
The provider field specifies which provider to use (gcp, aws, azure, openbao, local).
Project ID
The project field specifies the project ID for the cloud provider (required
for GCP and Azure).
Env
The env array defines how secrets are mapped to environment variables.
Fetch a single secret from your cloud provider:
env:
DATABASE_URL:
secret-key: "database-connection-string"
API_KEY:
secret-key: "external-api-key"Fetch all secrets under a specific path prefix:
env:
DB:
secret-path: "database"
API:
secret-path: "external-apis"This will create environment variables like DB_CONNECTION_STRING, DB_USERNAME, API_STRIPE_KEY, etc.
Set static environment variables:
env:
APP_ENV:
value: "production"
DEBUG:
value: "false"withsecrets supports environment variable interpolation using ${VAR_NAME} syntax:
env:
DB_PASSWORD:
secret-key: "db-password"
DB_HOST:
value: "mydbhost"
DB_CONNECTION_STRING:
value: "postgresql://user:${DB_PASSWORD}@${DB_HOST}:5432/mydb"Reference system environment variables:
API_URL:
value: "https://api.${DOMAIN}/v1"Provide fallback values with ${VAR:-default} syntax:
REDIS_URL:
value: "redis://${REDIS_HOST:-localhost}:${REDIS_PORT:-6379}/0"Multiple Cloud Providers
You can fetch secrets from different cloud providers in the same configuration:
default:
provider: gcp
project: 1337
env:
GCP_PROJECT_ID:
secret-key: "gcp_project_secret"
AWS_PROJECT_ID:
secret-key: "aws_project_secret"
provider: aws
AZURE_PROJECT_ID:
secret-key: "azure_project_secret"
provider: azure
project: "my-azure-project"Full Configuration Example
Here's a comprehensive example showing all features:
# yaml-language-server: $schema=https://withsecrets.com/ws.schema.json
---
default:
provider: gcp
project: 1337
env:
# Individual secrets
DATABASE_URL:
secret-key: "database-connection-string"
STRIPE_API_KEY:
secret-key: "stripe-api-key"
# Secret paths for bulk loading
DB:
secret-path: "database"
API:
secret-path: "external-apis"
# Hard-coded values
APP_ENV:
value: "development"
DEBUG:
value: "true"
# Interpolated values
REDIS_URL:
value: "redis://${REDIS_HOST:-localhost$}:${REDIS_PORT:-6379}/0"
LOG_LEVEL:
value: "${LOG_LEVEL:-info}"
development:
provider: gcp
project: 1337
env:
DEV_DATABASE_URL:
secret-key: "dev-database-connection-string"
DEV_STRIPE_API_KEY:
secret-key: "dev-stripe-api-key"
staging:
provider: gcp
project: 1337
env:
STAGING_DATABASE_URL:
secret-key: "staging-database-connection-string"
STAGING_STRIPE_API_KEY:
secret-key: "staging-stripe-api-key"
production:
provider: gcp
project: 1337
env:
PROD_DATABASE_URL:
secret-key: "prod-database-connection-string"
PROD_STRIPE_API_KEY:
secret-key: "prod-stripe-api-key"
APP_ENV:
value: "production"
DEBUG:
value: "false"Learn how to configure withsecrets itself (globally).
You can configure the default template that withsecrets uses when you run ws init without a template name.
To set the default template, run the following command:
ws create template default
You can also create templates with different names and
specify the template to use when running ws init my-template-name:
ws create template my-template-name
You can also create templates with different names and
specify the template to use when running ws init my-template-name:
There are no defaults set by default. To set defaults for a provider, run the following command:
ws config defaults set --provider gcp --regions europe-west3
This will set the default provider to GCP and the default region to europe-west3.
So, when you're using ws tui and add a secret, it will default to using europe-west3 as the region for GCP secrets.
Check ws config defaults get --help for more options related to managing the defaults.
Caching is off by default. To enable caching, run the following command:
ws config cache --enable --ttl 14d
This will enable caching of secrets locally, with a time-to-live (TTL) of 14 days. You can adjust the TTL as needed.
Check ws cache --help for more options related to managing the cache.
Organization
- Use descriptive environment variable names
- Group related secrets with secret paths
- Keep environment-specific overrides minimal
- Document your configuration structure
Security
- Never commit secrets to version control
- Use environment-specific configurations
- Limit access to production secrets
- Rotate secrets regularly
Maintenance
- Keep configurations in sync across teams
- Use consistent naming conventions
- Test configurations in staging first
- Version control your configuration templates
Performance
- Use secret paths for bulk operations
- Avoid unnecessary cross-provider calls
- Cache configurations when possible
- Monitor secret access patterns
Cloud Providers Setup
Configure authentication and permissions for your cloud providers.
Cloud Providers Guide