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:

bash
ws init

This will generate a default ws.yaml file that you can customize for your needs.

Tip: You can create your own templates (including one named default). When you run ws init without a template name, withsecrets will use the default template automatically. See Create Template.
OR

You can also create a configuration file by importing existing environment variables from a .env file using the following command:

bash
ws convert --from dotenv --infile .env

See ws convert --help for more options on importing from different formats.

OR

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.

bash
ws convert --from ksvc --infile service.yaml --env production

You 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.

bash
ws convert --from ksvc \
  --provider gcp \
  --project 1337 \
  --name my-service \
  --env production

For AWS, --name expects service.region.

bash
ws convert --from ksvc \
  --provider aws \
  --project 123456789012 \
  --name my-service.us-east-1 \
  --env production

For Azure, --name expects app.resource-group.

bash
ws convert --from ksvc \
  --provider azure \
  --project 00000000-0000-0000-0000-000000000000 \
  --name my-app.my-resource-group \
  --env production

For 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:

ws.yamlyaml
# 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:

ws.yamlyaml
env:
  DATABASE_URL:
    secret-key: "database-connection-string"
  API_KEY:
    secret-key: "external-api-key"

Fetch all secrets under a specific path prefix:

ws.yamlyaml
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:

ws.yamlyaml
env:
  APP_ENV:
    value: "production"
  DEBUG:
    value: "false"

withsecrets supports environment variable interpolation using ${VAR_NAME} syntax:

ws.yamlyaml
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:

ws.yamlyaml
API_URL:
  value: "https://api.${DOMAIN}/v1"

Provide fallback values with ${VAR:-default} syntax:

ws.yamlyaml
REDIS_URL:
  value: "redis://${REDIS_HOST:-localhost}:${REDIS_PORT:-6379}/0"
Important: Interpolation is processed in order, so you can reference variables defined earlier in the same configuration.

Multiple Cloud Providers

You can fetch secrets from different cloud providers in the same configuration:

ws.yamlyaml
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:

ws.yamlyaml
# 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:

bash
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:

bash
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:

bash
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:

bash
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

Usage Examples

See practical examples of how to use your configuration.

Examples Guide