Skip to content

Full pipeline action map

SARC turns an ordinary CI/CD pipeline into an auditable compliance machine. Every change to the code, infrastructure, or configuration flows through the same thirteen stages, and at each step the pipeline does two things at once: it builds and ships software, and it produces immutable evidence and a real change record that an auditor can later inspect.

This page walks the whole pipeline end to end — what each stage does, and the reasoning behind it — and then shows where the platform’s AI agents step in to find and fix problems. GitLab is the source of truth; GitHub Actions and Azure DevOps run the same shape.

The diagram below is the complete action map. It is interactive — use the on-canvas + / − controls, the mouse wheel, or click-and-drag to pan and zoom into any stage. (Drag the bottom edge of the frame to make it taller.)

%%{init: {'flowchart': {'useMaxWidth': false}}}%%
flowchart TD
  START(["Trigger<br/>push to main · merge request · scheduled"]) --> V

  subgraph V["validate"]
    direction TB
    V1["Lint &amp; validate<br/>yaml · shell · helm lint+template<br/>prisma · typecheck · mcp"]
    V2["Unit tests (karc-portal)"]
  end

  subgraph B["build"]
    direction TB
    B1["Build &amp; push container images<br/>portal -&gt; GHCR · podtato x6 · mcp"]
  end

  subgraph SEC["security"]
    direction TB
    SC1["App scans<br/>SAST · secret detection<br/>dependency · container scanning"]
    SC2["IaC scans<br/>checkov aws/azure/gcp · kics · kubeconform"]
    SC3["SBOM<br/>images + Helm charts"]
  end

  subgraph AT["attest (evidence + change record)"]
    direction TB
    A0["fides begin trail"]
    A1["Evidence Vault attestations<br/>pipeline · policy · artifact<br/>security results · SBOM · pull request"]
    A2["ServiceNow CR create + enrich<br/>compliance report · SBOM attach · fides sync"]
    A4["Supply-chain signing<br/>cosign keyless (Fulcio/Rekor)<br/>SLSA in-toto provenance · verify-image"]
    A5["Fides change-gate<br/>control-coverage map<br/>verdict + 0-100 risk score"]
  end

  subgraph DEV["deploy-dev"]
    direction TB
    D1["ServiceNow approve dev (auto)"]
    D2["Evidence deploy attestation (dev)"]
    D3["Helm deploy -&gt; dev"]
  end

  subgraph DST["dast"]
    direction TB
    Z1["ZAP DAST baseline scan<br/>portal + podtato (post-deploy)"]
  end

  subgraph QA["deploy-qa"]
    direction TB
    Q2{"Fides change-gate + ServiceNow CR gate<br/>Fides verdict/risk advises · SN decides<br/>auto-approve if compliant"}
    Q3["Evidence deploy attestation (qa)"]
    Q4["Helm deploy -&gt; qa + smoke check"]
  end

  subgraph PRD["deploy-prod"]
    direction TB
    P2{"ServiceNow approval<br/>MANUAL CAB only"}
    P3["Evidence approval + deploy attestation (prod)"]
    P4["Helm deploy -&gt; prod"]
  end

  subgraph POST["post-deploy"]
    direction TB
    PO1["ServiceNow CR close<br/>dev · qa · prod"]
  end

  subgraph GO["gitops"]
    direction TB
    G1["Bump image tags / promote chart<br/>ArgoCD GitOps branch"]
  end

  subgraph REL["release (v*.*.* tags only)"]
    direction TB
    R1["Package + push karc-portal Helm chart<br/>as OCI artifact"]
    R2["cosign keyless-sign released image digests<br/>+ OCI chart · attach CycloneDX SBOM<br/>as in-toto attestation · create GitLab Release"]
  end

  subgraph MIR["mirror (scheduled)"]
    direction TB
    M1["Mirror -&gt; GitHub + Azure DevOps"]
    M2["Slack notify on main failure"]
  end

  subgraph PG["pages"]
    direction TB
    PGS["Build &amp; publish showcase site<br/>(this site)"]
  end

  V --> B --> SEC --> AT --> DEV --> DST --> QA --> PRD --> POST --> GO --> REL --> MIR --> PG

  FIDES[("Evidence Vault / Fides<br/>evidence data plane")]
  SNOW[("ServiceNow<br/>change workflow")]
  A1 -.evidence.-> FIDES
  D2 -.evidence.-> FIDES
  Q3 -.evidence.-> FIDES
  P3 -.evidence.-> FIDES
  A2 -.change record.-> SNOW
  A4 -.evidence.-> FIDES
  A5 -.reads evidence.-> FIDES
  Q2 -.gate.-> SNOW
  P2 -.gate.-> SNOW
  PO1 -.close.-> SNOW

  class START trig
  class V1,V2 validate
  class B1 build
  class SC1,SC2,SC3 security
  class A0,A1,A2,A4 attest
  class D1,D2,D3 dev
  class Z1 dast
  class Q3,Q4 qa
  class P3,P4 prod
  class Q2,P2,A5 gate
  class PO1 post
  class G1 gitops
  class R1,R2 release
  class M1,M2 mirror
  class PGS pages
  class FIDES fides
  class SNOW snow

  classDef trig fill:#57606a,stroke:#32383f,color:#ffffff
  classDef validate fill:#1f6feb,stroke:#0b3d91,color:#ffffff
  classDef build fill:#6639ba,stroke:#3b1f7a,color:#ffffff
  classDef security fill:#cf222e,stroke:#82071e,color:#ffffff
  classDef attest fill:#2da44e,stroke:#116329,color:#ffffff
  classDef dev fill:#1b7c83,stroke:#0f4a4e,color:#ffffff
  classDef dast fill:#e8590c,stroke:#9a3b08,color:#ffffff
  classDef qa fill:#d29922,stroke:#8a6500,color:#ffffff
  classDef prod fill:#b62324,stroke:#6e0f10,color:#ffffff
  classDef gate fill:#9a6700,stroke:#5c3d00,color:#ffffff
  classDef post fill:#1f8f6b,stroke:#0d5a42,color:#ffffff
  classDef gitops fill:#8957e5,stroke:#512a8f,color:#ffffff
  classDef release fill:#1f6feb,stroke:#0b3d91,color:#ffffff
  classDef mirror fill:#768390,stroke:#444c56,color:#ffffff
  classDef pages fill:#57606a,stroke:#32383f,color:#ffffff
  classDef fides fill:#2da44e,stroke:#116329,color:#ffffff
  classDef snow fill:#d29922,stroke:#8a6500,color:#ffffff

