$npx -y skills add vinayaklatthe/microsoft-security-skills --skill iac-securityGuidance for securing Infrastructure-as-Code (Bicep, ARM, Terraform, and ACI/Container) pipelines on Azure — shift-left scanning, policy-as-code, secret hygiene, identity for pipelines, drift detection, and supply chain. Covers Microsoft Defender for Cloud DevOps Security (GitHub
| 1 | # Infrastructure-as-Code Security on Azure |
| 2 | |
| 3 | Most cloud breaches now route through misconfigured infrastructure that was provisioned |
| 4 | by code. Hardening the IaC pipeline — Bicep, ARM, Terraform, and the CI/CD that runs |
| 5 | them — moves security left of the deploy: misconfigurations get caught at PR review |
| 6 | instead of in a Defender for Cloud finding three weeks later. |
| 7 | |
| 8 | ## When to use |
| 9 | Designing or hardening the IaC pipeline (GitHub Actions / Azure DevOps / GitLab) for |
| 10 | Azure, including scanning, policy-as-code, pipeline identity, and supply-chain controls. |
| 11 | |
| 12 | **Do not use this skill** for K8s admission control alone (`defender-for-containers`), |
| 13 | general CI/CD architecture, or app-layer security. |
| 14 | |
| 15 | ## Capability stack |
| 16 | |
| 17 | | Layer | Capability | |
| 18 | |---|---| |
| 19 | | **Pipeline identity** | OIDC federation (no client secrets), Workload Identities Premium | |
| 20 | | **Pre-commit / PR-time scanning** | Microsoft Security DevOps (MSDO) Action / Extension; Bicep linter; tflint; checkov; trivy; secret scanning | |
| 21 | | **Policy-as-code gate** | Azure Policy in `Audit` and `Deny` modes at deploy; CI evaluation via `az policy` what-if, Terraform `azapi` policy preview | |
| 22 | | **Posture connect-back** | Defender for Cloud DevOps Security connectors to GitHub / Azure DevOps | |
| 23 | | **Drift detection** | Defender for Cloud, Terraform plan in scheduled CI, GitOps controllers (Flux/ArgoCD) on AKS | |
| 24 | | **Supply chain** | Signed commits, dependency review, artifact signing (Notation/cosign), allowed module registries | |
| 25 | |
| 26 | ## Approach |
| 27 | |
| 28 | 1. **Replace pipeline secrets with OIDC federation.** Every modern Azure CI integration |
| 29 | supports federated workload identity: |
| 30 | - GitHub Actions → Azure: federated credential on user-assigned MI; no |
| 31 | `AZURE_CREDENTIALS` JSON secret. |
| 32 | - Azure DevOps → Azure: Workload Identity federation service connection. |
| 33 | Pin federated credentials to **specific environments / branches** |
| 34 | (`environment:prod`, not `repo:org/repo:*`). See `entra-workload-identity`. |
| 35 | |
| 36 | 2. **Minimum scopes for pipeline identity.** Per-pipeline service principal/MI with |
| 37 | role assignments at RG / resource scope, not subscription Owner. Use deployment |
| 38 | stacks (Bicep) for blast-radius containment. |
| 39 | |
| 40 | 3. **Adopt Microsoft Security DevOps (MSDO) Action / Extension.** Bundles open-source |
| 41 | scanners (template-analyzer, checkov, terrascan, trivy, bandit, ESLint security) |
| 42 | plus secret scanning (CredScan). Single integration point; fail PR on critical |
| 43 | findings. |
| 44 | |
| 45 | 4. **Bicep specifics.** |
| 46 | - Use `bicep build` + `bicep lint` in CI. |
| 47 | - Use **template specs** for shared patterns; version them. |
| 48 | - Use **deployment stacks** with `denySettings` to prevent humans from drifting |
| 49 | stack resources outside the pipeline. |
| 50 | - Use module registries (private ACR or Bicep registry) with signed modules. |
| 51 | |
| 52 | 5. **Terraform specifics.** |
| 53 | - **Backend hardening**: state in Azure Storage with private endpoint, Customer |
| 54 | Lockbox + RBAC scoped, soft-delete + versioning + locking. |
| 55 | - **Provider version pinning** (~> for minor, exact for security-critical). |
| 56 | - **`tflint` + `checkov`** in CI; **`tfsec` is deprecated** — replaced by trivy. |
| 57 | - **`terraform plan` artifact** posted to PR for reviewer; Apply gated on approval. |
| 58 | - **Drift detection** via scheduled `terraform plan` against current state. |
| 59 | |
| 60 | 6. **Policy-as-code gate.** Azure Policy in **Deny** mode for non-negotiable controls: |
| 61 | - No public IP on VMs. |
| 62 | - Private endpoint required on Storage / SQL / Key Vault. |
| 63 | - Encryption + diagnostic settings + tags required. |
| 64 | In CI, run `az deployment what-if` (Bicep/ARM) or evaluate against Policy via |
| 65 | `Get-AzPolicyComplianceForResource` to surface deny-mode failures **before** apply. |
| 66 | |
| 67 | 7. **Secret hygiene.** |
| 68 | - **CredScan / GitHub Advanced Security secret scanning** on |