To scan a Subversion repository for vulnerable dependencies, give the scanner its own read-only account in the server's path-based authorization file, point it at the exact path you ship from (trunk, a release branch or a tag), and rescan whenever a new revision lands on that path. Because Subversion has no pull requests, fixes have to come back as a patch you apply with svn patch, or as a commit to a separate branch path that never touches trunk. Safeguard's Subversion integration works exactly that way: it exports the path you choose at its newest revision, builds an SBOM and findings from it, records the revision number as the scan's commit, and picks up new commits by polling or by a post-commit hook you install.
This guide is for the platform engineer or Subversion administrator who has been asked to bring the SVN estate into the same supply chain program as the Git repositories, and for the AppSec lead who owns the result. The first two thirds work with any scanner, or none: how Subversion's model changes what "scan the repo" means, how to set up least-privilege read access in authz, which paths to scan, and how to get fixes back in without a pull request. Then it shows the Safeguard flow step by step, as the Subversion integration docs describe it, and what Safeguard does not do.
Key takeaways
- Scan a path, not a repository. A Subversion repository can hold many projects, each with its own
trunk,branchesandtags. Decide which path you build releases from and scan that. - Read access is set by path in
authz, not by token scope. A dedicated account withron the scanned paths is enough for scanning. Nothing needs write access unless you want fixes delivered as a branch. - Revision numbers are global. One number identifies the whole repository state after a commit, so recording the revision with each scan gives you an exact, reproducible reference.
- Tags are a convention, not a lock. In Subversion a tag is a copy that anyone with write access to the tags path could change. Protect
tagsinauthzif you rely on tags as release records. - Externals can pull code from elsewhere. An
svn:externalsdefinition without a pinned revision follows whatever the other location holds today. Pin them, or know what you are scanning. - Safeguard Subversion integration (GA): connects public or private repositories over
https://,svn://orsvn+ssh://, exports the chosen path at its newest revision, and produces an SBOM (GA) and vulnerability findings (GA) for it. It is switched on per workspace. - New commits are picked up by polling (the default) or a post-commit hook, and you can also rescan on a schedule. The hook never blocks or changes a commit.
- Fixes arrive as a patch you apply with
svn patch, or, if you grant write access and choose it, as a commit to a new branch under a path you name. Safeguard never commits to trunk. Autonomous remediation (GA) ships switched off, with every category set to Manual. - Policies and gates (GA) apply to the scans Safeguard runs for connected repositories, with Block, Warn and Notify actions and approval handled through exceptions.
The situation
Plenty of software still ships from Subversion, often from an internal server that predates the organisation's Git hosting by years. The Apache Subversion project still ships long-term support releases; the 1.14 LTS release notes describe 1.14 as a superset of all previous Subversion releases.
The usual problem is not that SVN is insecure. It is that the supply chain program was built around a Git host. The SCA tool connects through an app installed on the Git organisation, the pull request bot opens pull requests, the dashboards count repositories by Git URL. Subversion has none of those hooks. So the SVN repositories end up as a line in a spreadsheet, scanned by hand once before an audit, or not at all.
A bad week looks like this. A widely used library gets a critical advisory, and the Git side has an answer by lunch. Someone asks about the product that builds from svn.example.com/repos/platform/trunk, and nobody knows. A developer greps the manifests and misses a module pulled in through svn:externals. The release branch customers run is a different path again, and the tag the last release was cut from has had a hotfix committed to it since.
None of that needs a new process. It needs the same three things the Git side already has: a reliable inventory of what each shipped path contains, a scan that reruns when that path changes, and a way to get fixes back into the repository that fits how Subversion works.
What the standards expect
No standard tells you which version control system to use, but the secure development frameworks do describe what should be true of the repository and of the components inside it. The clearest US reference is the NIST Secure Software Development Framework, SP 800-218. Read the practices themselves rather than a summary; the ones that bear on an SVN estate are these.
| SSDF practice | What it asks for, in short | What it means for an SVN repository |
|---|---|---|
| PS.1 (PS.1.1) | Protect all forms of code from unauthorized access and tampering, storing code with least-privilege access | Least-privilege authz, protected tags, accounts per purpose, a record of who committed what |
| PS.3 (PS.3.1, PS.3.2) | Archive and protect each software release, and collect and share provenance data for its components | Know which revision each release was built from, and keep an SBOM for it |
| PW.4 (PW.4.1, PW.4.4) | Reuse well-secured software, and verify acquired components, including checking them for publicly known vulnerabilities | Track third-party code that arrives through manifests, vendor branches and externals |
| RV.1 | Identify and confirm vulnerabilities on an ongoing basis | Rescan when the shipped path changes and when new advisories appear, not once a year |
Two points are worth drawing out. First, the SSDF treats repository access control and component tracking as parts of the same job, which suits Subversion well: its path-based authorization is fine grained enough to give a scanner read access to exactly the paths that ship. Second, "ongoing" matters. A scan that happened before the last audit says nothing about the revision your customers are running now.
Nothing here is legal or audit advice. If a contract, a federal attestation or a regulator is asking you about your development practices, the exact wording of that request decides what you have to show.
How Subversion's model changes what "scan the repo" means
Most scanning guides assume Git. Several Subversion behaviours change the answers, and getting them right first saves rework later. Everything in this section comes from the Apache Subversion documentation, chiefly the book Version Control with Subversion.
One repository, many projects
The Subversion book describes two common layouts. In one, each project gets its own repository with trunk, branches and tags at the root. In the other, a single repository holds many projects, each with its own trunk, branches and tags one level down. The book also notes that these directories are conventions; Subversion itself gives them no special meaning.
For scanning, that means "the repository" is rarely the right unit. If repos/platform holds a billing service, a reporting service and a shared library, each of those has its own release line. A scan of the repository root would mix them together, and in a large repository it may also be far larger than one product needs. Scan the path each product builds from.
Revision numbers cover the whole repository
Every commit in Subversion creates a new revision number for the entire repository tree, not for a single file or branch. The book's section on revision specifiers covers the keywords you will see (HEAD for the newest revision in the repository, BASE, COMMITTED and PREV for working copy states) and how to ask for a path as it was at a given revision.
This is useful for scanning. A path plus a revision number names exactly one tree, forever. If a scan records "/platform/billing/trunk at revision 48210", anyone can reproduce that tree with svn export -r 48210. The flip side is that the revision number increases on every commit anywhere in the repository, so a new HEAD does not mean the path you scan changed. A good trigger checks whether the scanned path itself changed.
Branches and tags are cheap copies
Subversion makes branches and tags with svn copy, which the book describes as a cheap server-side copy (using branches). A tag is the same thing as a branch, placed under tags by convention. The book's tags chapter is explicit that a tag stays a snapshot only as long as nobody commits to it. It offers administrators two approaches: a "hands off" project policy that tells people not to commit to tags, or a stricter one that uses Subversion's access control scripts so that nobody can do anything in the tags area except create new copies.
For supply chain work this matters twice. If your release records point at tags, a tag that can be changed is a weak record; the revision number is the strong one. And if you scan a tag to describe a release, check that nobody has committed to it since it was cut.
Externals bring in code from other places
An svn:externals property on a directory tells Subversion to fetch another repository location into the working copy when it checks out or exports that directory. The book's externals definitions section shows that a definition can name a specific revision, or none, in which case it follows the newest revision of the other location. svn export processes externals by default and has an option to skip them (svn export reference).
So two exports of the same path at the same revision can differ if an external is unpinned and the other location moved. That is a reproducibility problem for scanning and a supply chain problem in its own right: code is flowing into your build from somewhere that the path's revision number does not describe. The fix is the one the book recommends for stable builds: pin externals to explicit revisions on release branches and tags.
Vendored code and checked-in binaries
Subversion shops often store third-party code inside the repository, as a vendor branch or as files dropped into a lib or third_party folder. That is third-party code that may arrive without a manifest, and a scanner that reads manifests sees only what the manifests declare. Know where these folders are and keep them in your inventory.
Access is decided by the server, per path
Subversion has no personal access tokens with scopes. Who can read what is decided by the server's path-based authorization: an authz file with sections like [app:/trunk], where each line gives a user or @group r, rw or no access. Rules on a parent path are inherited by child paths, and a more specific path can override them. For svnserve the file is named by authz-db in svnserve.conf; for Apache with mod_dav_svn it is named by AuthzSVNAccessFile and enforced by mod_authz_svn.
How the account authenticates depends on how the server is reached, which the book covers in choosing a server configuration:
| Access method | Server side | How users authenticate |
|---|---|---|
https:// | Apache httpd with mod_dav_svn (httpd chapter) | Whatever Apache is configured for, often a password file named by AuthUserFile, or a directory service |
svn:// | The svnserve daemon (svnserve chapter) | The repository's own passwd file, or SASL |
svn+ssh:// | svnserve started in tunnel mode (svnserve -t) over an SSH login | SSH keys; authz still applies to the tunnel user |
Step by step: bring an SVN estate into the supply chain program
These steps work with any scanner. Do them before you connect anything, because most of the effort is knowing what to scan and giving the scanner the right access.
1. Inventory the repositories and the paths that ship
List every Subversion server and every repository on it. For each repository, list the projects inside it and the path each one builds releases from. Use a table like the one below. The rows are illustrative.
| Server URL | Repository | Project | Release path | Layout | Owner | Externals? | Vendored code? |
|---|---|---|---|---|---|---|---|
https://svn.example.com/repos/ | platform | billing | /billing/branches/release-4 | per project | Payments team | Yes, unpinned | third_party/ |
https://svn.example.com/repos/ | platform | reporting | /reporting/trunk | per project | Data team | No | No |
svn://build.example.com/ | firmware | controller | /trunk | standard at root | Devices team | Yes, pinned | vendor/ |
Ask each owner one question: "Which path, at which revision, did the last release come from?" If nobody can answer, that is the first finding.
2. Decide trunk, branch or tag for each project
Scanning trunk tells developers about what they are about to ship. Scanning the release branch tells you about what customers run. For many teams the answer is both: trunk so that problems are caught before a release is cut, and the release branch so that a new advisory against shipped code shows up quickly. Scan tags when you need a record of a specific release, and check that the tag has not been committed to since it was cut (svn log on the tag path will show any commits after the copy).
3. Create a dedicated read-only account
Create one account used only by the scanner. On svnserve, that is a line in the repository's conf/passwd. On Apache, it is an entry in the file named by AuthUserFile, for example with htpasswd. Then grant it read access in authz to exactly the paths it scans:
[app:/trunk]
safeguard = r
[app:/branches]
safeguard = r
This example is the one in Safeguard's docs. Read access to the repository root is optional; it only helps the scanner list branches and tags so you can pick a path instead of typing it. Write access is not needed for scanning at all.
If you connect over svn+ssh://, create a key pair for this purpose only and lock the key to the Subversion tunnel. The Subversion book's svnserve chapter shows the command= option in authorized_keys, which forces a key to run a single program, and the --tunnel-user option, which sets the user name Subversion sees. A typical entry looks like this (illustrative; the paths and key are yours):
command="svnserve -t -r /var/svn --tunnel-user=safeguard",no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty ssh-ed25519 AAAAC3Nza...KEY safeguard
With that entry, the key can do nothing but run svnserve in tunnel mode against the repositories under /var/svn, and authz still decides which paths it can read.
4. Protect tags and release branches while you are in authz
You are already editing the file, so decide how strict to be about tags. The Subversion book calls the strict approach usually unnecessary for day-to-day work, but when tags double as release records for an audit, a simple authz rule is cheap. An illustrative layout for one project:
[groups]
developers = dev1, dev2, dev3
release = rel1, rel2
[app:/]
@developers = r
@release = r
[app:/trunk]
@developers = rw
[app:/branches]
@developers = rw
[app:/tags]
@release = rw
@developers = r
Here developers can work on trunk and branches but cannot change a tag; only the release group can create tags. If you need tags to be immutable even for the release group, Subversion's own answer is a pre-commit hook that rejects changes to existing tag paths. Test any authz change on a copy before you deploy it; a typo can lock people out.
5. Check access from the command line first
Before you configure any tool, prove the account works from an ordinary machine:
svn info --username safeguard https://svn.example.com/repos/app/trunk
svn list --username safeguard https://svn.example.com/repos/app/branches
These two commands are the ones Safeguard's docs give. If svn info fails with an authorization error, the authz line is missing or on the wrong path. If svn list on branches fails but svn info on trunk works, the account has read access to trunk only, which is fine if trunk is all you scan.
If the server uses a self-signed or private-CA certificate, get its SHA-256 fingerprint from your administrator, or read it yourself:
openssl s_client -connect svn.example.com:443 </dev/null | openssl x509 -noout -fingerprint -sha256
Any tool that connects should show you the fingerprint it sees so you can compare the two before trusting it.
6. Pin externals on release paths
Run svn propget svn:externals -R on each release path and look for definitions without a revision. On release branches and tags, pin them to explicit revisions so that the path's revision number describes everything that goes into the build. On trunk, decide whether following the newest revision of another location is a deliberate choice. Either way, list the external locations in your inventory; they are third-party or shared code you depend on.
7. Choose how scans are triggered
There are three options, and they combine well.
- Polling. The scanner checks the scanned path's newest revision on an interval and rescans when it changed. Nothing is installed on the server.
- A post-commit hook. The server tells the scanner about each commit. Subversion runs the
post-commithook after the commit is complete, passing it the repository path and the new revision number (post-commit reference). The commit cannot be undone by the hook; its exit status does not change the outcome. - A schedule. A rescan at a fixed time catches new advisories against code that has not changed.
If you install a hook, remember the rule the book states in its hooks section: Subversion runs hook programs with an empty environment. A script that works from your shell can fail inside the hook because PATH is empty. Use absolute paths for every program the hook calls, including curl.
8. Decide how fixes come back
There are no pull requests in Subversion. A fix can come back in two shapes:
- A patch file that a developer applies to a working copy with
svn patch, reviews, builds, tests and commits in the usual way. The svn patch reference describes it as applying a unidiff patch to a working copy, and it has a--dry-runoption to show what would change first. - A branch created by a server-side copy of the scanned path, with the fix committed there. A developer reviews the branch and merges it. This needs write access for the scanner, so grant
rwonly on a dedicated branch path such asbranches/safeguard, never on trunk.
Patch delivery is the least-privilege option. Branch delivery is easier to review in some teams, because the change is already in the repository.
9. Write it down
Record, for each project: the scanned path, the trigger, the fix delivery choice, the account, where its credential is stored, and the rotation date. Subversion passwords and SSH keys do not expire on their own, so a scanner credential that nobody owns will still be working years after the person who created it has left.
A one-page checklist
| Check | Done when |
|---|---|
| Inventory | Every server, repository, project and release path is listed with an owner |
| Account | A dedicated scanner account exists, with r only on scanned paths |
| SSH (if used) | The key is passphrase-free, made for this connection only, and forced to svnserve -t |
| Tags | Developers cannot commit to tags |
| Externals | Externals on release paths are pinned to revisions |
| Certificates | The server fingerprint is known and recorded |
| Trigger | Polling, hook or schedule is chosen per path |
| Fixes | Patch or branch delivery is chosen; no write access to trunk |
| Rotation | The credential has an owner and a rotation date |
Which access method should the scanner use?
Use the one your server already offers people: a password over https:// for Apache with mod_dav_svn, a password over svn:// for an svnserve daemon, or an SSH key forced to svnserve -t for svn+ssh://. Never send a password over plain http://, and make the credential belong to the scanner, not to a person.
Polling or a post-commit hook?
Start with polling. It needs nothing on the server and catches every change to the scanned path, just a little later. Add a hook when the delay matters, for example on a release branch where you want findings before the build finishes. Keep polling or a schedule as a backstop either way, because a hook that fails quietly (an expired credential, a missing curl) looks the same as a hook that has nothing to report.
How Safeguard does this
Safeguard's Subversion integration (GA) is a card under Integrations, on the Project/Product tab. The docs note that the integration is switched on per workspace, so if you do not see the Subversion card, ask your Safeguard contact. Everything below follows the Subversion integration docs; the screens and fields are named as the docs name them. The commands in this post were not run against a live server for this article.
What the integration does
For each repository you connect, you choose the path to scan: trunk, a branch, a tag or a custom path. Safeguard exports that path at its newest revision, scans it to produce an SBOM (GA) and findings (GA), and records the revision number as the scan's commit. New commits are picked up by polling, which is the default, or by a post-commit hook you install. Because Subversion has no pull requests, fixes arrive as a patch you download and apply with svn patch. If you give the connection write access and choose it, Safeguard can instead commit a fix to a new branch under a path you name. It never commits to trunk.
1. Prepare the account on your server
Create a dedicated account as in step 3 above. The docs give the exact shapes: a line such as safeguard = followed by a long random password in the repository's conf/passwd for svnserve, or htpasswd /etc/apache2/svn.htpasswd safeguard for Apache, and r for the account on each scanned path in authz.
For SSH, the docs show creating a key with no passphrase and getting the server's host key line:
ssh-keygen -t ed25519 -N "" -f safeguard
ssh-keyscan -t ed25519 svn.example.com
Add the public key to the server account's authorized_keys. The docs' least-privilege advice is a dedicated key whose authorized_keys entry forces svnserve -t -r with your repositories root, with r access in authz. A key with a passphrase cannot be used, because scans run unattended. Client TLS certificates are not available as a sign-in method; use a user name and password, or SSH.
2. Open the Subversion card and choose Public or Private
- Open Integrations and choose the Project/Product tab.
- Click Connect on the Subversion (SVN) card.
- Choose Public or Private, enter a Name, and put one repository root URL per line in Repository URLs.
Public needs no credential, and the server must allow anonymous read; you can scan the paths anonymous users can read. Plain http:// is accepted only here. Private needs a Subversion account that can read the paths you scan.
3. Choose the sign-in method
For Private, choose Sign in with: User name and password, or SSH key (svn+ssh://) with the SSH private key and Server host key. The docs map these to servers like this:
| Method | Use it when | Note from the docs |
|---|---|---|
User name and password over https:// | Apache with mod_dav_svn, or a product built on it | The password is passed to the svn client on standard input, never on a command line |
User name and password over svn:// | The server runs svnserve | svnserve checks it with its own passwd file or SASL |
SSH key over svn+ssh:// | The server gives svnserve -t over SSH | Paste the server's host key line too; passphrase-protected keys are not accepted |
| None (Public tab) | Anonymous read is allowed | A password is never sent over plain http:// |
4. Describe the layout, the polling interval and fix delivery
- Choose the Repository layout: Standard (trunk, branches, tags), or Custom paths for the main line, branches and tags. Custom paths fit the "many projects in one repository" layout.
- Choose how often to Check for new commits.
- Choose how to Deliver fixes as: a patch, or a new branch, which needs write access and a Fix branch path. The docs reject trunk or the scanned path as the fix branch path and suggest something like
branches/safeguard.
5. Check access and confirm the certificate
Click Check access. If the server's certificate is self-signed or from a private CA, Safeguard shows the fingerprint the server presented. Compare it with the one your administrator gave you, tick This is my server's certificate, and the check runs again. From then on, Safeguard trusts exactly that certificate and nothing else. If the certificate is renewed later, the docs say scans will report that the server presented a different certificate from the pinned one, and you confirm the new fingerprint in the edit dialog after checking it with your administrator.
6. Pick paths and connect
Click Next, pick each repository's path, and connect with the scan depth you want. Each repository you select is scanned once on connect. If the account has read access to the repository root, Safeguard can list branches and tags so you can pick a branch or tag instead of typing the path.
7. Keep scans current: polling, the hook, schedules
- Polling (default). Safeguard checks each scanned path's newest revision on the interval you set and rescans when it changed. The docs give a default of every 15 minutes, adjustable from 5 minutes to 24 hours, or off.
- Post-commit hook. In the connection's edit dialog, Scan on commit then Set up commit hook gives you a post-commit script and a credential file,
safeguard-hook.conf. Save the script as the repository'shooks/post-commit(or call it from your existing hook) and make it executable. Save the credential file next to it, readable only by the usersvnserveor Apache runs as (chmod 600). The server needscurl. The hook sends the revision, its author, the changed folders and the repository UUID to Safeguard's hook endpoint for that connection, authenticated with the credential, and Safeguard rescans the projects whose path the commit touched. The credential is shown once; Issue a new hook credential rotates it and Revoke stops deliveries. The hook never blocks or changes a commit. - Schedules. You can also rescan on a schedule from Integrations then Scheduled.
If you already have a post-commit hook (for email notifications or a CI trigger, say), call Safeguard's script from it rather than replacing it. Keep the Subversion book's rule in mind: hooks run with an empty environment, so check that the script can find curl when the server runs it, not only when you run it by hand.
8. Review what the scan produced
Each scan produces an SBOM and findings for the exported path, with the revision number recorded as the commit. That gives you the record the SSDF's PS.3 asks for, tied to an exact tree: this path, at this revision, contained these components with these known vulnerabilities. Policies and gates (GA) apply to scans the platform runs for connected repositories, and each policy's action decides what a failed policy does to the gate: Block fails the gate, Warn passes it with a warning naming the policy, Notify passes it and sends a notification (policies and gates docs). When a finding has a legitimate reason to stay, a developer requests an exception with a business justification and an expiry date, and approvers grant or deny it.
9. Apply fixes with svn patch, or review the fix branch
With patch delivery, download the patch and apply it to a clean working copy of the scanned path. A dry run first shows what would change:
svn checkout https://svn.example.com/repos/app/trunk app-trunk
cd app-trunk
svn patch --dry-run ../safeguard-fix.patch
svn patch ../safeguard-fix.patch
svn diff
The file name here is illustrative. Build and test, then commit with a message that names the finding. With branch delivery, Safeguard makes a server-side svn copy of the scanned path to the fix branch path you set and commits the fix there; you review the branch and merge it the way you merge any branch. In both cases autonomous remediation (GA) ships switched off, with every category set to Manual, so nothing is generated or delivered on its own until your team turns it on.
What Safeguard reads and stores
The docs are specific, which helps when your security team asks:
| What the docs say | |
|---|---|
| Read | The files under each scanned path at the scanned revision, and the revision's number, author and date. For a fix, the original content of the files it changes. |
| Stored | The SBOM, findings and project metadata; the revision number as the scan's commit; for fixes, the patch and the files it changes. The password or SSH key is encrypted at rest and never shown again after you save it. Non-secret settings (layout, pinned fingerprint, polling, fix delivery) are stored with the connection. |
| Not stored | The exported source tree, which is deleted when the scan ends, and any working copy or Subversion auth cache; each run uses a private configuration directory that is removed afterwards. |
| Third parties | The docs state that no customer data from this integration is sent to third-party LLMs. |
The docs also list what Safeguard never needs: write access to trunk or the paths you scan, svnadmin or hook-script access, server configuration, or any repository you do not add.
When something goes wrong
The troubleshooting table in the docs maps each error message to a cause. The common ones, in short:
| Symptom | Likely cause | What to do |
|---|---|---|
| The server refused the user name and password, or the key | Wrong password, unknown user, or a key the server does not accept | Test with svn info and the same user, then save the right credential |
| The user is not allowed to read that path | No r for the account on that path in authz | Add the account with r on the path |
| The certificate is not from a trusted authority, or does not match | Self-signed or private-CA certificate | Compare and confirm the fingerprint |
| A different certificate from the pinned one | The certificate was renewed | Check the new fingerprint with your administrator, then confirm it |
| The SSH host key does not match | Wrong or changed host key line | Run ssh-keyscan -t ed25519 against the server and paste the line |
| The path or revision does not exist | A typo, or a branch that was deleted | Check with svn list and pick the path again |
| The repository cannot be reached | Wrong host or port, server down, or a firewall | Check the URL and allow Safeguard's addresses to reach the server |
Passwords are never sent over plain http:// | A private connection with an http:// URL | Use the server's https:// address |
| The key is protected by a passphrase | Encrypted key | Generate a key without a passphrase for this connection only |
| The address resolves to a private, loopback, link-local or metadata address | The server is only on a private network | Expose it on a public address with TLS, or use Safeguard's on-premise deployment (GA) |
| The selected path is larger than the limit for one scan | The path exceeds the checkout size limit (the docs give 2 GB as the default) | Scan a smaller path, such as one product's folder, or raise the limit on the connection |
| The fix branch path must not be trunk or the scanned path | Branch delivery pointed at trunk | Use a path under branches/ |
Rotation and disconnect
To rotate, change the password (or replace the key) on the server, open the connection's edit dialog, enter the new credential, click Check access and save. To rotate the hook credential, click Issue a new hook credential and replace safeguard-hook.conf on the server. Until the new credential is saved, scans fail with the authentication error.
To disconnect, delete the connection under Integrations, then clean up the server side yourself: remove the account or its authz lines, delete its SSH key from authorized_keys, and remove the Safeguard post-commit hook and safeguard-hook.conf. Safeguard has no access to your server configuration, so it cannot do that part for you.
Requirement, Safeguard, and what you still own
| Requirement | What Safeguard does | What you still own |
|---|---|---|
| Least-privilege access to code (SSDF PS.1) | Works with read-only access by path; never needs write to trunk, svnadmin or server configuration | Creating the account, writing authz, protecting tags, rotating credentials |
| Release records with component data (SSDF PS.3) | Produces an SBOM and findings per scan, recorded against the revision number | Deciding which paths and revisions are releases, and keeping your release records |
| Tracking acquired components (SSDF PW.4) | Scans the exported path at its newest revision | Pinning externals, knowing where vendored code and binaries live |
| Ongoing vulnerability identification (SSDF RV.1) | Rescans on polling, commit hook or schedule | Choosing triggers per path, watching for hooks that stop firing |
| Getting fixes in | Delivers a patch, or a commit on a separate branch path | Reviewing, building, testing, committing and releasing |
| Stopping releases with known problems | Gates with Block, Warn and Notify; exceptions with justification and expiry | Choosing policies, approving or denying exceptions |
What Safeguard does not do
- It does not manage your Subversion server. Safeguard never needs
svnadmin, hook-script access or server configuration, and it does not writeauthz, create accounts, install hooks or remove them when you disconnect. Those are your administrator's tasks. - It does not block commits. The post-commit hook runs after the commit is complete and never blocks or changes it. If you want Subversion to reject a commit, that is a
pre-commithook you write and own. - It does not commit to trunk or to the scanned path. Fixes come as a patch or as a commit on a separate branch path you name. Merging, building, testing and releasing are yours.
- It does not reach private-network servers from the hosted service. The docs say Safeguard never connects to an address that resolves to a private, loopback, link-local or metadata address. Expose the server on a public address with TLS, or use the on-premise deployment.
- It does not accept every credential type. SSH keys with a passphrase and client TLS certificates do not work; plain
http://is accepted only for public, anonymous connections. - It does not scan unlimited paths in one go. A single scan has a checkout size limit; large repositories are scanned path by path.
- It does not decide what your release paths are. Safeguard scans the path you choose at its newest revision. If your releases come from tags or older revisions, you choose those paths deliberately.
- It does not replace legal, audit or regulatory judgement. It gives you evidence; what that evidence has to show is decided by the contract, the framework or the regulator in front of you.
Common mistakes
- Scanning the repository root. It mixes projects, makes owners hard to find and can hit the size limit. Scan each project's release path.
- Using a personal account. It works, but it reads more than needed and breaks when the person leaves or changes their password. Make an account for the scanner.
- Granting
rw"to be safe". Scanning needsronly. Grantrwonly on a dedicated fix branch path, and only if you choose branch delivery. - Forgetting the empty hook environment. A hook that calls
curlwithout a path can work in testing and fail on the server. Use absolute paths and check the server's hook output. - Replacing an existing
post-commithook. Your email or CI trigger stops. Call the new script from the existing hook instead. - Leaving externals unpinned on release branches. The same path at the same revision can then export different code on different days.
- Treating tags as immutable without enforcing it. Protect
tagsinauthz, or a hotfix on a tag quietly changes a release record. - Trusting a certificate without comparing the fingerprint. The whole point of pinning is that a person checked it once against a known value.
- Not owning rotation. Subversion credentials do not expire. Put a date and an owner on every scanner credential.
FAQ
Can Safeguard scan a Subversion repository?
Yes. The Subversion integration (GA) connects public or private Subversion repositories over https://, svn:// or svn+ssh://, exports the path you choose at its newest revision, and produces an SBOM and findings for it. It is switched on per workspace; if the card is not visible, ask your Safeguard contact.
What permissions does a scanner need on an SVN server?
Read access (r) in the server's authz file on each path you scan. Read on the repository root is optional and only helps list branches and tags. Write access is needed only if you want fixes committed to a separate branch, and then only on that branch path.
Does Safeguard need SVN admin access?
No. The docs say Safeguard never needs svnadmin or hook-script access, server configuration, write access to trunk or the scanned paths, or any repository you do not add.
How do I scan only one project in a large SVN repository?
Pick that project's path (its trunk, a release branch or a tag) when you connect. Use Custom paths in the repository layout if your projects are one level down rather than at the root.
How does Safeguard know when an SVN repository changes?
By polling the scanned path's newest revision (the default), by a post-commit hook you install from the connection's edit dialog, or by a schedule. Polling rescans only when the scanned path changed.
Will the Safeguard post-commit hook slow down or block commits?
The docs state that the hook never blocks or changes a commit. Subversion itself runs post-commit after the commit is complete, so a hook's result cannot undo it.
How do I apply a Safeguard fix to an SVN working copy?
Download the patch and apply it with svn patch in a clean working copy of the scanned path. Run svn patch --dry-run first to see what would change, then build, test and commit.
Can I use a self-signed certificate on my SVN server?
Yes. Safeguard shows the fingerprint the server presented; you compare it with the one your administrator provides and confirm it, and Safeguard then trusts exactly that certificate. If the certificate is renewed, you confirm the new fingerprint.
Does Safeguard keep a copy of my SVN source code?
No. The docs say the exported source tree is deleted when the scan ends, and no working copy or Subversion auth cache is kept. Safeguard stores the SBOM, findings, project metadata and the revision number, plus patches and the files they change for fixes.
My SVN server is only on the internal network. Can Safeguard still scan it?
Not from the hosted service. The docs say Safeguard never connects to private, loopback, link-local or metadata addresses. Expose the server on a public address with TLS, or use Safeguard's on-premise deployment.
Finding a vulnerable library in a Subversion path is only half the job; the fix still has to reach the code you ship, and sometimes no fixed version exists yet. The section below covers Safeguard's options for both cases, and in an SVN estate any upgrade it produces still lands as a patch or a branch you review rather than a pull request.
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 first demo is a real CLI session: you install the CLI, open the interactive terminal with safeguard, and ask it to fix a lodash CVE in a repository. It reads the finding and the advisory, asks before any command that changes something, edits package.json, runs the install and the tests with your approval, prints a summary and pushes nothing. That last point is the same discipline this post recommends for Subversion: the change sits in your working copy until a person reviews and commits it.
Click through it at your own pace, or open it full screen.
The second demo connects Claude to the Safeguard MCP server with OAuth and shows how you choose which tools Claude can use. Once your SVN paths are connected as projects, the same connection is a way to read their findings from Claude, with you deciding which tools it may call.
Click through it at your own pace, or open it full screen.
Quick check
Your SVN scanner account needs to list branches so you can pick one in the setup dialog. What access does it need, and where?
Read access (r) on the repository root in the server's authz file, for example in an [app:/] section. Scanning itself only needs r on the paths you scan; root read is the optional extra that lets the dialog list branches and tags.
A post-commit hook that calls curl works when you run it by hand but never fires on the server. What is the most likely cause?
Subversion runs hook programs with an empty environment, so PATH is empty and a bare curl is not found. Call programs by absolute path in the hook, and check that curl is installed on the server, which Safeguard's hook needs.
Sources
- Safeguard docs: Subversion (SVN) integration
- Safeguard docs: Integrations overview
- Safeguard docs: Policies and gates
- NIST SP 800-218, Secure Software Development Framework and the full text (PDF)
- Version Control with Subversion: Path-Based Authorization
- Version Control with Subversion: svnserve, a custom server
- Version Control with Subversion: httpd, the Apache HTTP Server
- Version Control with Subversion: Choosing a server configuration
- Version Control with Subversion: Creating and configuring your repository (hooks)
- Version Control with Subversion: post-commit hook reference
- Version Control with Subversion: Planning your repository organization
- Version Control with Subversion: Using branches
- Version Control with Subversion: Tags
- Version Control with Subversion: Externals definitions
- Version Control with Subversion: Revision specifiers
- Version Control with Subversion: svn export
- Version Control with Subversion: svn patch
- Apache Subversion 1.14 LTS release notes
- Apache Subversion security advisories
Related reading: migrating from SVN to Git and keeping history, the Git and Subversion security models compared, version control market share in 2026 and CWE-527, an exposed version control repository.
Try it yourself: download Safeguard or read the Safeguard docs.
Last reviewed: 25 October 2026. Product capabilities change; check docs.safeguard.sh for the current state.