The solid arrows are the stage progression — a stage only starts when the previous one succeeds. The dotted arrows show the pipeline continuously writing evidence to the Evidence Vault / Fides and driving the change record in ServiceNow. Those two systems are not stages; they are the data planes the pipeline fills as it runs.

Colour key — nodes are coloured by lifecycle phase so the shape of the pipeline reads at a glance:

  • validate and build — pre-ship correctness and artifacts
  • security and DAST — static and dynamic security
  • attest / Evidence Vault — immutable evidence, supply-chain signing, and the Fides change-gate
  • deploy by rising risk: dev qa prod
  • gold diamonds — Fides change-gate + ServiceNow approval gates
  • gitops · release and post-deploy / mirror / pages — release ops

Step by step: what each stage does, and why

Section titled “Step by step: what each stage does, and why”

Each stage has its own detailed page — a colored diagram of that stage’s jobs plus a what/why breakdown of every job:

validate · build · security · attest · deploy-dev · dast · deploy-qa · deploy-prod · post-deploy · gitops · release · mirror · pages

What runs: YAML lint, shell lint, Helm lint + template render, Prisma schema check, TypeScript type-check, MCP config check, and the portal’s unit tests.

The logic: these checks are deterministic and take seconds. Running them first means a typo in a manifest or a broken type never burns expensive build, scan, or deploy minutes. Nothing here touches a cluster — it is pure correctness gating.

