Safeguard Docs
Integrations

Azure DevOps TFVC

Scan Team Foundation Version Control (TFVC) folders through your Azure DevOps connection. Which projects to name, the token scopes, polling and the Code checked in service hook, and why fixes arrive as patches.

Availability

TFVC is switched on per workspace, on top of the Azure DevOps integration. If you don't see the TFVC projects field in the Azure DevOps dialog, ask your Safeguard contact.

What it does

TFVC is part of your Azure DevOps connection, not a separate card. In the connection you name the projects that use Team Foundation Version Control. Safeguard then lists each project's TFVC root ($/<project>) and its top-level folders next to the git repositories. For each folder you pick the folder itself or one of its sub-folders.

Safeguard downloads that folder at its newest changeset, scans it for an SBOM and findings, and records the changeset number as the scan's commit. New check-ins are picked up by polling (the default) or by the connection's service hooks. Find it under Integrations on the Project/Product tab, on the Azure DevOps card.

Fixes arrive as a patch you download and apply. Azure DevOps lets apps read shelvesets but has no API to create one, so Safeguard never writes to TFVC.

Only Azure DevOps Services (https://dev.azure.com/<organization>) is supported. Azure DevOps Server (on-premises TFS) isn't.

Public vs private

PublicPrivate
What you enterOne or more TFVC folder URLs of a public projectThe organization, a Personal Access Token or Microsoft sign-in, and the TFVC projects
Credential neededNone (the project must be public)A token that can read code in those projects
What you can scanFolders of public projectsThe root and top-level folders of each named project, and their sub-folders

A TFVC folder URL is the page Azure DevOps opens for the folder, for example https://dev.azure.com/contoso/Fabrikam/_versionControl?path=$/Fabrikam/Main.

Supported auth methods

MethodUse it whenNotes
Personal Access TokenMost casesThe same token as the git repositories of the connection. It goes in the Authorization header of each request, never in a URL
Microsoft sign-in (Entra ID)Your organization allows it on the Azure DevOps cardRefreshed by Safeguard before it expires
None (Public tab)The project is publicRead anonymously

Permissions required

Code (Read) covers TFVC, the same scope the git repositories need.

Personal Access Token

ScopeRequired?What Safeguard uses it for
Code (Read)RequiredListing folders (tfvc/items), the newest changeset of a folder (tfvc/changesets), downloading the folder at that changeset, and reading the files a fix changes
Project and Team (Read)RequiredListing the organization's projects, and reading a project's id for its service hook
Service Hooks (Read, write & manage)OptionalCreating the Code checked in subscription for you. Without it, you add the subscription by hand
Code (Read & write)Not used for TFVCTFVC fixes are patches; nothing is checked in or shelved

Least privilege: Code (Read) and Project and Team (Read), for the one organization.

Token types

CredentialWorks?Notes
Personal Access Token for one organizationYes (recommended)Set the scopes above
Microsoft sign-inYesUses the account's own access to the projects
PAT for all accessible organizationsYesBroader than needed
Alternate credentials or a passwordNoAzure DevOps has retired them

Expiry: a Personal Access Token expires on the date you set (at most one year). When it does, scans fail with the token error below until you save a new one in the connection's edit dialog.

What we never need: Code (Read & write), check-in or shelve rights, project administration, or projects you do not name.

Step-by-step setup

Create the credential in Azure DevOps

  1. In Azure DevOps, open User settings > Personal access tokens > New Token.
  2. Pick the organization, and select Code (Read) and Project and Team (Read). Add Service Hooks (Read, write & manage) if you want Safeguard to create the check-in hook.
  3. Copy the token. Azure DevOps shows it once.

Or with the command line

Check that the token can read a folder (the token goes in the Basic password with an empty user name):

curl -s -u ":$AZURE_DEVOPS_PAT" "https://dev.azure.com/contoso/Fabrikam/_apis/tfvc/changesets?searchCriteria.itemPath=%24%2FFabrikam%2FMain&%24top=1&api-version=7.1"

Connect it in Safeguard

  1. Open Integrations, choose the Project/Product tab and click Connect on the Azure DevOps card. For an existing connection, open its edit dialog instead.
  2. On Private, enter the organization and the token (or sign in with Microsoft), and click Check access.
  3. In TFVC projects, enter one project name per line, for example Fabrikam.
  4. Click Next. The TFVC root and top-level folders of each project appear in Review next to the git repositories. Pick a folder and, under the branch column, / for the whole folder or one of its sub-folders.
  5. Connect with the scan depth you want.

For a public project, use the Public tab and add each folder's URL.

Webhooks and triggers

  • On connect: each folder you select is scanned once.
  • Polling (default): Safeguard checks the newest changeset of each scanned folder every 15 minutes and rescans when it changed.
  • Service hook: in the connection's edit dialog, Webhooks > Set up adds a Code checked in (tfvc.checkin) subscription for each project with a selected TFVC folder, with its required Under path filter set to $/<project>. It needs Service Hooks (Read, write & manage) on the token. Without that scope, the dialog shows the URL, user name and password to create the subscription by hand: Project settings > Service hooks > Web Hooks, trigger Code checked in, Under path $/<project>. The check-in event doesn't list the changed paths. So Safeguard rescans each folder whose newest changeset is the one that was checked in.
  • Schedules: you can also rescan on a schedule from Integrations > Scheduled.

What we read and store

  • Read: the files under each scanned folder at the scanned changeset, and the changeset's number, author, date and comment. For a fix, the original content of the files it changes.
  • Stored: the SBOM, findings and project metadata; the changeset number as the scan's commit; for fixes, the patch and the files it changes. The token is encrypted at rest. The TFVC project names are stored with the connection.
  • Not stored: the downloaded folder and its zip, which are deleted when the scan ends.
  • No customer data from this integration is sent to third-party LLMs.

Troubleshooting

Message you seeCauseFix
Azure DevOps refused the token (expired, revoked, or not for this organization)The token expired, was revoked, or belongs to another organizationCreate a new token for this organization and save it in the edit dialog
the token has no Code (Read) access to this projectThe token lacks Code (Read), or the account can't read the projectAdd the scope, or give the account access to the project
the path or revision does not existThe folder was renamed or deleted, or the project has no TFVCPick the folder again in Review; check the project name in TFVC projects
No TFVC folders appear in ReviewThe project uses only git, or the name is misspelledCheck the project name; git-only projects add no TFVC folders
TFVC is not enabled for this workspace (feature int:azure_devops_tfvc)TFVC is off for your workspaceAsk your Safeguard contact, or remove the TFVC projects
the selected path is larger than the checkout size limitThe folder is larger than the checkout limit (2 GB by default); nothing was downloadedScan a smaller folder

Rotation and disconnect

  • Rotate: create a new token, enter it in the connection's edit dialog, click Check access and save; then revoke the old one in Azure DevOps.
  • Disconnect: to stop scanning TFVC only, clear TFVC projects in the edit dialog, then delete the Safeguard projects that scan TFVC folders. To remove everything, delete the connection under Integrations; Safeguard deletes the service hooks it created. Then revoke the token in Azure DevOps.

Vendor references

On this page