← Back to Engineering Insights

Cloud Infrastructure & DevSecOps

DevSecOps: Hardening CI/CD Pipelines & Software Supply Chain Security

Key Architecture Takeaways

  • Eliminate Long-Lived Cloud Keys: Replace static AWS Access Keys or Azure Service Principals with OpenID Connect (OIDC) federated identity tokens in CI runners.
  • Shift Security Gates Left: Enforce Static Application Security Testing (SAST) and secret detection (TruffleHog, Gitleaks) as non-blocking pre-commit hooks and blocking pull request gates.
  • Generate Software Bills of Materials (SBOM): Automatically emit CycloneDX or SPDX metadata to audit third-party open-source vulnerabilities against the National Vulnerability Database (NVD).
  • Sign Artifacts Cryptographically: Use Sigstore/Cosign to digitally sign container images and enforce admission controller policies (Kyverno) preventing unsigned binaries in production.

Continuous Integration and Continuous Deployment (CI/CD) pipelines represent the nervous system of modern software organizations. They possess administrative access to production cloud infrastructure, privileged credentials to proprietary code repositories, and the authority to deploy artifacts directly to mission-critical workloads. Unsurprisingly, threat actors increasingly focus offensive operations not on perimeter web applications, but on the Software Supply Chain—compromising developer dependencies, build agents, and automated release pipelines.

High-profile supply chain compromises (such as SolarWinds and Codecov) underscored that perimeter security is futile if the build pipeline itself is compromised. Transforming a conventional DevOps pipeline into a resilient DevSecOps architecture requires establishing zero trust principles across automated runners, eliminating permanent secrets, enforcing cryptographic provenance, and auditing every software component entering production.

Advertisement

1. Eliminating Static Secrets with OpenID Connect (OIDC)

Historically, deploying software from platforms like GitHub Actions, GitLab CI, or Jenkins to cloud providers (AWS, Google Cloud, Azure) required storing long-lived API keys or service account tokens inside pipeline secret vaults. If a malicious dependency or an insecure pull request workflow script dumps environment variables, these permanent credentials can be exfiltrated and used indefinitely.

The modern standard for enterprise pipelines is Secretless Cloud Deployment via OIDC Federation. Under this paradigm, the CI runner requests a short-lived JSON Web Token (JWT) directly from the Git provider. The cloud provider's Identity and Access Management (IAM) service validates the token's cryptographic signature against the provider's OpenID discovery endpoint and issues temporary, least-privilege cloud credentials valid for mere minutes.

# GitHub Actions workflow using secretless OIDC authentication to AWS
name: Production Secure Deploy
on:
  push:
    branches: [main]

permissions:
  id-token: write   # Required to request the OIDC JWT token
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Codebase
        uses: actions/checkout@v4

      - name: Configure AWS Credentials via OIDC
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsDeploymentRole
          aws-region: us-east-1
          role-session-name: GitHubActionsRelease-${{ github.sha }}

      - name: Deploy to Cloud
        run: |
          aws ecs update-service --cluster production --service api-core --force-new-deployment

2. Shifting Static & Dynamic Security Testing Left

Discovering security vulnerabilities during annual penetration testing cycles is expensive and disruptive. DevSecOps embeds automated vulnerability identification into daily developer workflows without suffocating feature delivery speed. A comprehensive automated security pipeline deploys complementary scanning layers:

Security Gate Tooling Examples Execution Stage Target Vulnerabilities
Secret Scanning Gitleaks, TruffleHog Pre-commit hook & PR gate Committed API keys, private certificates, database connection strings
SAST (Static Analysis) Semgrep, SonarQube, CodeQL Pull request automated check SQL injection patterns, insecure deserialization, path traversal flaws
SCA (Software Composition) Snyk, Dependabot, OSV-Scanner Continuous scheduled scan Known CVEs in transitive open-source npm, NuGet, or pip packages
Container Scanning Trivy, Grype Post-build Docker step Base OS vulnerabilities (Debian/Alpine library CVEs)

3. Hardening Container Builds & Generating SBOMs

Containers built using standard default Dockerfiles frequently package hundreds of unnecessary operating system utilities (such as curl, wget, netcat, and package managers), providing adversaries with ready-made exploit toolkits inside your cluster. Production container images should strictly adhere to the Principle of Minimal Surface Area:

  1. Multi-stage compilation: Build applications inside a heavy development image, and copy strictly the compiled binary into a minimal runtime base (such as Google Distroless or Alpine Linux).
  2. Non-root user execution: Explicitly declare an unprivileged system user (e.g., USER 10001) so compromised container processes cannot access host namespaces.
  3. Software Bill of Materials (SBOM): Generate an immutable machine-readable catalog of every included library using Syft or CycloneDX during build time:
# Multi-stage production container build with minimal attack surface
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["CoreApi/CoreApi.csproj", "CoreApi/"]
RUN dotnet restore "CoreApi/CoreApi.csproj"
COPY . .
RUN dotnet publish "CoreApi/CoreApi.csproj" -c Release -o /app/publish /p:UseAppHost=false

# Production runtime stage: minimal distroless image
FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine AS final
WORKDIR /app
# Run as unprivileged non-root user
USER 10001
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "CoreApi.dll"]

4. Cryptographic Provenance: Signing Artifacts with Cosign

How does your production Kubernetes cluster verify that an image in your container registry was genuinely built by your trusted GitHub Actions workflow, rather than pushed by a compromised developer workstation? The solution is Cryptographic Artifact Signing using Sigstore/Cosign.

During pipeline execution, the runner signs the built container digest using ephemeral keys backed by OIDC identity. Inside the Kubernetes cluster, admission controllers like Kyverno or OPA Gatekeeper intercept pod creation requests and reject any image that lacks a valid cryptographic signature verified against your corporate identity:

# Signing a container image digest inside CI pipeline using Cosign
cosign sign --yes \
  ghcr.io/sunsmitsoftware/enterprise-api@sha256:d8b2e591740... \
  --oidc-issuer https://token.actions.githubusercontent.com

# Kubernetes Kyverno Policy: Block any unsigned container in production namespace
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: verify-image-signatures
spec:
  validationFailureAction: Enforce
  rules:
    - name: verify-signature
      match:
        resources:
          kinds: [Pod]
          namespaces: [production]
      verifyImages:
        - imageReferences: ["ghcr.io/sunsmitsoftware/*"]
          attestors:
            - entries:
                - keyless:
                    issuer: https://token.actions.githubusercontent.com
                    subject: https://github.com/sunsmitsoftware/*

5. Operationalizing Continuous DevSecOps Culture

Automated security tooling inevitably fails if developers treat alerts as annoying barriers to deployment. Successful DevSecOps programs align engineering incentives by enforcing clear service-level objectives (SLOs) around vulnerability remediation (e.g., Critical CVEs patched within 48 hours; High CVEs within 14 days) while providing automated remediation pull requests that streamline dependency upgrades without manual friction.

AP
Ashu Patel

Lead Solutions Architect at Sunsmit Software. Ashu specializes in enterprise DevSecOps pipelines, cloud security architecture, zero-trust infrastructure, and scalable container orchestration.