What runs: container images are built and pushed to GHCR — the karc-portal, the six podtato-head microservices, and the MCP server.

The logic: everything downstream (scanning, attestation, deployment) must refer to the exact artifact that will run in production. Building once and referencing by digest guarantees the thing you scanned is the thing you ship.

3. security — find problems and generate evidence

Section titled “3. security — find problems and generate evidence”

What runs: SAST, secret detection, dependency (SCA) scanning, container image scanning, IaC scanning (checkov for each cloud, plus kics), kubeconform manifest validation, and SBOM generation for every image and Helm chart.

The logic: this is where vulnerabilities and policy violations surface. Just as important, the outputs of these scans are the raw material for the compliance story — every SARIF report and SBOM becomes evidence in the next stage. (This is also the first place an AI agent can help: triaging and proposing fixes for what the scanners find.)

4. attest — turn output into immutable evidence + a change record

Section titled “4. attest — turn output into immutable evidence + a change record”

What runs: the pipeline opens an evidence trail for the run, then pushes every scan result, every artifact, every SBOM, and pipeline metadata as attestations on that trail. It also does three compliance-critical things:

  • Control-coverage mapping. Each scanner result is mapped to a named policy control — sast-semgrep-scan, secret-detection-scan, dependency-scan-gemnasium, container-scan-grype, sbom-cyclonedx, k8s-manifest-scan, iac-scan-terraform — and recorded as evidence on the Fides trail, so coverage is provable control-by-control rather than as a heap of raw reports.
  • Cryptographic supply-chain provenance. Images are signed with keyless cosign (Fulcio-issued short-lived certs), and the signature is recorded in the public Rekor transparency log. A SLSA in-toto provenance attestation is written to the trail, and fides verify-image records a cosign-verification attestation. Because builds run on a hosted runner and emit signed keyless provenance recorded in a transparency log, this reaches SLSA Build Level 2 and moves toward L3.
  • The ServiceNow change record. In parallel it creates the ServiceNow change request, enriches it with a compliance report and the SBOM, and syncs the evidence across.

From the trail evidence Fides computes an approve/hold verdict and a 0-100 risk score — the Fides change-gate that authorises promotion to qa/prod.

The logic: this is the heart of SARC. A normal pipeline throws its scan output away; SARC records it as tamper-evident, signed evidence tied to a specific artifact digest and a specific change request. Later, “prove this build was scanned, signed, and approved” is a query, not an archaeology project.

5. deploy-dev — first running environment

Section titled “5. deploy-dev — first running environment”

What runs: the dev change request is auto-approved, an evidence deploy attestation is written, and Helm deploys the change to the dev environment.

The logic: dev is low-risk, so approval is automatic — but the deployment is still attested, so even dev has a complete evidence trail. The environment now runs the candidate so dynamic tests have something to hit.

6. dast — dynamic security testing against a live instance

Section titled “6. dast — dynamic security testing against a live instance”

What runs: ZAP baseline scans run against the deployed portal and podtato-head.

The logic: static analysis cannot see runtime behaviour — misconfigured headers, exposed endpoints, auth gaps. DAST exercises the running application, and its findings flow back into the evidence trail.

What runs: the Fides change-gate (verdict + risk score from the trail evidence) feeds a ServiceNow change gate that auto-approves only if the change is compliant, then an evidence deploy attestation, the Helm deploy to qa, and a smoke check.

