1. Docs
  2. Secrets & Configuration
  3. Guides
  4. Managing Secrets

Managing Secrets in Pulumi ESC

    This guide shows you how to store and retrieve secrets in Pulumi ESC environments. Secrets are encrypted values that ESC stores securely and hides from view by default.

    Prerequisites

    • ESC CLI installed
    • Pulumi account created
    • An ESC environment (create one with esc env init <org>/<project>/<env-name>)

    Understanding ESC values

    ESC environments store configuration as key-value pairs in YAML format. All values are defined under a top-level values key:

    values:
      apiEndpoint: https://api.example.com
      region: us-west-2
      apiKey:
        fn::secret: my-secret-value
    

    Values can be:

    • Plain text - Regular configuration values (region, endpoint URLs)
    • Secrets - Encrypted values marked with fn::secret
    • Structured data - Objects and arrays
    • Dynamic values - Generated from providers (covered in other guides)

    Storing secrets

    Via the CLI

    Add a secret to your environment using the --secret flag:

    esc env set <org>/<project>/<env-name> apiKey my-secret-value --secret
    

    For example:

    esc env set my-org/my-project/dev apiKey demo-secret-123 --secret
    

    This encrypts the value before storing it.

    Via the Pulumi Cloud console

    1. Navigate to Pulumi Cloud
    2. Select Environments in the left navigation
    3. Select your environment
    4. In the editor, add your secret using the fn::secret function:
    values:
      apiKey:
        fn::secret: my-secret-value
    
    1. Select Save

    The console will encrypt the secret and replace the plaintext value with a ciphertext reference:

    values:
      apiKey:
        fn::secret:
          ciphertext: ZXNjeAA...
    

    Retrieving secrets

    Via the CLI

    Open your environment to retrieve all values, including secrets:

    esc env open <org>/<project>/<env-name>
    

    This returns all values in JSON format with secrets revealed:

    {
      "apiKey": "my-secret-value",
      "region": "us-west-2"
    }
    

    To retrieve a single value:

    esc env get <org>/<project>/<env-name> apiKey
    

    Via the Pulumi Cloud console

    1. Select your environment in Pulumi Cloud
    2. Select Open to evaluate the environment
    3. Toggle Show secrets to reveal encrypted values

    Organizing secrets

    Nested structure

    Group related secrets using nested keys:

    values:
      database:
        host: db.example.com
        password:
          fn::secret: db-password-123
        port: 5432
      api:
        key:
          fn::secret: api-key-456
        endpoint: https://api.example.com
    

    Access nested values with dot notation:

    esc env get my-org/my-project/dev database.password
    

    Multiple environments

    Organize secrets by environment (dev, staging, production) using separate ESC environments:

    • my-org/my-project/dev - Development secrets
    • my-org/my-project/staging - Staging secrets
    • my-org/my-project/prod - Production secrets

    Each environment can have different RBAC permissions, ensuring production secrets are only accessible to authorized users.

    Best practices

    Use secrets for sensitive data

    Mark these values as secrets:

    • API keys and tokens
    • Database passwords
    • Private keys and certificates
    • OAuth client secrets

    Use plain text for non-sensitive data

    These can be plain text:

    • Region names
    • Public endpoints
    • Feature flags
    • Port numbers

    Rotate secrets regularly

    Update secrets by setting new values:

    esc env set my-org/my-project/prod apiKey new-secret-value --secret
    

    ESC versions every change, allowing you to roll back if needed.

    Control access with RBAC

    Use Role-Based Access Control to limit who can read or write secrets:

    • Grant teams read-only access to production secrets
    • Allow developers full access to development secrets
    • Use service accounts for CI/CD access

    Next steps

      Neo just got smarter about infrastructure policy automation