# deploy/gitlab/examples/example-pipeline.gitlab-ci.yml # Example GitLab CI pipeline with StellaOps keyless signing # # This example demonstrates: # - Building and pushing a container image # - Generating and signing SBOM # - Evaluating and signing policy verdict # - Verification gate before deployment # # To use, copy this file to your repository's .gitlab-ci.yml include: - local: 'deploy/gitlab/examples/.gitlab-ci-stellaops.yml' # Or include from StellaOps templates project: # - project: 'stella-ops/templates' # file: 'deploy/gitlab/examples/.gitlab-ci-stellaops.yml' stages: - build - scan - sign - verify - deploy variables: DOCKER_TLS_CERTDIR: "/certs" IMAGE: ${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHORT_SHA} # ============================================================================== # Build Stage # ============================================================================== build: stage: build image: docker:24 services: - docker:24-dind before_script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY script: - | docker build -t ${IMAGE} . docker push ${IMAGE} # Get digest DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' ${IMAGE} | cut -d@ -f2) echo "IMAGE_DIGEST=${DIGEST}" >> build.env echo "IMAGE_REF=${CI_REGISTRY_IMAGE}@${DIGEST}" >> build.env artifacts: reports: dotenv: build.env rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - if: $CI_COMMIT_TAG # ============================================================================== # Scan Stage # ============================================================================== generate-sbom: stage: scan extends: .stellaops-sbom needs: - build variables: IMAGE: ${IMAGE_REF} SBOM_FORMAT: "cyclonedx-json" SBOM_OUTPUT: "sbom.cdx.json" rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - if: $CI_COMMIT_TAG vulnerability-scan: stage: scan image: stella-ops/cli:latest needs: - build script: - | stella scan vulnerability \ --image "${IMAGE_REF}" \ --output json > vulnerabilities.json # Extract summary CRITICAL=$(jq '.summary.critical // 0' vulnerabilities.json) HIGH=$(jq '.summary.high // 0' vulnerabilities.json) echo "Critical: ${CRITICAL}, High: ${HIGH}" if [[ "${CRITICAL}" -gt 0 ]]; then echo "WARNING: ${CRITICAL} critical vulnerabilities found" fi artifacts: paths: - vulnerabilities.json rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - if: $CI_COMMIT_TAG # ============================================================================== # Sign Stage # ============================================================================== sign-image: stage: sign extends: .stellaops-sign needs: - build variables: ARTIFACT_DIGEST: ${IMAGE_DIGEST} ARTIFACT_TYPE: "image" rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - if: $CI_COMMIT_TAG evaluate-policy: stage: sign extends: .stellaops-verdict needs: - build - vulnerability-scan variables: IMAGE: ${IMAGE_REF} POLICY: "production" FAIL_ON_BLOCK: "false" # Don't fail here, let verify stage handle it rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - if: $CI_COMMIT_TAG # ============================================================================== # Verify Stage # ============================================================================== verify-for-deployment: stage: verify extends: .stellaops-verify needs: - build - sign-image - generate-sbom - evaluate-policy variables: ARTIFACT_DIGEST: ${IMAGE_DIGEST} CERTIFICATE_IDENTITY: "project_path:${CI_PROJECT_PATH}:ref_type:branch:ref:${CI_COMMIT_REF_NAME}" CERTIFICATE_OIDC_ISSUER: "${CI_SERVER_URL}" REQUIRE_SBOM: "true" REQUIRE_VERDICT: "true" STRICT: "true" rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - if: $CI_COMMIT_TAG # ============================================================================== # Deploy Stage # ============================================================================== deploy-staging: stage: deploy needs: - build - verify-for-deployment environment: name: staging url: https://staging.example.com script: - | echo "Deploying ${IMAGE_REF} to staging" echo "All attestations verified:" echo " - Image signature: ${ATTESTATION_DIGEST}" echo " - SBOM: ${SBOM_ATTESTATION_DIGEST}" echo " - Policy verdict: ${VERDICT_ATTESTATION_DIGEST}" # Add your deployment commands here # kubectl set image deployment/app app=${IMAGE_REF} rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH deploy-production: stage: deploy needs: - build - verify-for-deployment - deploy-staging environment: name: production url: https://example.com script: - | echo "Deploying ${IMAGE_REF} to production" echo "Policy verdict: ${VERDICT}" # Add your deployment commands here rules: - if: $CI_COMMIT_TAG when: manual