The logic: promotion is earned, not assumed. Fides advises (verdict + risk score), ServiceNow decides (human approval / segregation of duties), and the pipeline enforces. A change with a clean risk score flows through automatically; a risky one stops and waits for a human. On GitHub Actions the Fides change-gate is a hard block (ADR #446); GitLab is being brought to parity. The decision is driven by recorded evidence, not by someone eyeballing a dashboard.

What runs: a mandatory manual ServiceNow CAB approval, the evidence approval + deploy attestation, then the Helm deploy to prod.

The logic: production is never automatic. Fides still advises with its verdict and risk score, but a change-advisory-board member must approve, and that approval is itself attested. This is the control auditors care about most — and it is enforced by the pipeline, not by policy on paper.

What runs: the ServiceNow change request is closed for each environment.

The logic: a change record that never closes is noise. Closing the CR makes ServiceNow reflect reality, so the change lifecycle is complete and reportable.

10. gitops — ArgoCD owns the final state

Section titled “10. gitops — ArgoCD owns the final state”

What runs: image tags are bumped / the chart is promoted on the GitOps branch, which ArgoCD reconciles onto the clusters.

The logic: the desired cluster state lives in git, not in a pipeline’s imperative steps. ArgoCD continuously converges the cluster to git, so drift is detected and the deployment is declarative and auditable.

11. release — publish a signed, versioned release (v*.*.* tags only)

Section titled “11. release — publish a signed, versioned release (v*.*.* tags only)”

What runs: on an annotated v*.*.* git tag, the pipeline packages the karc-portal Helm chart and pushes it to the registry as an OCI artifact, then cosign keyless-signs the released image digests and the OCI chart, attaches the CycloneDX SBOM as an in-toto cosign attestation, and creates the GitLab Release with auto-generated notes and the chart attached. Unlike the per-commit attest stage, signing here is required — a release that cannot be signed fails.

The logic: a release is the artifact customers actually install, so it carries the strongest provenance: a versioned, immutable OCI chart plus signed, transparency-logged image digests that a consumer can verify with cosign verify before deploying.

12. mirror — keep the replicas in sync (scheduled)

Section titled “12. mirror — keep the replicas in sync (scheduled)”

What runs: the repo is mirrored to GitHub and Azure DevOps twice a day, and Slack is notified on a main-branch failure.

The logic: GitHub and ADO are read-only replicas for demos and parity. They run on a schedule rather than per-push so they never add latency to a developer’s pipeline.

What runs: this showcase site is built from docs/site/ and published to GitLab Pages.

The logic: documentation that ships from the same pipeline is always current — including the page you are reading.

The pipeline is rigorous, but rigour creates work: vulnerabilities to triage, incidents to investigate, costs to tune, and auditors to answer. SARC embeds an AI agent layer (multi-provider — Anthropic, Azure OpenAI, Bedrock, Vertex, or on-prem) that turns those signals into proposed actions. Crucially, anything that writes is human-gated: an agent proposes, an ADMIN approves in /admin/mcp, and only then does it execute — with every step recorded in a hash-chained audit log.

%%{init: {'flowchart': {'useMaxWidth': false}}}%%
flowchart LR
  subgraph SIG["Signals from the pipeline + portal"]
    direction TB
    S1["Vulnerability found<br/>SAST / SCA / container"]
    S2["SLA breach or<br/>high risk score"]
    S3["Production incident"]
    S4["Cost / right-sizing drift"]
    S5["Auditor question"]
  end

  subgraph AI["AI agent layer (multi-provider LLM)"]
    direction TB
    AG1["AskAi explainers<br/>vuln · CR · deploy · trail · problem"]
    AG2["Agent recipes<br/>vuln-suggest-fix<br/>problem-investigate-fix<br/>right-sizing-apply"]
    AG3["NL search + MCP read tools<br/>over Evidence Vault + ServiceNow evidence"]
  end

  subgraph ACT["Proposed actions"]
    direction TB
    P1["Remediation MR / patch"]
    P2["Problem record + fix plan"]
    P3["Right-sizing change"]
  end

  GATE{"Human approval<br/>ADMIN-gated · /admin/mcp"}
  EXEC["MCP-Client Gateway<br/>execute via in-cluster sidecar<br/>hash-chained AuditLog"]
  ANS["Cited answer in portal<br/>(read-only, no write)"]

  S1 --> AG2
  S2 --> AG1
  S3 --> AG2
  S4 --> AG2
  S5 --> AG3
  AG1 --> ACT
  AG2 --> ACT
  AG3 --> ANS
  P1 --> GATE
  P2 --> GATE
  P3 --> GATE
  GATE -->|approved| EXEC
  EXEC -.result feeds back.-> SIG

  class S1,S2,S3,S4,S5 signal
  class AG1,AG2,AG3 ai
  class P1,P2,P3 action
  class GATE gate
  class EXEC exec
  class ANS answer

  classDef signal fill:#cf222e,stroke:#82071e,color:#ffffff
  classDef ai fill:#8957e5,stroke:#512a8f,color:#ffffff
  classDef action fill:#1f6feb,stroke:#0b3d91,color:#ffffff
  classDef gate fill:#9a6700,stroke:#5c3d00,color:#ffffff
  classDef exec fill:#2da44e,stroke:#116329,color:#ffffff
  classDef answer fill:#1b7c83,stroke:#0f4a4e,color:#ffffff

How each capability solves a real problem:

  • Vulnerabilities → vuln-suggest-fix. When the security stage flags a CVE, the agent drafts a remediation (for example a dependency bump) and opens it as a proposed change. A human reviews and approves — the agent shortens time-to-fix without taking the human out of the loop.
  • Understanding findings → AskAi explainers. On any vulnerability, change request, deploy, trail, or problem, an AskAi popover explains it in plain language with links to NVD / OSV / advisories and the cost-impact, so an on-call engineer is not decoding a SARIF blob at 2am.
  • Incidents → problem-investigate-fix. When prod has an incident, the agent correlates the incident to the affected service and ServiceNow Problem record, then proposes a fix plan — collapsing the investigation phase.
  • Cost drift → right-sizing-apply. The agent spots over-provisioned workloads and proposes a right-sizing change tied to the cost data already in the portal.
  • Auditor questions → NL search + MCP read tools. An auditor (or the MCP server’s 12 read tools) can ask, in natural language, for the evidence behind a control. The answer is assembled from the Evidence Vault and ServiceNow data the pipeline already recorded — read-only, fully cited, no write path.
  • Acting safely → the MCP-Client Gateway. Any action that changes something external (for example opening a GitHub issue) follows propose → ADMIN approve → execute through an in-cluster MCP sidecar, and every step is written to a hash-chained AuditLog. The agent never has unsupervised write access.

The result fed back from an executed action becomes a new signal — a fix lands, a scan re-runs, and the evidence trail updates. The agents accelerate the work inside the same compliance guardrails the pipeline enforces.

  • Environment promotion is gated. dev is automatic; qa auto-approves only if the Fides change-gate (verdict + risk score) reports compliant; prod is manual CAB approval, always. The pattern is consistent: Fides advises, ServiceNow decides, the pipeline enforces. On GitHub Actions the Fides change-gate hard-blocks (ADR #446); GitLab is being brought to parity.
  • Infrastructure is not applied by the pipeline. The infra/{aws,azure,gcp} Terraform stacks are applied out of band by ops — there is no terraform apply in any pipeline stage.
  • Most jobs fan out per cloud. TARGET_CLOUD selects the kubectl context, Helm values overlay, and Evidence Vault environment name — the same pipeline shape runs for aws, azure, and gcp.
  • Builds fan out per artifact. The portal, six podtato-head microservices, and the MCP server each build, scan, SBOM, and attest independently — which is why a real run is ~190 jobs.
  • mirror and smoke:e2e are schedule-driven, not part of the per-push flow, so they never add latency to a developer’s pipeline.

For the per-job invocation reference and the GitLab ↔ GitHub ↔ Azure DevOps parity matrix, see the CI docs under docs/ci/, and the conceptual integration map at Pipelines + integration.