Akhil
Home
Experience
Achievements
Blog
Tools
Contact
Resume
Home
Experience
Achievements
Blog
Tools
Contact
Resume
Portfolio

Building robust and scalable cloud-native solutions with modern DevOps practices.

Navigation

  • Home
  • Experience
  • Achievements
  • Blog
  • Tools
  • Contact

Get in Touch

akhil.alakanty@gmail.com

+1 (248) 787-9406

Austin, TX

GitHub
LinkedIn
Twitter
Email

© 2025 Akhil Reddy. All rights reserved.

Built with Next.js, Tailwind CSS, and Framer Motion. Deployed on Vercel.

    Who Built This? Securing Our Software Supply Chain with SBOM, Cosign, and Kyverno

    How do you know the container image running in production is the exact one your CI pipeline built? Learn how we implemented a modern, verifiable supply chain using SBOMs for transparency, Cosign for signing, and Kyverno for enforcement.

    8/3/2025, 8:00:00 PM
    SecuritySupply ChainCosignSBOMKyvernoSLSA

    The Modern Trojan Horse

    In today's world, we don't just write code; we assemble it from a vast ecosystem of open-source dependencies. A sophisticated attacker doesn't need to breach your firewall if they can sneak a malicious library into your application. This is a software supply chain attack, and it's one of the biggest threats facing modern development.

    How can we be sure that the container image running in production is exactly what we intended to build, free from tampering and with a clear record of its contents? We needed a system to provide provenance and integrity.

    Our Three-Step Solution

    We built a robust security pipeline using three key open-source tools:

    1. Syft to generate a Software Bill of Materials (SBOM).
    2. Cosign to sign our container images and attach the SBOM as a verifiable attestation.
    3. Kyverno to enforce a policy in our Kubernetes cluster that only allows signed images from trusted builders.

    Here’s how it all fits together:

    sequenceDiagram
        participant CI as CI/CD Pipeline
        participant Reg as Container Registry
        participant K8s as Kubernetes API
        participant Kyverno as Kyverno Webhook
    
        CI->>CI: 1. Build Image
        CI->>CI: 2. Generate SBOM with Syft
        CI->>CI: 3. Sign image & attest SBOM with Cosign
        CI->>Reg: 4. Push Image, Signature, & Attestation
    
        participant Dev as Developer
        Dev->>K8s: 5. `kubectl apply -f app.yaml`
        K8s->>Kyverno: 6. Validate Request
        Kyverno->>Reg: 7. Fetch Signature & Attestation
        Kyverno->>Kyverno: 8. Verify against Public Key
        alt Valid Signature & Attestation
            Kyverno-->>K8s: Allow
        else Invalid or Missing
            Kyverno-->>K8s: Deny
        end
    

    Step 1: Generating the SBOM

    An SBOM is a detailed inventory of every component in your application. It's like a list of ingredients for your software. We use Anchore's Syft to scan our image and generate an SBOM in the standard SPDX format.

    # In our CI pipeline, after building the image
    IMAGE="my-registry/my-app:v1.2.3"
    syft $IMAGE -o spdx-json > sbom.spdx.json
    

    Step 2: Signing and Attesting with Cosign

    Next, we use Cosign to perform two critical actions:

    1. Sign the image: This creates a cryptographic signature that proves the image was built by our CI pipeline and hasn't been altered.
    2. Attest the SBOM: We attach the SBOM we just generated to the image as a formal, verifiable attestation. This links the image's contents to its signature.
    # Assumes COSIGN_PRIVATE_KEY is a CI/CD secret
    # The public key is distributed to our clusters
    
    # Sign the image digest
    cosign sign --key env://COSIGN_PRIVATE_KEY $IMAGE
    
    # Attach the SBOM as an attestation
    cosign attest --key env://COSIGN_PRIVATE_KEY --predicate sbom.spdx.json --type spdx $IMAGE
    

    Now, the image, its signature, and its SBOM attestation are all stored together in our container registry.

    Step 3: Enforcing Verification with Kyverno

    This is the final and most important step. A signature is useless if you don't check it. We use a Kyverno ClusterPolicy to act as an admission controller in Kubernetes. This policy rejects any Pod that tries to run a container image that isn't signed with our trusted key.

    apiVersion: kyverno.io/v1
    kind: ClusterPolicy
    metadata:
      name: check-image-signature
    spec:
      validationFailureAction: enforce
      rules:
      - name: verify-image-signature
        match:
          resources:
            kinds:
            - Pod
        verifyImages:
        - image: "my-registry/my-app:*"
          key: |-
            -----BEGIN PUBLIC KEY-----
            MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...
            -----END PUBLIC KEY-----
          attestations:
          - type: "spdx"
            conditions:
            - all:
              - key: "{{ data.predicate.name }}"
                operator: "Equals"
                value: "my-app"
    

    This policy tells Kubernetes: "For any image matching my-registry/my-app:*, verify it has a valid signature using this public key AND that it has an SPDX attestation where the package name is my-app."

    The Impact: A Chain of Trust

    • Tamper-Proof Deployments: We have cryptographic proof that the code running in production is the exact code that passed our CI checks.
    • Automated Compliance: Generating an SBOM for every build gives us an instant, auditable asset inventory for compliance and vulnerability management.
    • Developer Transparency: Developers don't need to change their workflow. The signing and verification are completely automated within the platform.

    By implementing this chain of trust, we've hardened our defenses against one of the most insidious threats in modern software development.