To scan a Perforce Helix Core server for vulnerable dependencies, give the scanner its own Perforce user with read access only on the paths you care about, pin the server's ssl: fingerprint, and scan each depot path or stream at its newest submitted changelist. Rescan whenever a new changelist lands, by polling or by a change-commit trigger that never blocks a submit.
Most dependency scanning advice assumes Git: a clone URL, a token with a scope, a webhook on push. A Perforce shop has none of those. It has depots and streams, changelists instead of commits, workspaces instead of clones, a protections table instead of token scopes, and tickets that expire after a group timeout. This post is written for the platform or build engineer who owns that server and has been asked to get it into the same vulnerability and SBOM process as the Git repositories. The first two thirds work with any scanner. The last third shows how Safeguard's Perforce (Helix Core) integration does it, using only what Safeguard's docs say today.
Key takeaways
- Treat the scanner as a Perforce user like any other. One dedicated user,
readon the paths you scan, nothing more. Perforce has no token scopes; the protections table is the whole permission model. - Scan a path or stream at a specific changelist, and record that changelist number as the scan's "commit". That number is what lets you reproduce, diff and audit a result later.
- Use
ssl:and pin the fingerprint you checked with your administrator. Never accept whatever key the server presents. - Choose your change detection on purpose. Polling needs no server changes. A change-commit trigger is faster but needs a super user, a script on the server and a credential file you must protect.
- Keep fixes reviewable. A patch you download, or a shelved fix in a pending changelist a human submits, keeps the scanner out of the submit path.
- Safeguard's Perforce (Helix Core) integration is GA. It produces an SBOM (GA) and findings through software composition analysis (GA), rescans on new changelists through polling or a trigger (continuous scanning, GA), and feeds the same policies and gates (GA, actions Block, Warn and Notify, with approval through exceptions) and notifications as every other source. Fix delivery is a patch, or a shelved changelist if you allow it. Safeguard never submits a changelist.
- Safeguard can also run on premises (GA) for servers that only live on a private network.
The situation
The ask usually arrives the same way. Security has a dashboard that covers every Git repository in the company. Somebody notices that the game engine, the firmware tree or the chip design flow lives in Perforce, and that none of it appears. The question lands on the platform team: can we get the Perforce side into the same view by the end of the quarter, without opening the server up?
The people asking care about three things. Security wants an SBOM and a list of known vulnerable components for every product, including the ones built from Perforce. Compliance wants evidence that the source of record is scanned on a schedule and that results trace back to an exact revision. Engineering wants none of this to slow down a submit, break a build at 2 a.m., or burn the handful of workspaces an unlicensed server allows.
The platform engineer cares about different things. Who gets a super user? What lands in the triggers table? What happens when the ticket expires on a Saturday and every scan starts failing? What does the scanner write back to the depot, if anything? How big is the sync, and does it run on the server's disks?
A bad week looks like this. A scanner is wired up with a personal account that has write on //.... It syncs the whole depot, textures and all, into a workspace on a build agent. It runs p4 trust -y because the first connection failed. Its ticket was created without -a, so it only works from the laptop that made it, and the job silently fails on the build agent. Nobody notices until an auditor asks for the last scan of the release branch, and the answer is "three weeks ago, on someone's laptop". Everything in this post is about avoiding that week.
Why Perforce is different from Git for a scanner
Before choosing settings, it helps to be precise about what a scanner sees on a Perforce server. Perforce now brands the product as P4; its documentation carries the banner "Helix Core is now P4", and the current command reference is labelled 2026.1. The concepts below are unchanged by the rename. For background on where Perforce sits among version control systems, see our version control market share data, and for a reminder that the client tools carry their own CVEs, see CVE-2024-0325 in Perforce Helix sync.
Depots, paths and streams
A Perforce server holds one or more depots. Files are addressed by depot paths such as //depot/main/..., where ... means "everything below here". A classic depot is just a tree of paths, and teams invent their own branch layout inside it. A stream depot adds structure: Perforce describes streams as hierarchical branches, each with a parent and a type, plus rules that control how change flows between them. To a scanner, both reduce to the same thing. You pick a path (or a stream's path), you sync files under it at some revision, and you scan what arrived.
The difference that matters is scope. In Git, a repository is usually one product, with its manifests at the root. In Perforce it is common for one depot to hold many products, with package.json, pom.xml, requirements.txt, go.mod or vendored libraries scattered across folders. Choosing what to scan is a design decision, not a default.
Changelists, not commits
Perforce records history as numbered changelists. A submitted changelist has a number that only goes up, a user, a date and a list of files. The newest submitted changelist under a path is the natural "revision" for a scan: p4 changes -m1 -s submitted //depot/main/... returns it. If you record that number with every scan, any finding can be traced back to the exact state of the code that produced it.
Pending changelists are different. They hold files that are opened but not yet submitted. A shelved changelist is a pending changelist whose file contents have been copied to the server so someone else can see them. That makes shelving the natural way for a tool to propose a change without submitting it.
Workspaces
A Perforce workspace (also called a client) maps depot paths to a local directory. You cannot sync without one. Workspaces are server objects, so a scanner that creates a workspace per scan leaves records behind unless it cleans up. On a server without a license, the number of workspaces allowed is small, so a scanner that leaks workspaces can block real users.
The protections table
Perforce has no tokens with scopes. Access comes from the protections table, edited with p4 protect by a user with super access. Perforce's reference describes the access levels in order. list lets a user see metadata but not file contents. read adds commands that read file data, such as p4 print, p4 diff and p4 sync. open lets a user open files for edit and shelve them. write adds submitting. admin and super are for administrators. Lines can grant access to a user or a group, can be limited by IP address, and can deny a right with an = prefix in an exclusionary mapping. Perforce recommends granting to groups where you can.
One warning from the same reference is worth repeating to anyone standing up a new server: a fresh installation lets anyone connect and treats every user as a superuser until someone runs p4 protect. If your scanner is the first thing to touch a test server, check that the protections table exists before you rely on it.
Tickets and timeouts
p4 login creates a ticket that represents a session. By Perforce's reference, tickets are valid for 12 hours by default, and the timeout can be set per group. p4 login -p prints the ticket instead of storing it locally, and -a makes it valid on all client machines and across connected servers such as replicas and edges. A ticket printed without -a is tied to the host that created it, which is why tickets copied from a laptop so often fail on a build agent.
ssl: and trust
A Perforce server can listen in plain text (perforce.example.com:1666) or with SSL (ssl:perforce.example.com:1666). Many servers use a self-signed key. The client keeps the fingerprints it trusts in a P4TRUST file and manages them with p4 trust. p4 trust -l lists known fingerprints, -i installs a specific one, and -y accepts any prompt automatically. Perforce's reference notes that since 2021.2, a server whose certificate chain can be verified against the client's trusted certificate authorities does not need a P4TRUST entry. For self-signed keys the fingerprint is the only thing standing between you and a server impersonating yours.
Triggers
Triggers are scripts the server runs on events. The triggers table is edited with p4 triggers, which needs super. If a trigger script exits with 0 the operation continues, and any other value makes it fail. A change-commit trigger fires after the changelist is created, its files are transferred and it is committed to the database, so the files are already submitted when it runs. Perforce's administration guide also notes that metadata-only replicas do not support change-commit triggers.
What the standards ask for
None of the frameworks below mention Perforce. They do describe what a source of record and its scanning process should look like, and they are what an auditor will hold the Perforce side to once the Git side is covered. This is general orientation, not legal or audit advice.
NIST SP 800-218, the Secure Software Development Framework (SSDF). Three groups of practices map directly onto a Perforce scanning setup. PS.1 asks organisations to protect all forms of code from unauthorised access and tampering, with least privilege as the basis for access. A scanner account with write on the whole depot works against that. PS.3 asks organisations to archive and protect each release and to collect and maintain provenance data, with an SBOM as the usual form, for the components of each release. That is the SBOM, tied to a changelist. RV.1 asks organisations to identify and confirm vulnerabilities on an ongoing basis, including monitoring the components they use for new vulnerabilities. That is the rescan on every changelist and on every new advisory.
CISA's SBOM work. CISA's SBOM page is the current home for its SBOM guidance, including its 2026 minimum elements, which replaced the NTIA 2021 minimum elements as the baseline people cite. The practical point for Perforce is that an SBOM is only useful if you can say which build or revision it describes. A changelist number gives you that. Our guides to the NIST SSDF in practice and SBOM automation in CI/CD pipelines cover the wider programme.
Least privilege, in general. Every control framework you are likely to be audited against has some form of "accounts get only the access they need". For Perforce that becomes one sentence: the scanner's line in the protections table says read, names one user or group, and names only the paths you scan.
Step by step, with or without Safeguard
These steps work with any scanner that can run against a synced Perforce path. Commands are standard p4 commands from Perforce's reference. Run them against a test server first. None of the commands below were run for this post.
1. Inventory what lives on the server
Start with a list, because you cannot scope a scan you have not seen.
p4 depots
p4 streams
p4 dirs //depot/*
For each depot or stream, write down what product it holds, who owns it, where the dependency manifests sit, and roughly how large it is. p4 sizes -s //depot/main/... gives a total size for a path, which tells you early whether a full sync is reasonable.
2. Decide scan scope per product, not per depot
The right unit of scanning is usually one product's folder, at the level where its manifests and vendored libraries live. Scanning //depot/... as one blob gives you one SBOM for many products, which nobody can act on. Scanning every leaf folder gives you many tiny projects with no owner.
A simple decision table helps.
| Layout you have | Scan unit to choose | Why |
|---|---|---|
| Stream depot, one product per stream | Each stream you release from | The stream is already the product boundary |
| Classic depot, one product per top-level folder | Each top-level folder under main | Matches ownership and release |
| Monorepo depot with shared third-party folder | Each product folder, plus the shared folder on its own | Shared libraries get one owner and one SBOM |
| Huge asset folders next to code | Only the code folders | Binary assets rarely hold package manifests and cost the most to sync |
| Release branches you still patch | Each supported release branch | Customers run those, not main |
3. Create a dedicated user and give it read only
A dedicated user makes the scanner visible in logs, easy to rotate and easy to remove. As a super user:
p4 user -f safeguard
p4 passwd safeguard
Then add a line to the protections table with p4 protect. A minimal line looks like this:
read user safeguard * //depot/main/...
The * is the host field, meaning any IP address. If your scanner always connects from known addresses, you can put them there instead and narrow the account further. Repeat the line for each path you scan. Do not give open unless you want the scanner to shelve fixes, and never give write, admin or super.
If you prefer groups, create a group for scanners and put the line on the group. That also gives you one place to set the ticket timeout.
4. Choose password or ticket, and plan for expiry
A password works until someone changes it or a password policy expires it. A ticket avoids handing the scanner a password, but it expires after the group timeout, 12 hours by default.
| Option | Good for | Watch out for |
|---|---|---|
| Password of a dedicated user | Long-running scanning with predictable rotation | Store it encrypted; rotate on a schedule |
Ticket from p4 login -a -p | Teams that will not hand a password to a tool | Expires after the group timeout; set a longer timeout on a scanner group or plan to paste new tickets |
Ticket from p4 login -p without -a | Nothing, for a scanner | Tied to the host that created it |
| Your personal password | Short tests only | Far broader than needed; leaves with you |
Create a ticket that works from anywhere with:
p4 -u safeguard login -a -p
5. Use ssl: and pin the fingerprint
Get the fingerprint from a machine that already trusts the server, or ask the administrator to read it from the server itself.
p4 -p ssl:perforce.example.com:1666 trust -l
When a scanner first connects, compare the fingerprint it reports with that value, character by character. Install it explicitly with p4 trust -i followed by the fingerprint. Do not script p4 trust -y. If the fingerprint ever changes, treat it as an event: confirm with the administrator that the key was replaced on purpose before you accept the new one.
6. Test the account before you wire anything up
Two commands prove the account works for scanning:
p4 -p ssl:perforce.example.com:1666 -u safeguard login
p4 -p ssl:perforce.example.com:1666 -u safeguard changes -m1 //depot/main/...
The first proves the credentials. The second proves read on the path and returns the changelist your first scan will use.
7. Choose how changes are detected
| Method | Server changes needed | Delay after a submit | Risk |
|---|---|---|---|
Polling p4 changes -m1 -s submitted on a schedule | None | Up to one polling interval | Very low; one cheap command per path |
change-commit trigger | A super user adds a triggers line; a script and credential file on the server | Seconds to minutes | A badly written trigger can slow or fail submits if it does not exit 0 |
| Scheduled rescans only | None | Up to the schedule | New vulnerabilities in old code still need feed-driven rescoring |
Polling is the safe default. A trigger is worth it when the team wants findings on the same afternoon as the change. If you use a trigger, make sure the script exits 0 whatever happens, because Perforce fails the operation on any other exit code. A change-commit trigger runs after the submit is already committed, so even a failing script will not undo a submit, but it should still never get in the way.
8. Sync into a throwaway workspace, scan, delete
For each scan: create a workspace that maps only the scanned path, sync it at the changelist you recorded, run the scanner, keep the SBOM and findings, then delete the workspace and the files. This keeps the workspace count flat, keeps no copy of the source on disk, and means each scan describes exactly one changelist.
9. Route results to owners
A finding with no owner is noise. Map each scanned path to the team that owns it, and send new or escalated findings to that team's channel or tracker. Use the changelist user and the path owner, not the scanner account, as the person to notify.
10. Keep fixes out of the submit path
The scanner should never submit. Either hand the developer a patch, or shelve the change in a pending changelist the developer can review, test and submit. Both keep a human between a proposed fix and the depot.
A checklist you can use today
- One dedicated user or scanner group exists, with a password or an
-aticket. - The protections table gives it
readon named paths only, andopenonly where shelved fixes are wanted. - The server is reached over
ssl:, and the fingerprint was confirmed out of band and pinned. - Every scan records the changelist number it scanned.
- Change detection is chosen: polling, a trigger, or both.
- Workspaces are temporary and deleted after each scan.
- Each scanned path has an owner who receives its findings.
- Fixes arrive as patches or shelves, never as submits.
- There is a rotation date for the password or ticket, and a written disconnect procedure.
Common questions engineers ask before they connect
Should I scan the whole depot or individual folders?
Individual folders, in almost every case. Pick the folder where a product's manifests live. A whole depot scan merges products that have different owners, release dates and risk tolerance. It also syncs far more data than the scan needs. If you are not sure where manifests live, a first pass of p4 dirs on each depot, followed by a conversation with each team lead, is faster than trying to scan everything and sorting it out afterwards.
How do streams change the setup?
Very little. A stream has a depot path like any other, and you can list streams with p4 streams. The protections line names the stream's path. The one decision streams force is which streams to scan. Mainline and every release stream you still patch are the usual answer. Short-lived task streams are usually not worth scanning on their own, because their changes reach the mainline when they are merged.
What about big binary assets?
Large binary trees are the most common reason a Perforce scan fails or takes too long. They rarely contain package manifests, and syncing them costs disk and network. Scope scans to code folders. If a product folder mixes code and assets, ask the owning team whether a code-only subfolder exists, or use the size check in step 1 to find out before the first scan.
Does any of this need super access?
Two steps do, once each. Creating the user and editing the protections table needs super, and so does adding a line to the triggers table. The scanner's own account never needs super, admin or write.
How Safeguard does this
Safeguard's Perforce (Helix Core) integration is GA. Everything below comes from Safeguard's Perforce integration page and related docs. Where the docs do not show a screen or command, this section describes the result instead of inventing one. The docs say the integration is switched on per workspace, so if the Perforce card is not visible under Integrations, ask your Safeguard contact to turn it on.
What the integration does
The Perforce card connects Safeguard to a Helix Core server (p4d). You add depot paths or streams, or leave the list empty so Safeguard lists every depot and stream the account can read. For each one, you pick the whole path or one of its top-level folders. Safeguard then syncs only that path, at the newest submitted changelist, into a temporary workspace. It scans the files for an SBOM (SBOM generation and analysis, GA) and findings (software composition analysis, GA), records the changelist number as the scan's commit, and deletes the temporary workspace when the scan ends.
The connection is always private
Perforce has only a private connection in Safeguard. Every Helix Core command runs as a user, so Safeguard always needs a user name with a password or a ticket. What you enter is the server address (P4PORT), optional depot paths or streams, a user name, and a password or ticket. What you can scan is exactly the set of paths that user can read in the protections table.
Sign-in methods
The docs describe two ways to sign in, and two ways to reach the server.
| Method | Use it when | What the docs say |
|---|---|---|
| User name and password | The server uses its own passwords or an auth-check trigger, LDAP for example | Safeguard gives the password to p4 login on standard input for each session; it never goes on a command line |
| User name and ticket | You do not want Safeguard to hold a password | Create it with p4 login -a -p. When the group timeout expires the ticket, scans fail until you paste a new one |
Plain host:1666 | The server listens without SSL | Files and commands cross the network unencrypted; the docs say to prefer ssl: |
ssl:host:1666 | The server listens with SSL | Recommended. The key is trusted only after you confirm its fingerprint |
On fingerprints, the docs are specific. Safeguard shows the fingerprint the server presented. You compare it with the one your administrator gets from p4 -p ssl:host:1666 trust -l, or from p4d -Gf on the server, and tick the box. Safeguard then trusts exactly that key, the equivalent of p4 trust -i with that fingerprint, never trust -y.
The docs also list what does not work. A ticket from p4 login -p without -a works only from the machine that made it, so Safeguard cannot use it. Client TLS certificates are not available as a sign-in method; use a password or ticket.
Permissions Safeguard needs
Safeguard only reads, unless you turn on shelved fixes. The docs map each access level to the commands Safeguard runs.
| Access in the protections table | Required? | What Safeguard uses it for |
|---|---|---|
list on the server | Required | p4 depots and p4 streams for listing, p4 dirs for folders, p4 labels for labels, and creating the temporary workspace for each scan |
read on each scanned path | Required | p4 changes -m1 for the newest changelist, p4 sizes -s for the size limit, p4 sync for scans, p4 print for files a fix changes |
open on each scanned path | Optional | Shelved fixes: p4 edit, p4 add and p4 shelve in a pending changelist |
write | Never | Safeguard never submits |
The least privilege line the docs suggest is the one from step 3:
read user safeguard * //depot/main/...
list on the server comes with read. The docs list what Safeguard never needs: write, admin, super or owner access, p4 protect or p4 triggers access for the connection's user, submitting changelists, or any depot you do not add.
Step by step setup in Safeguard
The docs split setup into the server side and the Safeguard side. On the server, as a super user:
- Create the user with
p4 user -f safeguard, then set its password withp4 passwd safeguard. - Add a
readline for the paths you scan withp4 protect, for exampleread user safeguard * //depot/main/.... Addopenlines only for shelved fixes. - For a ticket instead of a password, run
p4 -u safeguard login -a -pas that user and copy the ticket it prints. - For an
ssl:server, get the fingerprint withp4 -p ssl:perforce.example.com:1666 trust -lfrom a machine that already trusts it.
You can check the account with the two commands from step 6 above, which are the same ones the docs show:
p4 -p ssl:perforce.example.com:1666 -u safeguard login
p4 -p ssl:perforce.example.com:1666 -u safeguard changes -m1 //depot/main/...
Then, in Safeguard:
- Open Integrations and choose the Project/Product tab.
- Click Connect on the Perforce (Helix Core) card.
- Enter a Name and the Server (P4PORT), for example
ssl:perforce.example.com:1666. - Put one depot path or stream per line in Depot paths or streams, or leave it empty to list everything the user can read.
- Choose Sign in with: User name and password, or User name and ticket.
- Choose how often to Check for new commits, and how to Deliver fixes as: a patch, or shelved in a pending changelist (which needs
openaccess). - Click Check access. If the server's
ssl:key is not trusted yet, compare the fingerprint shown, tick This is my server's certificate, and the check runs again. - Click Next, pick each path's folder, and connect with the scan depth you want.
Each path you select is scanned once when you connect.
Change detection: polling, trigger or schedule
The docs offer the same three options as the table in step 7.
Polling is the default. Safeguard checks the newest submitted changelist of each scanned path with p4 changes -m1 -s submitted, and rescans when it changed. The docs give a default of every 15 minutes, adjustable from 5 minutes to 24 hours, or off.
A change-commit trigger is set up from the connection's edit dialog under Scan on commit, then Set up commit hook. Safeguard gives you a trigger script and a credential file, safeguard-hook.conf. You save both on the server, for example in /p4/common/safeguard/, make the script executable, and keep the credential file readable only by the user p4d runs as (chmod 600). A super user then adds a line to the triggers table with the path you scan:
safeguard change-commit //depot/main/... "/p4/common/safeguard/safeguard-change-commit.sh %change% %user% %serverport%"
The server needs curl, and the trigger needs to be able to run p4 describe. After each submit, the trigger sends the changelist number, its user and the changed depot files to Safeguard's hook endpoint for that connection, authenticated with the credential. Safeguard then rescans the projects whose path the changelist touched. The credential is shown once. Issue a new hook credential rotates it, and Revoke stops deliveries. The docs state plainly that the trigger never blocks or changes a submit.
Schedules are the third option: you can rescan on a schedule from Integrations, then Scheduled.
Beyond changes in the depot, Safeguard's continuous scanning (GA) re-evaluates assets in its inventory when vulnerability feeds change, so a component scanned last month can pick up a new finding when a new advisory affects it, without a new changelist.
What Safeguard reads and stores
This is the section a Perforce administrator will read twice, so here it is as the docs state it.
- Read: the files under each scanned path at the scanned changelist, and the changelist's number, user and date. For a fix, the original content of the files it changes.
- Stored: the SBOM, findings and project metadata, with the changelist number as the scan's commit. For fixes, the patch and the files it changes. The password or ticket is encrypted at rest and never shown again after you save it. Non-secret settings (server, pinned fingerprint, polling, fix delivery) are stored with the connection.
- Not stored: the synced files and the temporary workspace, which are deleted when the scan ends. Each session uses private ticket, trust and environment files that are removed afterwards, and reads no P4CONFIG file.
The docs also state that no customer data from this integration is sent to third-party LLMs.
Findings, policies and notifications
Once a Perforce path is connected, its SBOM and findings sit alongside every other source in Safeguard. That means the same tools apply.
- Policies and gates (GA). Policies turn scan results into findings that matter to you, such as known exploited vulnerabilities in a release stream or a license outside your allow list (license compliance, GA). Gates enforce them at checkpoints with three actions: Block, Warn and Notify. When a team needs to ship despite a blocking finding, approval goes through a time-boxed exception granted by an approver with the right role, and exceptions appear in the audit log and expire automatically.
- Notifications. New or escalated findings route by owner, severity and exploitation status to channels and trackers configured under notifications, such as Slack, Microsoft Teams or Jira (notifications and ticketing integrations, GA).
Two points are specific to Perforce. First, because the trigger never blocks a submit, gates act on the scan of a changelist that is already in the depot. They tell you, and the release process, that the path is not shippable; they do not stop the submit. Second, the "commit" on every finding is a changelist number, so a gate decision can always be traced to an exact state of the path.
Fixes: a patch, or a shelf you submit
Fixes for Perforce work differently from the pull requests Safeguard opens on Git hosts. The docs say fixes arrive as a patch you download and apply. If you give the connection open access on a path and choose shelved delivery, Safeguard can also shelve a fix in a pending changelist for you to review and submit. Safeguard never submits a changelist.
A shelved fix keeps its workspace, named with an sg-fix- prefix, so you can see the shelf. Delete it with p4 client -d after you submit or discard the fix. The docs recommend that on an unlicensed Helix Core server, which allows only a few workspaces, you keep fixes as patches.
Autonomous remediation (GA) ships switched off, with every category set to Manual, so no fix is prepared on its own until your team chooses to allow it.
Size limits and private servers
Two limits shape what you connect. The first is a checkout size limit, 2 GB by default per the docs. If a path is larger, nothing is synced, and Safeguard reports the path's size and the limit; the fix is to scan a smaller path, such as one product's folder. That lines up with the scoping advice in step 2.
The second is network reach. Safeguard's hosted service never connects to an address that resolves to a private, loopback, link-local or metadata range. If your Perforce server is only reachable on a private network, the docs give two options: expose it on a public address with ssl: (and allow Safeguard's addresses through your firewall), or use Safeguard's on-premises deployment (GA), which runs the platform inside your own perimeter.
Troubleshooting, in plain words
The docs list the errors you are most likely to meet. In summary:
| You see | Usually means | Do this |
|---|---|---|
| The server refused the user name and password | Wrong password or unknown user | Check with p4 -u safeguard login, then save the right password |
| The server refused the ticket | It expired, or it was made without -a | Run p4 login -a -p again and paste the new ticket, or switch to a password |
| The user is not allowed to read that path | No read line covers it | Add read user safeguard * //your/path/... in p4 protect |
| The ssl: key is not trusted yet | First connection to an ssl: server | Compare the fingerprint and confirm it |
| The server presented a different ssl: key | The key changed since you pinned it | Check the new fingerprint with your administrator, then confirm it in the edit dialog |
| Could not reach the server | Wrong host or port, plain address for an ssl: server, or a firewall | Check P4PORT and allow Safeguard's addresses |
| Refused a new workspace because of the license limit | Unlicensed server at its workspace limit | Delete unused workspaces, including old sg-fix- ones |
| Refused the shelve | Shelved fixes on, but no open on the path | Add an open line, or switch fixes to patches |
Rotation and disconnect
To rotate, change the password with p4 passwd or create a new ticket, then open the connection's edit dialog, enter it, click Check access and save. To rotate the hook credential, click Issue a new hook credential and replace safeguard-hook.conf on the server.
To disconnect, delete the connection under Integrations. Then remove the user's lines from p4 protect (or delete the user with p4 user -d -f safeguard), remove the safeguard line from p4 triggers and its two files, and delete any sg-fix- workspaces and shelves you do not need.
How the pieces map to the standards
| Requirement | What Safeguard does | What you still own |
|---|---|---|
| SSDF PS.1, least privilege on code | Works with a read only user; open only if you choose shelved fixes; never needs write or super | Writing and reviewing the protections table; who holds super |
| SSDF PS.3, provenance and SBOM per release | SBOM per scanned path, with the changelist number as the commit | Deciding which paths and streams are releases; keeping release records |
| SSDF RV.1, ongoing vulnerability identification | Rescans on new changelists by polling or trigger, plus continuous scanning on feed changes | Triaging findings and deciding what ships |
| Credential handling | Password or ticket encrypted at rest; password passed on standard input; hook credential shown once and rotatable | Rotation dates; ticket timeouts; the hook credential file's permissions on the server |
| Transport security | ssl: with a fingerprint you confirm and pin | Confirming the fingerprint out of band; investigating any key change |
| Change control | Never submits; fixes as patch or shelf | Reviewing, testing and submitting fixes |
What Safeguard does not do
- It does not block submits. The change-commit trigger only reports a changelist to Safeguard. It never blocks or changes a submit, and gates act on scans of code that is already in the depot. If you need pre-submit enforcement, that is a server-side policy your team designs and owns.
- It does not submit changelists. Fixes arrive as patches or shelves. Someone on your team reviews, tests and submits them, and resolves any conflicts.
- It does not scan paths you do not grant or add. The scan covers what the connection's user can read and what you select. A product in a depot the user cannot read is invisible to it, and that is by design.
- It does not accept client TLS certificates or host-bound tickets. Use a password, or a ticket made with
-a. - It does not manage your ticket timeouts or password policy. If a ticket expires, scans fail with a clear error until someone pastes a new one. Setting a sensible group timeout is your job.
- It does not clean up shelved-fix workspaces for you. Workspaces with the
sg-fix-prefix stay until you delete them, which matters on servers with a workspace limit. - It does not replace your release decision. It tells you what is in a path and what is known about it. Whether a finding is acceptable for a given release stays a human decision, recorded as an exception if you make one.
Common mistakes
Using a personal account. It works on day one and becomes a problem the day that person changes role. It also carries far more access than a scanner needs. Create a dedicated user.
Granting write "just in case". Nothing in a read-only scanning flow needs it. If you want shelved fixes, open on the specific paths is enough.
Copying a ticket made without -a. It only works from the machine that created it. The symptom is a connection that tests fine on a laptop and fails everywhere else.
Accepting any fingerprint. p4 trust -y in a script quietly trusts whatever key answers. Confirm the fingerprint once, out of band, and pin it.
Scanning //.... One huge SBOM, one huge sync, no owner. Scope to product folders and streams.
Leaving workspaces behind. On an unlicensed server a few leaked workspaces can block developers. Make every scan workspace temporary, and clean up shelved-fix workspaces after each fix.
No rotation date. Put the password or ticket rotation in the same calendar as certificate renewals. Expired credentials are the most common cause of silent scan gaps.
FAQ
Can Safeguard scan Perforce Helix Core?
Yes. Safeguard's Perforce (Helix Core) integration is GA. It connects to a Helix Core server, syncs the depot paths or streams you choose at the newest submitted changelist into a temporary workspace, and scans them for an SBOM and findings. The integration is switched on per workspace; ask your Safeguard contact if you do not see the card.
Does Safeguard support Perforce streams?
Yes. You can add streams as well as depot paths, or leave the list empty to see every depot and stream the account can read. For each one you choose the whole path or one of its top-level folders.
What Perforce permissions does a scanner need?
For Safeguard, read on each scanned path, which includes list on the server. open is optional and only for shelved fixes. write, admin, super and owner are never needed.
Should I use a password or a ticket for Perforce scanning?
Either works. A password of a dedicated user is the simplest for long-running scans. A ticket from p4 login -a -p avoids handing over a password, but it expires after the user's group timeout, 12 hours by default in Perforce, and must then be replaced.
How quickly does Safeguard rescan after a Perforce submit?
With polling, within the polling interval you set, every 15 minutes by default per Safeguard's docs. With the change-commit trigger, Safeguard is told about the changelist right after the submit and rescans the projects whose path it touched.
Will the Safeguard trigger slow down or block submits?
Safeguard's docs say the trigger never blocks or changes a submit. It runs as a change-commit trigger, which Perforce fires after the changelist is already committed.
Can Safeguard fix vulnerabilities in a Perforce depot?
It can prepare the fix. You download it as a patch, or, if you grant open access and choose shelved delivery, Safeguard shelves it in a pending changelist. A person on your team reviews and submits it. Safeguard never submits.
My Perforce server is on a private network. Can I still use Safeguard?
The hosted service will not connect to private, loopback, link-local or metadata addresses. You can expose the server on a public ssl: address and allow Safeguard's addresses through your firewall, or run Safeguard on premises.
Perforce scanning tells you which components in a depot path carry known vulnerabilities, but finding them is only half the job. The section below covers what happens next, when a fixed version exists and when it does not, and it applies to the open source code you sync and build from Perforce just as it does to code in Git.
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 Safeguard CLI demo shows a real terminal session. You install the CLI, run safeguard to open the interactive terminal and ask it to "fix the lodash CVE in this repo". It reads the finding and the advisory, asks before any command that changes something, edits package.json to lodash 4.17.21, runs npm install and npm test with your approval, prints a summary and pushes nothing. The same habit applies to a patch Safeguard prepares for a Perforce path: you see the change, you approve it, and you submit it yourself.
Click through it at your own pace, or open it full screen.
The local runner demo shows how to set up the runner on your own machine, approve it with its device code, and scan from the terminal. It shows the terminal side of Safeguard; the Perforce connection itself is set up under Integrations in the app, as described above.
Click through it at your own pace, or open it full screen.
The Claude demo shows how to connect Claude to the Safeguard MCP server with OAuth and choose which tools Claude can use. Once a Perforce path is scanned, the same connection lets you ask about its findings in plain language.
Click through it at your own pace, or open it full screen.
Quick check
What is the smallest Perforce access Safeguard needs to scan a path?
read on each path you scan, for example read user safeguard * //depot/main/.... That includes list on the server. open is only needed for shelved fixes, and write is never needed.
Why does a ticket from p4 login -p fail in Safeguard when it worked on your laptop?
Without -a the ticket is valid only on the host that created it. Create it with p4 login -a -p so it is valid on all hosts, or switch to a password.
To try Safeguard, download the apps and CLI and read the docs, including the Perforce (Helix Core) integration guide.
Sources
- Safeguard docs: Perforce (Helix Core) integration
- Safeguard docs: Integrations
- Safeguard docs: Continuous Scanning
- Safeguard docs: Guardrails and Enforcement
- Safeguard docs: Air-Gapped Deployment
- Perforce: p4 protect
- Perforce: p4 login
- Perforce: p4 trust
- Perforce: p4 triggers
- Perforce: Change-commit triggers
- Perforce: p4 changes
- Perforce: p4 sync
- Perforce: p4 stream
- Perforce: p4 shelve
- NIST SP 800-218, Secure Software Development Framework (SSDF) Version 1.1
- NIST SP 800-218 full text (PDF)
- CISA: Software Bill of Materials (SBOM)
Last reviewed: 25 October 2026. Product capabilities change; check docs.safeguard.sh for the current state.