
Citadel Cloud Management
Compliance as Code OPA + Sentinel
DevOps PipelinesCreated by Kenny Ogunlowo
Product Description
Compliance as Code OPA + Sentinel
Security scanning bolted onto the end of a pipeline is theater. I learned this at Lockheed Martin, where a scan running after deployment means vulnerabilities are already in production by the time the report appears in someone's inbox three days later. At Cigna, a dependency vulnerability in a healthcare data pipeline went unpatched for 4 months because the security scan was an optional, non-blocking step that developers skipped when they were behind on sprint deadlines. This template makes security a blocking gate at every stage — not a post-mortem checkbox.
This GitHub Actions workflow implements a full DevSecOps pipeline with security scanning at five distinct points: code commit, dependency resolution, container build, infrastructure template, and runtime configuration.
Pipeline Stages
-
secret-detection —
trufflesecurity/trufflehog@v3.63.0scans the full git history (not just the diff) for API keys, database passwords, JWT secrets, and cloud credentials. Runs first because leaked secrets invalidate everything else. -
sast —
github/codeql-action/analyze@v3for CodeQL analysis across JavaScript, Python, Go, Java, and C#. Custom query packs add rules for OWASP Top 10: SQL injection, XSS, SSRF, path traversal, insecure deserialization. -
dependency-scan —
actions/dependency-review-action@v4checks new dependencies added in PRs against the GitHub Advisory Database. Blocks PRs that introduce known-vulnerable packages.ossf/scorecard-action@v2.3.1evaluates dependency health. -
iac-scan —
bridgecrewio/checkov-action@v12scans Terraform, CloudFormation, Kubernetes manifests, and Dockerfiles. Over 1,000 built-in policies covering AWS, Azure, and GCP misconfigurations. -
container-scan —
aquasecurity/trivy-action@0.24.0scans built images for OS and application vulnerabilities. Severity gate blocks on CRITICAL and HIGH. SARIF output feeds GitHub Security tab. -
license-compliance —
fossas/fossa-action@v1checks dependency licenses against an approved list. Blocks copyleft licenses (GPL, AGPL) in commercial projects. Generates attribution document for legal. -
dast —
zaproxy/action-full-scan@v0.10.0runs OWASP ZAP against the deployed staging environment. Finds XSS, CSRF, insecure headers, and authentication bypasses that static analysis cannot detect. - report-aggregate — Consolidates all scan results into a single GitHub issue with severity counts, affected files, and remediation links. Tags the security team for CRITICAL findings.
What Each Gate Catches
- TruffleHog — AWS access keys, GCP service account JSON, Stripe API keys, database connection strings, SSH private keys, Slack webhooks.
- CodeQL — SQL injection via string concatenation, XSS via unsanitized output, SSRF via user-controlled URLs, path traversal via unsanitized file paths.
-
Checkov — Public S3 buckets, security groups with 0.0.0.0/0 ingress, unencrypted EBS volumes, IAM policies with
*resources, missing CloudTrail logging. - Trivy — CVE-2024-class vulnerabilities in base image OS packages, outdated npm/pip dependencies with known exploits, embedded credentials in image layers.
Environment Matrix
Every scan runs on every PR — no exceptions, no skip labels. SAST and secret detection run in parallel to minimize pipeline duration. Container scanning runs after build. DAST runs against staging after deployment. Production deployment is gated on zero CRITICAL findings across all scanners.
Common Failures
-
CodeQL timeout on large repositories — Repositories with 500K+ lines of code exceed the 2-hour CodeQL analysis limit. Fix: configure
pathsandpaths-ignorein the CodeQL config to exclude generated code, vendor directories, and test fixtures. -
Trivy false positives on distroless images — Distroless base images report vulnerabilities in packages that are not actually installed (only metadata remains). Fix: use
--ignore-unfixedflag and maintain a.trivyignorefile reviewed monthly. - ZAP scan hitting rate limits — The DAST scan sends thousands of requests that trigger WAF rate limiting, causing false positive connection errors. Fix: configure ZAP's request-per-second limit and whitelist the scanner's IP in the WAF rules for the staging environment only.