Skip to main content

Practical Case - Containerised Pipeline with Secure Execution

This example illustrates the practical application of the prescriptions of Chapter 09 - from the secure building of the base image to its controlled execution in a CI/CD pipeline and in Kubernetes.

The pipeline in question is responsible for compiling, testing, signing and publishing a Node.js microservice, with 100% containerised execution aligned with the practices of SbD-ToE.


📦 Pipeline structure​

.
├── /.github/workflows/build.yml
├── /Dockerfile
├── /.sbom/
├── /k8s/deployment.yaml
└── /policies/

🔐 Main steps implemented​

StepActual implementationAssociated documentation
Secure base imageFROM node:18.17.0-alpine + USER node01-imagens-base.md
Image signingcosign sign with GitHub OIDC03-assinatura-cadeia-trust.md
SBOM generationsyft . -o cyclonedx-json > .sbom/container.json06-inventario-sbom.md
Vulnerability scannertrivy image with blocking on CVSS > 707-vulnerabilidades-imagens.md
Isolated runnersruns-on: [self-hosted, ephemeral]02-runners-isolamento.md
Execution with enforcementKyverno validate for labels, UID, origin05-policies-runtime-opa.md
Controlled deploy on K8sPod with securityContext and PSA: restricted08-kubernetes-execucao.md

📜 Summarised example of the pipeline (GitHub Actions)​

jobs:
build-and-push:
runs-on: [self-hosted, hardened]
steps:
- uses: actions/checkout@v3
- name: Build Docker image
run: docker build -t registry/project/app:1.0.0 .
- name: Generate SBOM
run: syft docker:registry/project/app:1.0.0 -o cyclonedx-json > sbom.json
- name: Scan for CVEs
run: trivy image --exit-code 1 --severity HIGH registry/project/app:1.0.0
- name: Sign image
run: cosign sign --key env://COSIGN_KEY registry/project/app:1.0.0
- name: Push image
run: docker push registry/project/app:1.0.0

☸️ Controlled execution in Kubernetes​

apiVersion: v1
kind: Pod
metadata:
labels:
app: microservico
sbom: "true"
spec:
securityContext:
runAsNonRoot: true
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
containers:
- name: app
image: registry/project/app:1.0.0
ports: [ { containerPort: 3000 } ]

🔐 This pod will only be accepted in clusters with Pod Security Admission (restricted) + Kyverno policies validating origin and UID.


✅ Results obtained​

  • Pipeline execution that is 100% traceable and aligned with policies;
  • Final image with SBOM, CVE scan and verifiable signature;
  • Deploy to Kubernetes with security enforcement at admission;
  • Auditable, versioned process that can be reapplied to other projects.

🧹 Lessons learned​

  • The use of containers requires discipline and continuous automation;
  • Enforcement at runtime is as important as the secure build;
  • The validation of the image's origin and content must be done before execution - not after;
  • A clear separation between build, validation and execution significantly reduces the attack surface.

📎 Cross-references​

  • Chapter 07 - addon/10-sbd-no-proprio-pipeline.md
  • Chapter 05 - 06-validacao-dependencias.md
  • Chapter 10 - intro.md (tests of containerised execution)

✅ This example shows how to apply the practices of SbD-ToE to the complete lifecycle of containerised execution, in an integrated and realistic way.