Mercurial (hg)
Connect Mercurial repositories on any server (hgweb, Heptapod, RhodeCode, SourceHut, hg serve) to Safeguard. The access each sign-in method needs, step-by-step setup, commit hooks and polling.
Availability
This integration is switched on per workspace. If you do not see the Mercurial card under Integrations, ask your Safeguard contact.
What it does
The Mercurial card connects Safeguard to one or more Mercurial repositories on your server. Mercurial is mostly self-hosted, so the card takes any repository URL your server serves, for example from hgweb, Heptapod, RhodeCode, SourceHut or hg serve. For each repository you choose the named branch, bookmark or tag to scan; Safeguard clones only the history of that revision, archives it, scans it for an SBOM and findings, and records the full changeset hash as the scan's commit. New changesets are picked up by polling (the default) or by a changegroup hook you install. Find the card under Integrations on the Project/Product tab.
Fixes arrive as a patch in hg export format that you apply with hg import. If you give the connection write access and choose it, Safeguard can also push a fix as a new named branch. It never pushes to an existing branch or moves a bookmark.
Public vs private
| Public | Private | |
|---|---|---|
| What you enter | One or more repository URLs | The repository URLs, and a user name with a password or token, or an SSH key |
| Credential needed | None (the server must allow anonymous read) | An account that can read the repositories |
| What you can scan | Repositories anonymous users can read | Repositories the account can read |
Supported auth methods
| Method | Use it when | Notes |
|---|---|---|
User name and password or access token over https:// | Your server serves Mercurial over HTTPS (hgweb behind a web server, Heptapod, RhodeCode, SourceHut) | Prefer a token where your server offers one. It is written to a private configuration file for each run, never to a command line |
SSH key over ssh:// | Your server gives Mercurial over SSH | You also paste the server's host key line; a key with a passphrase cannot be used |
| None (Public tab) | The repository allows anonymous read | http:// is accepted only here: a password is never sent over plain http:// |
A server with a self-signed or private-CA certificate works only after you confirm its fingerprint in the dialog. Safeguard then trusts exactly that certificate (Mercurial's [hostsecurity] fingerprint pinning) and nothing else.
Permissions required
Safeguard only reads, unless you turn on branch delivery for fixes. Mercurial has no token scopes of its own: access is whatever your server enforces, for hgweb the [web] allow_read and allow_push settings and your web server's authentication, and for hosted servers such as Heptapod or RhodeCode their repository roles. Give the account the smallest access that works.
User name and password or token (https://)
| Access on the server | Required? | What Safeguard uses it for |
|---|---|---|
| Read (pull) access to each repository you add | Required | hg identify for the newest changeset, hg clone -U -r <ref> and hg archive for scans, hg branches, hg bookmarks and hg tags for listing, hg cat for the files a fix changes |
| Push access to the repository | Optional | Branch delivery of fixes: hg push --new-branch of a new named branch |
Least privilege: read access to the repositories you scan and nothing else. Leave fixes as patch downloads.
SSH key (ssh://)
| Access | Required? | What Safeguard uses it for |
|---|---|---|
An SSH login that can run hg serve --stdio for the repository | Required | The transport for every hg command |
| Read access to the repository on the server | Required | Reading, listing and archiving |
| Write access to the repository | Optional | Branch delivery of fixes |
Least privilege: a dedicated SSH key whose authorized_keys entry restricts it to hg-ssh <repository paths> (Mercurial's contrib/hg-ssh), read-only unless you turn on branch delivery.
Token types
| Credential | Works? | Notes |
|---|---|---|
| Read-only access token from your server | Yes (recommended) | For example a personal or project access token that can read the repository on Heptapod or RhodeCode; check your server's documentation for its name |
| Account password | Yes | Only over https:// |
| SSH key without a passphrase | Yes | Generate one for this connection only |
| SSH key with a passphrase | No | Scans run unattended |
| Client TLS certificate | Not available | Use a password, token or SSH key |
Expiry: set the token to expire on your normal rotation schedule (for example 90 days). When it expires, scans fail with the authentication error below until you save a new one.
What we never need: administrator or owner rights, the ability to delete or strip changesets, server hook or extension configuration, or any repository you do not add.
Step-by-step setup
Create the credential on your server
- Create an account or a token that can read the repositories. On hgweb, allow the account in
[web] allow_read(or give it access in your web server's authentication); on Heptapod or RhodeCode, give it read access to the project. - For SSH, create a key pair (
ssh-keygen -t ed25519 -N "" -f safeguard), add the public key on the server, and get the host key line withssh-keyscan -t ed25519 <server>. - If your server's certificate is self-signed, get its SHA-256 fingerprint to compare in the dialog, for example
openssl s_client -connect <server>:443 </dev/null | openssl x509 -noout -fingerprint -sha256.
Or with the Mercurial command line
Check the access before you connect:
hg identify -r default https://hg.example.com/repos/app
hg identify -r default ssh://hg@hg.example.com//srv/hg/appConnect it in Safeguard
- Open Integrations and choose the Project/Product tab.
- Click Connect on the Mercurial card.
- Choose Public or Private, enter a Name, and put one repository URL per line in Repository URLs.
- For Private, choose Sign in with: User name and password or token, or SSH key (ssh://) with the SSH private key and Server host key.
- Choose how often to Check for new commits, and how to Deliver fixes as (a patch, or a new named branch with write access and a Fix branch name prefix).
- Click Check access. If the server's certificate is not trusted, compare the fingerprint shown, tick This is my server's certificate, and the check runs again.
- Click Next, pick each repository's branch, bookmark or tag, and connect with the scan depth you want.
Webhooks and triggers
-
On connect: each repository you select is scanned once.
-
Polling (default): Safeguard checks the newest changeset of each scanned branch, bookmark or tag every 15 minutes (5 minutes to 24 hours, or off) with
hg identify, and rescans when it changed. -
Commit hook: in the connection's edit dialog, Scan on commit > Set up commit hook gives you
safeguard-hg-hook.shand a credential file,safeguard-hook.conf. Save both on the server that hosts the repository, make the script executable, keep the credential file readable only by the user the server runs as (chmod 600), and add to the repository's.hg/hgrc:[hooks] changegroup.safeguard = /path/to/safeguard-hg-hook.shThe server needs
curl. After each push the hook sends the newest changeset, its author and the branches and bookmarks it touched tohttps://api.safeguard.sh/scm/api/v1/integrations/vcs-hooks/<connection id>, authenticated with the credential, and Safeguard rescans the projects on those branches or bookmarks. The credential is shown once; Issue a new hook credential rotates it and Revoke stops deliveries. The hook never blocks or changes a push. -
Schedules: you can also rescan on a schedule from Integrations > Scheduled.
What we read and store
- Read: the history of the scanned revision (clone without a working copy), the files of that revision, and its hash, author and date. For a fix, the original content of the files it changes.
- Stored: the SBOM, findings and project metadata; the changeset hash as the scan's commit; for fixes, the patch and the files it changes. The password, token or SSH key is encrypted at rest and never shown again after you save it.
- Not stored: the clone and the archived tree, which are deleted when the scan ends. Each run uses a private Mercurial configuration with no extensions and no hooks, removed afterwards.
- No customer data from this integration is sent to third-party LLMs.
Troubleshooting
| Message you see | Cause | Fix |
|---|---|---|
The Mercurial server refused the user name and password or token (or the SSH key). | Wrong password or token, an expired token, or a key the server does not accept | Check with hg identify -r default <url> and save the right credential |
This user is not allowed to read that repository. Ask its administrator for read access. | The account has no read access | Give it read access on the server |
The server's certificate is not issued by a trusted authority (or does not match the host name). If this is your server's certificate, confirm the fingerprint shown and pin it on the connection. | Self-signed or private-CA certificate | Compare the fingerprint and confirm it in the dialog |
The server presented a different certificate from the pinned one. If the certificate was renewed, confirm the new fingerprint. | The certificate changed since you pinned it | Check the new fingerprint, then confirm it in the edit dialog |
The SSH host key of the server does not match the one on the connection. Add the server's current host key line. | Wrong or changed host key line | Run ssh-keyscan -t ed25519 <server> and paste the line |
That branch, bookmark, revision or file does not exist in the repository. | A typo, or a branch that was closed or a bookmark that was deleted | Pick the branch again in Review |
Could not reach a Mercurial repository at that URL. Check the address and protocol (https:// or ssh://). | Wrong host or path, the server is down, or a firewall blocks Safeguard | Check the URL; allow Safeguard's addresses to reach the server |
Passwords are never sent over plain http://. Use the https:// address of the server. | A private connection with an http:// URL | Use the server's https:// address |
This server address isn't allowed: it resolves to a private, loopback, link-local or metadata address, which Safeguard never connects to. | The server is only reachable on a private network | Expose it on a public address with TLS, or use Safeguard's on-premise deployment |
A branch named <name> already exists. Nothing was pushed. | Branch delivery found a branch with the fix's name | Delete or rename that branch, or change the fix branch name prefix |
Rotation and disconnect
- Rotate: create a new token or key on the server, then open the connection's edit dialog, enter it, click Check access and save; then revoke the old one. To rotate the hook credential, click Issue a new hook credential and replace
safeguard-hook.confon the server. - Disconnect: delete the connection under Integrations. Then revoke the token or remove the SSH key on the server, and remove the
changegroup.safeguardline and the two files.
Vendor references
- hgrc(5): the [auth], [hostsecurity], [hooks] and [web] sections, checked 2026-10-16 against Mercurial 7.2.4.
- hg(1): identify, clone, archive, export and import, checked 2026-10-16 against Mercurial 7.2.4.
- Mercurial wiki: Publishing repositories (hgweb), checked 2026-10-16.
Subversion (SVN)
Connect Apache Subversion repositories to Safeguard. The access each sign-in method needs, which credentials work, step-by-step setup, commit hooks and polling.
Perforce (Helix Core)
Connect Perforce Helix Core depots and streams to Safeguard. The protections each step needs, password or ticket sign-in, ssl: fingerprint pinning, step-by-step setup, change-commit triggers and polling.