████████ ██ ██ ███████ ██████ ██ ██ █████ ██████ ██████
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██ ███████ █████ ██ ███ ██ ██ ███████ ██████ ██ ██
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██ ██ ██ ███████ ██████ ██████ ██ ██ ██ ██ ██████
multi-cloud CI/CD security pipeline · aws · azure · gcp
Six-gate, shift-left security pipeline for multi-cloud Terraform deployments. Every push runs through secret scanning, SAST, IaC analysis, OPA policy enforcement, dependency audit, and container scanning before any cloud apply is allowed.
push ─▶ [1] TruffleHog ─▶ [2] Semgrep ─▶ [3] Checkov (AWS│Azure│GCP)
│
▼
[4] OPA / Conftest ─▶ [5] pip-audit ─▶ [6] Trivy
│
▼
deploy (OIDC only)
dev → AWS │ staging → Azure │ main → GCP
| # | Gate | Tool | Scope |
|---|---|---|---|
| 1 | Secrets | TruffleHog | repo-wide, verified only |
| 2 | SAST | Semgrep | OWASP Top 10 + python |
| 3 | IaC | Checkov | AWS / Azure / GCP Terraform (parallel) |
| 4 | Policy | OPA + Conftest | custom rego per cloud |
| 5 | Deps | pip-audit | python requirements |
| 6 | Image | Trivy | CRITICAL + HIGH, fail on hit |
Each cloud has its own rego namespace (policies/{aws,azure,gcp}/):
- AWS — block public S3 ACLs, SSH
0.0.0.0/0, unencrypted RDS - Azure — block public blobs, TLS < 1.2, Key Vault without purge protection
- GCP — block
allUsersbucket IAM, GKE legacy ABAC, public Cloud SQL IPs
All three clouds authenticate via OIDC federation — no long-lived keys in GitHub Secrets.
| Cloud | Mechanism |
|---|---|
| AWS | IAM role + OIDC trust policy |
| Azure | Entra federated credential |
| GCP | Workload Identity Federation |
.github/workflows/
security-gates.yml # the 6 gates
deploy-aws.yml # dev → AWS
deploy-azure.yml # stg → Azure
deploy-gcp.yml # main → GCP
terraform/{aws,azure,gcp} # demo IaC (intentional findings)
policies/{aws,azure,gcp} # rego policies
docs/security-decisions.md
checkov -d terraform/aws
conftest test aws-plan.json --policy policies/aws --namespace aws.security
trufflehog filesystem ./
trivy image app:devMIT