Terraform dominates the IaC conversation, but Pulumi and Crossplane are gaining serious traction. Pulumi lets you write infrastructure in general-purpose languages. Crossplane turns Kubernetes into a universal control plane for cloud resources. Both bring genuine advantages -- and security challenges that differ from what Terraform teams deal with.
If your organization is adopting either of these tools, the security patterns you learned from Terraform do not fully transfer. Here is what you need to know.
Pulumi: Infrastructure in Real Code
Pulumi lets you define infrastructure in TypeScript, Python, Go, Java, or C#. This is not a DSL that looks like a programming language -- it is actual code running in a real runtime. That changes the security equation significantly.
The Security Implications of General-Purpose Languages
When your IaC is TypeScript, your infrastructure definitions can do anything that TypeScript can do. They can make HTTP calls, read files, execute system commands, and import arbitrary npm packages. This is powerful and dangerous.
Dependency supply chain risk. A Pulumi program in TypeScript has a package.json with npm dependencies. Those dependencies have transitive dependencies. Every npm supply chain attack -- dependency confusion, typosquatting, compromised maintainer accounts -- applies to your infrastructure code. A malicious package in your Pulumi project's dependency tree could modify your infrastructure during deployment.
This is a risk that Terraform's HCL does not have. HCL is declarative and sandboxed. You cannot import arbitrary packages or execute arbitrary code. Pulumi's flexibility is its greatest strength and its greatest security challenge.
Code injection risks. If your Pulumi program constructs resource configurations from external inputs -- environment variables, API responses, configuration files -- those inputs need validation. A Pulumi program that reads a configuration value and uses it to set an IAM policy without validation could be tricked into creating overly permissive policies.
Runtime environment security. Pulumi programs execute on the machine running pulumi up. That machine needs access to your cloud credentials and your state backend. If the runtime environment is compromised, the attacker has everything needed to modify your infrastructure.
Securing Pulumi Deployments
Pin all dependencies. Use lock files (package-lock.json, go.sum, etc.) and verify their integrity. Run npm audit or equivalent as part of your CI pipeline before applying infrastructure changes.
Scan Pulumi code with standard SAST tools. Because Pulumi programs are real code, standard static analysis tools work on them. Run ESLint security plugins, Bandit (for Python), or gosec (for Go) on your Pulumi programs.
Use Pulumi's policy framework (CrossGuard). CrossGuard lets you write policy checks in the same language as your infrastructure. Policies run against the resource graph before any changes are applied. Use them to enforce encryption, restrict public access, and validate IAM configurations.
Isolate the Pulumi runtime. Run pulumi up in a dedicated CI/CD environment with minimal permissions. Do not run it on developer laptops for production deployments. Use Pulumi Cloud or a locked-down CI runner.
Encrypt state and secrets. Pulumi encrypts secrets in state by default (unlike Terraform). You can choose the encryption provider -- Pulumi Cloud, AWS KMS, Azure Key Vault, or GCP KMS. Use a cloud KMS for production workloads.
Crossplane: Kubernetes as Control Plane
Crossplane takes a fundamentally different approach. Instead of running a CLI tool that calls cloud APIs, Crossplane extends the Kubernetes API server with custom resource definitions (CRDs) that represent cloud resources. You create an S3 bucket by applying a YAML manifest to your Kubernetes cluster.
The Security Implications of Kubernetes-Native IaC
Kubernetes becomes your most critical system. If Crossplane manages your cloud infrastructure, then compromising the Kubernetes cluster means compromising everything. The cluster is not just running your applications -- it is the control plane for your entire cloud environment.
RBAC complexity increases. Crossplane introduces dozens of CRDs. Each CRD type needs RBAC rules controlling who can create, modify, and delete those resources. A misconfigured RBAC rule could let a developer in one namespace create resources in another team's cloud account.
Provider credentials are stored in the cluster. Crossplane providers need credentials to authenticate with cloud APIs. These credentials are stored as Kubernetes secrets. Anyone with access to those secrets has the same cloud access as Crossplane.
Compositions hide complexity. Crossplane Compositions let platform teams create abstractions that developers use. A developer might create a "database" resource without knowing it provisions an RDS instance, a security group, a subnet group, and an IAM role. If the Composition has a security flaw, every developer who uses it inherits that flaw.
Securing Crossplane Deployments
Harden the Kubernetes cluster. Enable RBAC, network policies, pod security standards, and audit logging. The cluster running Crossplane should be treated as a tier-zero security asset with the strictest controls in your organization.
Use IRSA, workload identity, or pod identity. Instead of storing static credentials as Kubernetes secrets, use identity federation. On EKS, use IAM Roles for Service Accounts. On GKE, use Workload Identity. On AKS, use Workload Identity. This eliminates long-lived credentials.
Scope provider permissions narrowly. The Crossplane provider's cloud IAM role should have only the permissions needed to manage the resources you define. Do not give it admin access to your cloud account.
Review Compositions carefully. Every Composition should go through security review. Check that resources created by the Composition have proper encryption, network isolation, and access controls. Since Compositions are used by many consumers, a flaw in a Composition is a flaw at scale.
Use Crossplane's built-in validation. Crossplane supports composition validation and OpenAPI schema validation for XRDs. Use these to prevent invalid or insecure configurations from being accepted.
Implement GitOps for Crossplane resources. Use Argo CD or Flux to manage Crossplane resources through Git. This provides code review for infrastructure changes and an audit trail of who approved what.
Monitor Crossplane provider activity. Crossplane providers make cloud API calls on behalf of Kubernetes resources. Monitor these API calls in CloudTrail, Azure Activity Log, or GCP Audit Logs. Unusual API patterns could indicate a compromised cluster.
Security Scanning for Both Tools
Pulumi scanning. Use Checkov, which supports Pulumi programs by analyzing the resource graph. CrossGuard policies provide native policy enforcement. Standard SAST tools cover the code itself.
Crossplane scanning. Use OPA/Gatekeeper or Kyverno to enforce policies on Crossplane CRDs before they are reconciled. Checkov also supports scanning Kubernetes manifests that include Crossplane resources.
Both tools need dependency scanning. Pulumi programs have language package dependencies. Crossplane has provider images that contain dependencies. Scan both with standard vulnerability scanners.
Comparing Security Postures
| Aspect | Terraform | Pulumi | Crossplane | |--------|-----------|--------|------------| | Code injection risk | Low (DSL) | High (general-purpose) | Low (YAML) | | Dependency supply chain | Providers only | Full language ecosystem | Provider images | | State security | Manual encryption | Default encryption | Kubernetes etcd | | Policy frameworks | Sentinel, OPA | CrossGuard | Gatekeeper, Kyverno | | Credential management | Environment/config | Environment/config | Kubernetes secrets | | Audit trail | State file | State file | Kubernetes audit log |
How Safeguard.sh Helps
Safeguard.sh provides supply chain security for your infrastructure code regardless of whether you use Terraform, Pulumi, or Crossplane. For Pulumi, it scans the language-specific dependencies in your infrastructure programs for vulnerabilities and tracks them alongside your application dependencies. For Crossplane, it monitors the provider images running in your cluster and alerts you to vulnerabilities in the Crossplane control plane itself.
The platform gives you a unified view of your infrastructure supply chain risk across all IaC tools, helping you identify which infrastructure code is most exposed and where to focus your hardening efforts.