Skip to content

Stage: attest

The attest stage is the heart of SARC: it turns raw pipeline output into immutable, queryable compliance evidence and a real change record. It opens an evidence trail in the Evidence Vault / Fides, pushes every artifact, scan result, and SBOM onto it as attestations, maps each scanner result to a named policy control, cryptographically signs the images (keyless cosign, recorded in the Rekor transparency log, with a SLSA in-toto provenance attestation), computes the Fides change-gate verdict + risk score, and creates + enriches the ServiceNow change request. The Evidence Vault is the source of truth, so its jobs are allow_failure: true and never auto-cancelled mid-trail.

Part of the Full pipeline action map. Use the Fullscreen button on the diagram to view it edge-to-edge.

flowchart TD
  IN["Images + scan reports + SBOMs<br/>(from build and security)"]
  BEGIN["fides:begin:trail<br/>open trail at commit SHA"]

  subgraph FIDES["Evidence Vault / Fides attestations"]
    direction TB
    AV["attest:pipeline:validation"]
    AA["attest:artifact<br/>portal + podtato x6 (digest-pinned)"]
    AS["attest:security<br/>25-cell matrix (every scanner)"]
    ASB["attest:sbom<br/>7-cell (portal + podtato images)"]
    AP["attest:policy:aliases<br/>control-coverage map (named controls)"]
    APR["attest:pullrequest (MR only)"]
  end

  subgraph SUPPLY["Supply-chain provenance"]
    direction TB
    SG["supply-chain:sign<br/>cosign keyless (Fulcio/Rekor)<br/>portal + podtato x6, by digest"]
    SL["fides attest slsa<br/>SLSA in-toto provenance"]
    VI["fides:verify-image<br/>cosign-verification attestation"]
  end

  subgraph SNOW["ServiceNow change record"]
    direction TB
    CR["cr:create (+ cr:create:infra)<br/>risk score -> auto-approve flag"]
    RPT["cr:comply-report — bundle evidence"]
    SB["cr:sbom-attach — SBOM zip"]
    SY["fides:sync — u_fides_* tables"]
  end

  GATE{"Fides change-gate<br/>verdict + 0-100 risk score<br/>authorises qa/prod"}

  KDB[("Evidence Vault / Fides trail")]
  SDB[("ServiceNow CR")]

  IN --> BEGIN --> FIDES
  FIDES --> SUPPLY
  SUPPLY --> SNOW
  FIDES -.evidence.-> KDB
  SUPPLY -.evidence.-> KDB
  KDB -.reads.-> GATE
  SNOW -.change record.-> SDB

  class BEGIN,AV,AA,AS,ASB,AP,APR,SG,SL,VI,KDB attest
  class CR,RPT,SB,SY,SDB snow
  class GATE gate
  class IN io
  classDef attest fill:#2da44e,stroke:#116329,color:#ffffff
  classDef snow fill:#d29922,stroke:#8a6500,color:#ffffff
  classDef gate fill:#9a6700,stroke:#5c3d00,color:#ffffff
  classDef io fill:#57606a,stroke:#32383f,color:#ffffff

Evidence Vault — building the evidence trail

Section titled “Evidence Vault — building the evidence trail”
JobWhat it doesWhy
fides:begin:trailOpens an evidence trail at the commit SHA, linked to the repo.Every attestation lands on one trail per pipeline; needed before any attest.
fides:attest:pipeline:validationAttests the validate stage passed (compliant=true/false).All policies (dev/qa/prod) require pipeline-validation evidence.
fides:attest:artifact (+ :podtato ×6)Attests each OCI image by digest (daemon-free pull).Records the immutable artifact fingerprint; digest-pinning survives tag rewrites.
fides:attest:security (25-cell matrix)Attaches every scanner’s report (Trivy, Grype, checkov, kubeconform, GitLab scanners…) to the trail.Aggregates all security evidence; omits truthfully if a scanner was gated out.
fides:attest:sbom (7-cell)Attaches the CycloneDX SBOMs for portal + each podtato image.Supply-chain inventory on the trail per policy.
fides:attest:policy:aliasesRe-posts evidence under policy-canonical control names — sast-semgrep-scan, secret-detection-scan, dependency-scan-gemnasium, container-scan-grype, sbom-cyclonedx, k8s-manifest-scan, iac-scan-terraform.The control-coverage map: each scanner result becomes evidence against a named control, so coverage is provable control-by-control. Omits if upstream didn’t run (truthful MISSING, not false-compliant).
fides:attest:pullrequestAttests MR metadata (MR pipelines only).Satisfies the prod-strict “pull-request” evidence requirement.
JobWhat it doesWhy
supply-chain:sign:portal (+ :podtato)Cosign-signs each image by digest using keyless signing — a short-lived Fulcio-issued cert from the GitLab CI OIDC identity — and the signature is recorded in the public Rekor transparency log.Anyone can later cosign verify the exact bytes that shipped, against a public transparency log, with no long-lived key to leak.
(within supply-chain:sign) fides attest slsaRecords a SLSA in-toto provenance attestation on the trail.Provenance links the artifact to the build that produced it. Hosted-runner build + signed keyless provenance in a transparency log positions this at SLSA Build Level 2, reaching toward L3.
fides:verify-image:portal (+ :podtato)Runs fides verify-image, recording a cosign-verification attestation on the trail — the supply-chain deploy gate.Proves the signature verifies before the artifact is promoted; a build whose signature can’t be verified is caught here.

ServiceNow — creating and enriching the change record

Section titled “ServiceNow — creating and enriching the change record”
JobWhat it doesWhy
servicenow:cr:create (+ :infra)Creates the change request, runs risk scoring against the evidence trail, and writes cr.env with the auto-approve flag.The change record that gates dev→qa→prod; risk scoring decides what can auto-approve.
servicenow:cr:comply-reportBundles all scan outputs + SBOMs + the evidence trail link into a compliance report attached to the CR.One attachment for CAB reviewers instead of dozens.
servicenow:cr:sbom-attachZips all CycloneDX SBOMs and attaches them to the CR.Keeps the supply-chain evidence together for auditors.
servicenow:fides:syncSyncs artifacts/test-results/vulnerabilities into the u_fides_* custom tables.Makes the evidence queryable inside ServiceNow’s CMDB.

From the evidence on the trail, Fides computes an approve/hold verdict and a 0-100 risk score (scripts/ci/fides-score.sh). This is the authoritative compliance gate before qa/prod. The division of responsibility is deliberate:

Fides advises (verdict + risk score), ServiceNow decides (human approval / segregation of duties), the pipeline enforces.

On GitHub Actions the change-gate is a hard block — a non-compliant verdict fails the run (ADR #446). On GitLab it is being brought to parity; today the risk score drives the ServiceNow auto-approve flag consumed at the qa/prod gates.

No infrastructure here. The infra/{aws,azure,gcp} Terraform stacks are applied out of band by ops — no terraform apply runs in this (or any) pipeline stage.

A normal pipeline discards its scan output. SARC records it as tamper-evident, signed evidence tied to a specific artifact digest and a specific change request, maps every scanner to a named control, and hands that record to ServiceNow for the human workflow. This is what makes “prove this build was scanned, signed, control-mapped, and approved” a one-line query later.


Stages: securityattestdeploy-dev · all stages