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 --secretfor 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¶
Pulumi Cloud (Recommended)¶
- 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
mandatoryenforcement - 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 |