If your assessor wants proof that PCI DSS Requirement 6.3 runs inside your pipeline, write each rule down as a policy, attach it to a gate on the branches that reach the cardholder data environment, and give it one action: Block, Warn or Notify. Route every override through a time-boxed exception with a named approver. Then the gate history, the exception log and your component inventory are the evidence, produced on every build instead of assembled the week before fieldwork.
This post walks that job end to end for a DevSecOps engineer at a fintech. The first two thirds work with whatever CI and scanners you already run. Safeguard enters at "How Safeguard does this", and the honest limits follow it.
Key takeaways
- PCI DSS 6.3.1 asks you to identify and risk rank vulnerabilities, 6.3.2 asks for an inventory of bespoke and custom software and the third-party components inside it, and 6.3.3 sets patch timeframes. A CI gate is a good place to enforce all three and record that you did.
- Change control under 6.5.1 already expects documented approval, testing and a way back to a secure state. A gate that fails a build, plus an exception record, maps onto that language directly.
- Pick one action per rule. Block is for rules you will defend in front of an assessor. Warn is for rules you are still tuning. Notify is for rules someone must see but that should not stop a release.
- Approval belongs in the exception process, not in the gate. Every exception needs a reason, a scope, an approver and an expiry date.
- Safeguard's policies and gates (GA) evaluate on the platform's scans of your connected repositories, with Block, Warn and Notify as the policy actions and exceptions handled through an approval workflow. The Safeguard CLI (GA) can fail a CI job on a gate with
safeguard ci scan --wait --fail-on-gate. - SBOM generation (GA), SCA and vulnerability management with EPSS and KEV enrichment (GA), reachability analysis (GA), license compliance (GA), the compliance and GRC suite with a PCI DSS 4.0 framework (GA), the MCP server (GA) and autonomous remediation (GA, ships switched off with every category set to Manual) support the same workflow.
- This is not legal or audit advice. Your QSA decides what satisfies a requirement for your environment.
The job and who owns it
The person in this story is the DevSecOps engineer at a fintech that stores, processes or transmits card data, or whose software can affect the security of systems that do. They own the CI configuration, the shared pipeline templates, and the on-call pager when a build stops for a reason nobody understands. They do not own the assessment, but they own most of the evidence for Requirement 6.
The trigger is usually a request list. The compliance lead forwards the assessor's evidence request for the coming assessment, and three lines in it land on DevSecOps:
- Show how new vulnerabilities in your software and its third-party components are identified and ranked (6.3.1).
- Provide the inventory of bespoke and custom software and its third-party components (6.3.2).
- Show that critical patches were installed within the required timeframe, and how you decide timeframes for the rest (6.3.3).
A fourth line usually rides along from 6.5.1: show that changes to production follow documented procedures, including approval, testing and a way back.
A bad week looks like this. You have a vulnerability scanner in CI, but it runs in report-only mode on half the repositories because someone turned the threshold down during an outage and never turned it back. The other half fail on any critical finding, so developers have learned to rerun the job until a flaky network call skips the scan. Exceptions live in chat threads. The inventory is whatever the scanner printed last, for whichever branch it happened to run on. All of it is hard to show to an assessor who samples three releases and asks what the gate said on each one.
The goal of this post is a pipeline where the answer to "what did the gate say on that release" is one lookup.
What the rules actually ask for
Quote requirement numbers from the primary text, because summaries drift. The PCI Security Standards Council publishes the standard and the self-assessment questionnaires. The requirement text below is from the Council's published SAQ D for merchants (v4.0), which reproduces the PCI DSS requirements; PCI DSS v4.0.1 is a limited revision that the Council says corrects formatting and clarifies intent without adding or deleting requirements, and v4.0 was retired on 31 December 2024. Read the v4.0.1 text your assessor works from before you finalise thresholds.
PCI DSS Requirement 6.3: security vulnerabilities are identified and addressed
6.3.1 says new vulnerabilities are identified from industry-recognised sources, including CERT alerts, and given a risk ranking based on industry practice and potential impact. At a minimum, rankings must identify everything considered high risk or critical to the environment. The requirement covers bespoke and custom software and third-party software. Its applicability note is worth reading twice: this is not the same as the vulnerability scans in 11.3.1 and 11.3.2. It is a process for knowing about vulnerabilities and ranking them.
6.3.2 says an inventory of bespoke and custom software, and of the third-party components incorporated into it, is maintained to support vulnerability and patch management. The Council made it a best practice until 31 March 2025, after which it must be fully considered during an assessment. It is now in force. In practice this is a software bill of materials per application, kept current.
6.3.3 says system components are protected from known vulnerabilities by installing security patches and updates. In the v4.0 wording, critical or high-security patches identified through the 6.3.1 ranking are installed within one month of release, and all others within a timeframe the entity sets, with three months given as an example. Check how v4.0.1 words the one-month clause; the Council's revision clarified intent on some requirements, and your assessor will use the current text.
PCI DSS Requirement 6.5: changes are managed securely
6.5.1 says changes to production system components follow established procedures that include the reason and description of the change, documentation of security impact, documented change approval by authorised parties, testing that the change does not hurt security, testing of bespoke software changes against 6.2.4 before deployment, and procedures to address failures and return to a secure state.
That list is the best argument for routing approvals through exceptions. The change approval in 6.5.1 is about the change. An exception approval is about letting a change through despite a failed control. Keep them separate and each one stays legible.
PCI DSS Requirement 6.2: bespoke software is developed securely
6.2.3 expects code review before release to find and correct coding vulnerabilities, by manual or automated means. 6.2.3.1 adds that manual reviews are done by someone other than the author and approved by management before release. A required review rule on your protected branch is one way to show that; it is a separate control from the policy gate, and assessors will usually test it separately.
The US rules a fintech also answers to
For a non-bank financial institution under the Federal Trade Commission's jurisdiction, the Safeguards Rule in 16 CFR 314.4 applies alongside your card brand obligations. Three clauses touch the pipeline:
- 314.4(c)(4) requires secure development practices for in-house applications that transmit, access or store customer information, and procedures to evaluate or test externally developed applications you use.
- 314.4(c)(7) requires procedures for change management.
- 314.4(d)(2) requires continuous monitoring, or else annual penetration testing and vulnerability assessments at least every six months and whenever there are material changes.
If you are a bank or a bank's service provider, your prudential regulator's examination expectations apply instead of, or alongside, the FTC rule. Either way, the same gate history and exception log serve as evidence.
The engineering references behind a good gate
NIST SP 800-218, the Secure Software Development Framework (version 1.1, February 2022), gives you the vocabulary for the gate itself. Practice PO.4 is "define and use criteria for software security checks": PO.4.1 defines the criteria and tracks them through the lifecycle, and PO.4.2 implements the mechanisms that gather the information to support those criteria. Task PW.4.4 asks you to verify that acquired commercial, open source and other third-party components comply with your requirements throughout their life cycles.
NIST SP 800-204D (February 2024) covers integrating supply chain security into DevSecOps CI/CD pipelines, including the idea that the pipeline itself is a security-relevant system.
The OWASP Top 10 CI/CD Security Risks names the failure you are trying to avoid. Its first risk, CICD-SEC-1, Insufficient Flow Control Mechanisms, describes a pipeline where one person or one account can push code or artifacts to production without external verification. A policy gate is a flow control. So is a required status check on a protected branch.
Finally, two public signals help you rank. CISA's Known Exploited Vulnerabilities catalog is, in CISA's words, "the authoritative source of vulnerabilities that have been exploited in the wild". FIRST's Exploit Prediction Scoring System estimates the probability that a published CVE will be exploited in the next 30 days. Neither replaces your own 6.3.1 ranking, but both are industry-recognised inputs to it.
How teams do it today and where it breaks
Most fintech pipelines already have the parts. What breaks is the wiring between them.
The threshold lives in a YAML file nobody owns. A scanner step with a severity flag is a policy, but nobody wrote it down as one. When it changes, the change is a one-line diff in a pipeline file, reviewed by whoever was on rotation.
Warn-only becomes permanent. Teams roll out a new rule in report-only mode to see the noise, then never promote it. Six months on, the warnings are ignored and the rule does nothing.
Block on everything, then bypass everything. The opposite failure. A gate that fails on any critical finding with no exception path trains developers to rerun, skip or disable the step. Each bypass is invisible.
Exceptions without expiry. An approved exception in a chat thread or a ticket that never closes is a permanent waiver. PCI DSS 6.3.3 timeframes keep running whether or not someone remembered the thread.
The inventory is a by-product, not a record. The scanner produces a component list on each run, but it is not kept per release, so "what was in the build you shipped on 3 March" has no answer.
The gate and the evidence disagree. The CI log says the build passed. The scanner dashboard, run later on a newer database, says the same commit has a critical finding. Both are true, and the assessor will ask why they differ.
Pipeline configuration is not treated as code. Third-party actions referenced by tag, broad token permissions and shell steps that interpolate pull request titles turn the gate into something an attacker can switch off. GitHub's own hardening guide recommends pinning actions to a full-length commit SHA for this reason.
Step by step: gates an assessor can sample
These steps work with any CI system and any scanner that can fail a job and keep its output. Where a step names a GitHub feature, the same idea exists in the other major CI and source control platforms.
1. Scope the gate to what the assessment covers
List the repositories whose builds reach the cardholder data environment or can affect its security. Mark each with the branch that represents production (usually main and any release/* branches). Gates on those branches are your Requirement 6 evidence. Gates elsewhere are hygiene.
Keep the scoping list next to your PCI scope documentation and update it when a repository moves in or out.
2. Write every rule as a named policy
A policy is a sentence with a condition, an owner and a requirement it serves. Write them before you touch YAML. A starting register for a fintech pipeline might look like this.
| Policy name | Condition (what fails it) | Serves | Owner | Starting action |
|---|---|---|---|---|
| No known exploited vulnerabilities | Any component with a CVE on CISA KEV | 6.3.1, 6.3.3 | AppSec | Block |
| No critical vulnerabilities past timeframe | Critical finding older than your 6.3.3 window | 6.3.3 | AppSec | Block |
| High findings visible | Any new high finding | 6.3.1 | Service team | Warn |
| Inventory present | Build has no current component inventory | 6.3.2 | DevSecOps | Block |
| Pinned component versions | Floating or unpinned dependency references | 6.5.1 | DevSecOps | Warn |
| Approved licenses only | Component with a license outside your allow list | Legal policy | OSS office | Warn, then Block |
| Abandoned packages | Component with no maintenance activity for your chosen period | 6.3.1 risk ranking | AppSec | Notify |
Two rules of thumb. First, one condition per policy, so a failure names exactly one problem. Second, every Block policy should map to a requirement you will defend in an assessment. If you cannot name the requirement, it probably belongs at Warn.
3. Choose one action per policy
Three actions cover almost every case.
| Action | What happens on failure | Use it for | Avoid it for |
|---|---|---|---|
| Block | The gate fails and the build stops | Rules tied to a requirement, with a clear fix path | Rules still producing false positives |
| Warn | The gate passes, with a warning naming the policy | New rules in their tuning period; advisory rules | Anything you will cite as a control to an assessor |
| Notify | The gate passes and the owner is told | Signals someone must act on but that should not stop a release | Rules that need a decision before release |
Notice what is missing: an action that pauses the build until someone approves it. That is deliberate. A gate that waits for a person couples release speed to someone's calendar and hides the decision inside a CI log. Put the decision in an exception instead, where it has a reason, an approver and an expiry.
4. Design the exception path before you turn on Block
Exceptions are what make Block survivable. A usable exception record has six fields.
| Field | What to write | Why the assessor cares |
|---|---|---|
| Policy and finding | The exact policy and the specific finding (component, version, CVE) | Scope: one finding, not a blanket waiver |
| Business justification | Why the release cannot wait, and what compensates in the meantime | Shows a risk decision was made |
| Requester | The engineer or team asking | Accountability |
| Approver | A named role with authority, not the requester | Separation of duties |
| Expiry | A date, inside your 6.3.3 timeframe for that risk ranking | The exception cannot outlive the requirement |
| Outcome | Granted or denied, with the date | Completeness of the record |
Set default expiry windows by risk ranking and write them into your vulnerability management procedure. For example, an exception on a critical finding might default to days, not weeks, and never past the one-month line. The numbers are yours to set and defend; the point is that they are written down and enforced.
5. Wire the gate into branch protection
A gate that fails a job does nothing if the job is optional. Make the gate's CI check a required status check on the protected branches from step 1. GitHub's documentation is explicit: once required status checks are enabled, all of them must pass before changes can be merged into the protected branch. Rulesets can layer these requirements across many repositories, and they let you choose who, if anyone, may bypass them. Keep that bypass list short and review it with the same cadence as exceptions.
Pair the status check with a required pull request review, which covers the code review side of 6.2.3 and the separation of duties idea in CICD-SEC-1.
6. Make the gate itself hard to switch off
A few changes close the obvious holes:
- Pin third-party actions and tools to a full commit SHA or an exact version, so a moved tag cannot change your gate.
- Give the CI token the least permissions the job needs.
- Pass event data such as pull request titles through environment variables rather than interpolating it into shell commands.
- Store the gate's credentials as CI secrets, scoped to the repositories that need them.
- Remember that pull requests from forks usually receive no secrets. Decide how fork contributions are gated rather than discovering it when the step silently does not run.
7. Keep the evidence per release
For each build on a protected branch, keep: the commit, the component inventory (an SBOM in SPDX or CycloneDX), the gate outcome with each policy's result, any exceptions in force, and the time of evaluation. Store it somewhere that outlives CI log retention.
That last field matters because vulnerability data changes after the fact. When the assessor's sample shows a finding today that the gate did not flag at release time, the evaluation time and the inventory let you show what was known when.
8. Roll out in phases
Start every new policy at Warn on all in-scope repositories. Review what would have blocked for two release cycles. Fix false positives in the policy, not with exceptions. Promote to Block on one repository, then on all of them. Write the promotion date in the policy's change history, because "when did this control start operating" is a standard assessor question.
Which gate action fits which PCI DSS clause?
Here is a compact version you can paste into a control narrative.
| Clause | What it asks | Gate design that supports it | Evidence the gate produces |
|---|---|---|---|
| 6.3.1 | Identify and risk rank vulnerabilities | Policies keyed on severity, KEV and EPSS | Policy results per build, with the finding detail |
| 6.3.2 | Maintain an inventory of software and components | Block when the inventory is missing or stale | One SBOM per release |
| 6.3.3 | Patch critical items within the required timeframe | Block on criticals past the window; exceptions expire inside it | Gate history plus exception log with dates |
| 6.5.1 | Documented approval, testing, a way back | Required status check plus exception approvals | Merge records, gate outcomes, exception approvals |
| 6.2.3 | Review code before release | Required review on protected branches | Pull request review records |
How long should an exception last?
As short as the fix takes, and never longer than the requirement allows. A useful default is to tie the maximum expiry to the 6.3.3 timeframe for the finding's risk ranking, then shorten it for anything on KEV. Renewing an exception should be a new request with a new justification, not an edit to the old expiry date.
What does an assessor usually sample?
Expect a handful of releases from in-scope repositories, the gate result for each, the inventory for each, and the record behind any exception that let a failing build through. Expect a question about when each control started operating and whether it changed during the period. Expect a check that the required status check cannot be bypassed casually. Describe this shape to your QSA early and agree what they want to see; do not guess at their sampling method.
Illustrative scenario: a card-issuing fintech prepares for its assessment
This is a composite example, not a customer. The company, people and numbers are invented to show the workflow, and every number below is an example input, not a result.
The fictional company, called Example Card Co. here, runs a card-issuing program on behalf of partner banks. As example inputs: about 40 repositories, 12 of them in PCI scope, deploying from main through GitHub Actions; one DevSecOps engineer and a three-person AppSec team; an assessment window opening in eight weeks.
Week one: scope and register. The DevSecOps engineer lists the 12 in-scope repositories and their protected branches. AppSec drafts a policy register like the one in step 2, with seven policies. Each Block policy names its requirement. The compliance lead reads the register and adds the vulnerability management procedure reference beside each 6.3.3 timeframe.
Week two: Warn everywhere. Every policy goes live at Warn on all 12 repositories. Nothing stops. The engineer reviews what would have blocked and finds that the "pinned versions" policy fires on a build tool that resolves versions at install time. The fix is in the policy condition, not in an exception.
Weeks three and four: promote in order. The KEV policy goes to Block first, on one repository, then all 12. The "inventory present" policy follows. The critical-past-window policy goes to Block last, after AppSec writes default exception expiry windows by risk ranking into the procedure.
Week five: the first real exception. A critical finding lands in a transitive dependency of the payments API on the day of a planned release. The fixed version exists but breaks an integration test. The service team requests an exception scoped to that one finding, with a justification, a compensating step and an expiry inside the window. AppSec's lead approves it. The release goes out. The upgrade pull request merges a few days later, and AppSec closes the exception.
Weeks six to eight: evidence by lookup. For the assessment, the engineer exports the gate history, the exception log and the per-release inventories for the sample the QSA requests. No one assembles anything by hand.
The scenario makes no claim about time saved, findings reduced or audit results; those depend on your environment.
How Safeguard does this
The same workflow, in Safeguard, uses capabilities that are all GA today. Each step links the docs page that describes it.
-
Connect the repositories and create the CI key. Under Settings, Developer, create a secret key with the scopes
scans:triggerandscans:read, optionally locked to one project, and store it in your CI asSAFEGUARD_API_KEY. The CI/CD Integration page lists GitHub Actions, GitLab CI/CD, Bitbucket Pipelines, Jenkins and Azure Pipelines, plus any CI that can run a shell step. There is no plugin to install: each system runs the Safeguard CLI (GA) in a plain shell step. Each push becomes a new version of its Safeguard project, named after the branch and commit, which gives you the per-release record from step 7. -
Add the workflow. The GitHub Actions page gives this template for
.github/workflows/safeguard.yml, which we reproduce as published and have not run here:
name: Safeguard
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- name: Safeguard scan
env:
SAFEGUARD_API_KEY: ${{ secrets.SAFEGUARD_API_KEY }}
SAFEGUARD_INSTALL_DIR: ${{ runner.temp }}/safeguard-bin
run: |
set -eu
curl -fsSL https://cli.safeguard.sh/install | bash
"$SAFEGUARD_INSTALL_DIR/safeguard" ci scan --wait --fail-on critical
The docs list the options: drop --fail-on critical to report only, change the threshold with --fail-on high, add --fail-on-gate all to fail on a policy gate, add a checkout step and --local to scan on the runner, and pin the CLI with SAFEGUARD_VERSION in env so a release does not change a build under you. Pinning is worth doing for the same reason as step 6. By default the scan runs on Safeguard against the connected repository; with --local, only the results leave the runner.
-
Generate the inventory on every scan. SBOM generation and analysis (GA) produces SPDX and CycloneDX inventories, and SCA (GA) builds the full transitive dependency list. That is your 6.3.2 inventory, kept per project version rather than overwritten.
-
Rank what the scan finds. Vulnerability management (GA) enriches findings with EPSS and CISA KEV. Reachability analysis (GA) ranks the vulnerable code paths your application actually calls. Together they give you the inputs to a written 6.3.1 risk ranking; the ranking procedure itself stays yours.
-
Write the policies. The Policies and Gates page describes the builder: under Settings, Policies, create a policy, define conditions with the visual builder or YAML, set severity and action, then save and enable it. Example conditions in the docs include vulnerability severity, CVSS score, EPSS score, license, component age and maintenance status. Pre-built templates include No Critical Vulnerabilities, License Compliance and No Abandoned Packages. Policy creation from plain English prompts (GA) is also available if you would rather describe the rule than build it. License compliance (GA) covers the license policy in the register.
-
Set one action per policy. The Policy outcomes and actions page defines exactly three. Block: the gate fails. Warn: the gate passes with a warning naming the policy. Notify: the gate passes and Safeguard notifies the workspace's configured channels, meaning the in-app bell, connected chat integrations and email by each person's preferences. Notify does not repeat for the same failure; it fires when a policy goes from passing to failing, and again when a failing policy finds new matching issues. New policies have no threshold, so any match fails them.
-
Link policies to gates and read the outcome. A gate takes its outcome from its linked policies in a fixed order: no policies linked is Not evaluated; any failed Block policy is Failed; otherwise any policy that could not be evaluated is Error; otherwise any policy not yet evaluated is Not evaluated; otherwise any failed Warn policy is Warning, which still passes; otherwise Passed, with failed Notify policies listed as notified. An Error never counts as a pass, and a gate that has never been evaluated never shows Passed. Policies re-evaluate when new assessment data arrives for the product. The docs note that policy outcomes are turned on per workspace by Safeguard; if you do not see an Outcome column on the Gates and Policies tables, ask Safeguard to turn it on.
-
Fail the CI job on the gate. Per the policy outcomes page,
safeguard ci scan --wait --fail-on-gatewith a gate name, id orallwaits for the scan and for the gate's policies to be evaluated on the new data. It exits 0 when the gate is Passed or Warning, printing warnings and notified policies. It exits non-zero when the gate is Failed, printing the Block policies that failed, and also when the gate is Error or Not evaluated, or its policies were not evaluated before--timeout.--fail-onwith a severity still works and can be combined with it. Make this job a required status check on your protected branches, as in step 5. -
Handle overrides through exceptions. The Policies and Gates page describes the exception workflow: a developer requests an exception for a policy and finding with a business justification and an expiration date, approvers are notified, an approver reviews and decides, the exception is granted or denied, and the audit trail records it. Approval lives here, not in the gate, which matches the design in step 4.
-
Report and map to PCI DSS. The same page lists compliance reporting by policy, exception history, violation trends and audit documentation. In the compliance and GRC suite (GA), the PCI DSS 4.0 framework page describes scan requirements checked against each product's inventory, including a maintained component inventory (6.3.2), machine-readable inventory format, continuous vulnerability identification (6.3.1), patch applicability data (6.3.3), change-controlled versions with no floating references (6.5.1) and supplier tracking (12.8.1). The framework is on by default and can be switched off in Compliance, Manage.
-
Ask about gate state from an assistant. The policy outcomes page notes that Safeguard's MCP server (GA) has read-only tools for gate outcomes, policy outcomes and evaluation history, available when policy outcomes are on and your MCP access settings allow them. That is useful when the on-call engineer wants to know why a gate failed without opening the console.
-
Fix rather than waive, where you can. Autonomous remediation (GA) can open a tested, policy gated pull request that moves a vulnerable dependency to a fixed version, on one repository or in bulk. It ships switched off, with every category set to Manual, so you decide what runs on its own. A merged fix is a better 6.3.3 record than an exception.
For the business view of this workflow, see the Guardrails and Enforcement use case.
What to measure
Use this as a checklist for your own program. These are measures to track, not outcomes we are claiming.
- Share of in-scope repositories whose gate job is a required status check on every protected branch.
- Number of Block policies, and for each, the requirement it serves and the date it started operating.
- Policies still at Warn, and how long each has been there. Anything at Warn for more than two review cycles needs a decision.
- Gate outcomes on protected branches by week: Passed, Warning, Failed, Error, Not evaluated. Error and Not evaluated should trend to zero.
- Open exceptions, their age, and how many expire in the next 14 days.
- Exceptions renewed more than once. Each one is a fix that is not happening.
- Median time from a Block failure to a merged fix, by risk ranking, compared with your 6.3.3 timeframes.
- Releases on protected branches without a stored inventory. The target is none.
- Bypasses of branch protection or rulesets, and who made them.
- Policy changes in the period, each with a reviewer.
What Safeguard does not do
- It does not decide what satisfies PCI DSS for you. The PCI DSS 4.0 framework mapping and the reports are evidence. Your QSA decides whether a control meets a requirement, and your risk ranking procedure for 6.3.1 is yours to write and defend.
- It does not enforce branch protection. The CLI can fail a CI job on a gate, but making that job required, and controlling who can bypass it, is configured in your source control platform.
- SAST findings do not fail the build through
--fail-onyet. The CI docs say SAST findings are scanned and shown in Safeguard but are not part of--fail-on. Plan severity thresholds around dependency vulnerabilities, and use gates for the rest. - There is no gate command in the CLI. Gates are evaluated by the platform on the scans it runs, and the CI step reads the result.
safeguard scanrun fully on a build machine reports findings without failing the build on them. - Kubernetes admission enforcement is not available. The docs say the admission controller is not published. Enforcement in this workflow happens at CI and merge, not at deploy.
- It does not replace your change management process. Exception approvals record a decision to let a failing build through. The 6.5.1 change record, with its security impact and back-out plan, still lives in your change process.
- It does not test card data handling, segmentation or the payment page. Requirements outside Requirement 6 need their own controls and evidence.
- Fork pull requests need a decision. As the GitHub Actions page notes, GitHub gives fork pull requests no secrets, so the step cannot authenticate. Scan pushes only, or design a fork workflow carefully.
Common mistakes
Turning on Block before the exception path exists. The first urgent release will route around the gate, and that bypass will not be recorded.
Using exceptions to fix noisy policies. If a policy needs a stream of exceptions, the condition is wrong. Change the policy and record the change.
Treating Warn as a destination. A rule that has sat at Warn for a quarter is either not important or not trusted. Decide which.
Letting Error count as a pass. A gate that could not evaluate did not pass. Fail the job, and alert on it.
No expiry, or expiries past the patch window. An exception that outlives the 6.3.3 timeframe for its risk ranking is a finding in waiting.
Keeping evidence in CI logs. Log retention is usually shorter than an assessment period. Store gate outcomes and inventories somewhere durable.
Unpinned tools in the gate. If the scanner version or a third-party action can change between runs, the same commit can pass on Monday and fail on Tuesday, and you will not be able to explain why.
One giant policy. A single "security policy" that fails on many conditions produces failures nobody can act on. One condition per policy.
FAQ
What does PCI DSS 6.3 require in a CI pipeline?
PCI DSS does not prescribe CI tooling. Requirement 6.3 asks you to identify and risk rank vulnerabilities (6.3.1), keep an inventory of your software and its third-party components (6.3.2) and install patches within set timeframes (6.3.3). A CI gate is a practical place to enforce those rules and record that you did.
Is PCI DSS 6.3.2 mandatory now?
Yes. The requirement was a best practice until 31 March 2025 and must be fully considered in assessments after that date.
What gate actions should a fintech pipeline use?
Block for rules tied to a requirement with a clear fix path, Warn for rules being tuned or advisory, and Notify for signals someone must see without stopping a release. Handle approvals through time-boxed exceptions rather than a gate that waits for a person.
How do policy gate exceptions work in Safeguard?
The docs describe a developer requesting an exception for a specific policy and finding, with a business justification and an expiration date. Approvers are notified, one reviews and decides, and the outcome is recorded in the audit trail. Exception history appears in compliance reporting.
Can Safeguard fail a GitHub Actions build on a policy gate?
Yes. Add --fail-on-gate all, or a specific gate name or id, to the safeguard ci scan --wait step. The job exits non-zero when the gate is Failed, Error or Not evaluated, and zero when it is Passed or Warning.
Does a Warn policy stop a release?
No. In Safeguard a failed Warn policy leaves the gate at Warning, which passes, with a warning naming the policy. Only a failed Block policy fails the gate.
Is an SBOM enough for PCI DSS 6.3.2?
An SBOM per release is the usual way to show the inventory, provided it covers bespoke and custom software and the third-party components incorporated into it, and is kept current. Your assessor decides whether your inventory meets the requirement.
How do I show 6.3.3 patch timeframes to an assessor?
Show the date a fix was released, the date the finding appeared in your gate, the date the fix merged, and any exception in between with its expiry. A Block policy on criticals past your window, plus exceptions that expire inside it, produces that record as a by-product.
Does the FTC Safeguards Rule apply to fintech CI pipelines?
For non-bank financial institutions under FTC jurisdiction, 16 CFR 314.4 requires secure development practices for in-house applications, change management procedures and continuous monitoring or periodic testing. It does not name CI gates, but gate history and exception records are reasonable evidence for those clauses. Confirm applicability with counsel.
The policy gate stops a vulnerable version from shipping; it does not make the fix exist. The section below covers what Safeguard offers when the fix is slow to arrive or has to come from somewhere other than upstream.
Fix it without waiting for upstream
Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.
1. Autonomous remediation: pull requests, not tickets
When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation categories include dependencies, licenses, security posture and findings, and each one is set separately. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.
2. Gold Open Source: the safe version in seconds, free
gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds.
3. Gold Registry: start from components that are already fixed
Gold Registry provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs and a completed license check, with signed build provenance (signed with Safeguard's key and verifiable with cosign, SLSA Build Level 3 as the design target) and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.
When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. Ask which packages it covers before you plan around it.
| Your situation | What to use |
|---|---|
| A fixed version exists | Autonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version |
| You need to know today whether you are affected | Gold Open Source lookup and "Am I affected?" checker, free and without login |
| You want vulnerable versions to stop shipping | Safeguard policies and gates in CI |
| Upstream has no fix yet, or will not ship one | A custom Gold request; fork and patch |
| You want to start clean on new projects | Pull hardened components and images from Gold Registry |
One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.
See how Safeguard would help
The local runner demo shows setting up the runner on your own machine, approving it with its device code, then scanning from the terminal. It is the closest match to running the CI scan with --local, where only results leave the machine.
Click through it at your own pace, or open it full screen.
The CLI demo is a real session: install, open the interactive terminal, ask it to fix the lodash CVE in a repository, and watch it read the finding and advisory, ask before any command that changes something, edit package.json, run the install and tests with approval, and push nothing. It is the developer side of a Block failure: the fix, made with a human approving each change.
Click through it at your own pace, or open it full screen.
The Claude demo shows connecting Claude to the Safeguard MCP server with OAuth and choosing which tools Claude can use. With policy outcomes on, the same connection is how an assistant can read gate and policy outcomes when someone asks why a build failed.
Click through it at your own pace, or open it full screen.
Quick check
A Warn policy fails and every other policy on the gate passes. Does a CI job that checks the gate fail?
No. The gate's outcome is Warning, which passes, and the CLI exits 0 while printing the warning. Only a failed Block policy, an Error or a Not evaluated gate makes the job exit non-zero.
Where should approval for letting a failing build through live: in the gate or in an exception?
In an exception. Gate actions are Block, Warn and Notify. An exception carries the policy and finding, a business justification, an approver, an expiry date and an audit record, which is the evidence an assessor will ask for.
Related reading
- PCI DSS 4 software security evidence flow
- PCI DSS software composition analysis requirements for payment processors
- How to set up a CI/CD pipeline security gate
- PR-time policy gates that developers accept
- SBOM automation in CI/CD pipelines
- CI/CD pipeline audit logging
Sources
- PCI SSC: PCI DSS v4.0 SAQ D for Merchants (requirement text for 6.2, 6.3 and 6.5)
- PCI SSC blog: Just Published, PCI DSS v4.0.1
- PCI SSC blog: Now is the time to adopt the future-dated requirements of PCI DSS v4.x
- eCFR: 16 CFR 314.4, elements of an information security program
- NIST SP 800-218, Secure Software Development Framework v1.1
- NIST SP 800-218 full text (PDF)
- NIST SP 800-204D, software supply chain security in DevSecOps CI/CD pipelines
- OWASP Top 10 CI/CD Security Risks
- OWASP CICD-SEC-1: Insufficient Flow Control Mechanisms
- CISA Known Exploited Vulnerabilities Catalog
- FIRST: Exploit Prediction Scoring System
- GitHub Docs: About protected branches
- GitHub Docs: About rulesets
- GitHub Docs: Security hardening for GitHub Actions
- Safeguard docs: Policies and Gates
- Safeguard docs: Policy outcomes and actions
- Safeguard docs: CI/CD Integration
- Safeguard docs: GitHub Actions
- Safeguard docs: Guardrails and Enforcement
- Safeguard docs: PCI DSS 4.0 framework
- Safeguard: Guardrails and Enforcement use case
To try the workflow, download Safeguard or start with the documentation.
Last reviewed: 25 October 2026. Product capabilities change; check docs.safeguard.sh for the current state.