Skip to content

Security

Authentication Model

Pulumi supports multiple authentication methods for accessing Pulumi Cloud and managing infrastructure:

Method Use Case
Personal Access Token Individual developer CLI authentication
Team/Organization Tokens CI/CD pipelines and automation
SSO (SAML/OIDC) Enterprise identity federation (Okta, Azure AD, etc.)
SCIM Automated user provisioning and deprovisioning
GitHub/GitLab SSO Developer-friendly login via existing accounts
graph TB
    subgraph Users
        Dev["Developer\n(CLI / IDE)"]
        CI["CI/CD Pipeline\n(GitHub Actions)"]
    end
    subgraph PulumiCloud["Pulumi Cloud"]
        AuthN["Identity Provider\n(SAML/OIDC/SCIM)"]
        RBAC["RBAC Engine\n(Org/Team/Stack)"]
        StateStore["Encrypted State\n(HSM-backed)"]
        ESC["ESC\n(Secrets Manager)"]
    end
    subgraph Providers["Cloud Providers"]
        AWS["AWS"]
        Azure["Azure"]
        GCP["GCP"]
    end
    Dev --> AuthN
    CI --> AuthN
    AuthN --> RBAC
    RBAC --> StateStore
    RBAC --> ESC
    RBAC --> Providers

Secrets Management

Built-in Secrets Encryption

Pulumi encrypts individual secret values within the stack state, providing fine-grained protection:

  • Pulumi Cloud secrets provider: Encryption/decryption happens server-side; the key never reaches the client. HSM-backed encryption at rest.
  • Passphrase-based: Local backend uses a passphrase to derive an encryption key (AES-256-GCM).
  • Cloud KMS backends: AWS KMS, Azure Key Vault, GCP KMS for customer-managed keys.
# Set a secret config value
pulumi config set --secret db-password "s3cureP@ss"

# Use in code
config.requireSecret("db-password")

Secrets are tracked transitively — if a secret value is used in a computation, the output is also treated as a secret and masked in CLI output and the Pulumi Cloud console.

Pulumi ESC (Environments, Secrets, and Configuration)

ESC provides centralized secrets management with:

  • Hierarchical environments: Inherit and override secrets across org, team, and project scopes
  • Dynamic credentials: Generate short-lived AWS/Azure/GCP credentials on demand via OIDC
  • External secret stores: Pull from HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, GCP Secret Manager, 1Password
  • Access methods: CLI, API, Kubernetes operator, UI, in-code SDK (TypeScript, Python, Go)

Authorization and RBAC

Pulumi Cloud RBAC

Role Scope Permissions
Org Admin Organization Manage members, teams, billing, all stacks
Team Admin Team Manage team membership, team stacks
Contributor Team/Stack Read/write stacks, run updates
Reader Stack Read-only access to stack state and outputs
Deploy Admin Stack Approve/trigger deployments (Pulumi Deployments)

Stack-Level Access Control

Stacks support granular permissions independent of team membership:

  • Protection policies: Lock stacks against destructive changes
  • Revision history: Full audit trail of all state changes
  • Concurrent update prevention: State locking prevents conflicting updates

CrossGuard Policy as Code

Pulumi CrossGuard enforces organizational policies during previews and updates:

import * as pulumi from "@pulumi/pulumi";

new pulumi.Policy("s3-encryption", {
    enforcementLevel: "mandatory",
    validateResource: (args, reportViolation) => {
        if (args.type === "aws:s3/bucketV2:BucketV2") {
            if (!args.props.serverSideEncryptionConfiguration) {
                reportViolation("S3 buckets must have encryption enabled");
            }
        }
    },
});

Policy packs can be set to advisory (warn), mandatory (block), or disabled per stack.

Provider Credential Security

Dynamic Provider Credentials

Instead of static credentials, use OIDC-based dynamic credentials:

Provider Method
AWS sts:AssumeRoleWithWebIdentity via Pulumi Cloud OIDC
Azure Workload Identity Federation
GCP Workload Identity Federation

Credential Best Practices

  • Never store cloud provider credentials in Pulumi config — use OIDC or ESC
  • Use pulumi config set --secret for any sensitive configuration
  • Rotate personal access tokens regularly; prefer organization tokens for CI
  • Enable SSO for all team members to enforce corporate identity policies

Stack References Security

Stack references allow one stack to read outputs from another:

const infra = new pulumi.StackReference("org/project/infra-stack");
const vpcId = infra.getOutput("vpcId");

Security Considerations

  • Stack outputs are visible to anyone with read access to the referenced stack
  • Secret outputs remain encrypted when accessed via stack references
  • Use RBAC to restrict which teams can read sensitive stack outputs
  • Consider separate organizations for complete isolation between environments

State File Security

  • State stored in HSM-backed encrypted storage
  • All data encrypted in transit (TLS 1.2+) and at rest (AES-256)
  • State files are never written to disk on the client machine during operations
  • Full audit log of all state changes accessible in the Pulumi Cloud console

Self-Managed Backends

When using self-managed backends (S3, Azure Blob, GCS):

  • Enable server-side encryption (SSE-S3, SSE-KMS, or customer-managed keys)
  • Enable versioning to protect against accidental deletion
  • Restrict bucket access using IAM policies
  • Enable access logging for audit trail
  • Use a secrets provider (not passphrase) for production stacks

Hardening Checklist

  • Enable SSO (SAML or OIDC) for all organization members
  • Use dynamic provider credentials (OIDC) instead of static access keys
  • Store all sensitive values with pulumi config set --secret
  • Enable CrossGuard policy packs with mandatory enforcement
  • Use Pulumi Cloud as the state backend (HSM-backed encryption)
  • Configure team-based RBAC with least-privilege access
  • Enable ESC for centralized secrets management
  • Review stack revision history periodically for unauthorized changes
  • Rotate organization tokens and personal access tokens quarterly
  • Enable audit logging for compliance tracking

Known Pitfalls

Pitfall Risk Mitigation
Plaintext secrets in config Credential exposure in version control Always use --secret flag
Static AWS keys in CI Long-lived credential compromise Use OIDC dynamic credentials
Broad org admin membership Overprivileged users Use least-privilege RBAC roles
Unprotected stack references Cross-stack data leakage Restrict stack read access via RBAC
Passphrase state encryption Weak passphrase equals weak encryption Use cloud KMS backends for production