pulumi.secret(). By default, these sensitive values are encrypted with a Pulumi-managed key when using Pulumi Cloud, but when using a self-managed backend like S3, the encryption is your responsibility. Without the encryption sub-block, sensitive values in state are stored as base64-encoded strings that anyone with S3 access can decode. The encryption sub-block inside backend tells ubx which secrets provider to use when initialising the Pulumi stack — either an AWS KMS key (rotatable, access-controlled, audited via CloudTrail) or a passphrase (simpler, portable, but requires secure distribution). One backend block, one encryption configuration, and your state secrets are protected at rest.
What you’ll learn
- How
encryption { provider = "awskms" }encrypts state secrets with a KMS key - How
encryption { provider = "passphrase" }uses an environment variable passphrase - Why only one
backendblock is allowed per compile unit
Why this matters
State encryption matters because state contains secrets. An RDS password marked
pulumi.secret() is encrypted in state — but only if the stack was initialised with a secrets provider. Without encryption, sensitive state values are base64-encoded, not encrypted. Anyone who can read your S3 bucket can decode them.The source code
How it works
encryption configures the Pulumi secrets provider on stack init
The
encryption sub-block translates to a --secrets-provider flag on pulumi stack init. For KMS: --secrets-provider=awskms://arn:aws:kms:.... For passphrase: --secrets-provider=passphrase with PULUMI_CONFIG_PASSPHRASE set in the environment.Sensitive state values are encrypted with the specified key
Any output or config value wrapped in
pulumi.secret() (or produced by an ephemeral = true input) is encrypted using the configured KMS key before being written to the S3 state file. The KMS key ID is stored in the state file metadata so future reads know which key to use for decryption.What ubx generates
Like the plain
backend block, encryption produces no TypeScript/Python/Go code. It configures the Pulumi CLI before the generated program runs. The secrets provider is set once at stack initialisation and stored in the stack’s metadata.Common mistakes
Run it
What you learned
encryption { provider = "awskms" } encrypts sensitive state values with a KMS keyencryption { provider = "passphrase" } uses an environment variable as the encryption passphraseOnly one
backend block is allowed per compile unit — a second block is a compile errorNext steps
Code hierarchy
Share backend and provider config across multiple stacks
backend block reference
Full backend and encryption sub-block syntax
Full runnable example: github.com/ubiquex/ubx-examples/40-backend-encryption-kms

