Why a PAT is the right choice for services
When a service runs outside of a user session it cannot rely on the cached Windows credentials that Visual Studio or the TFS client uses on a developer machine. Azure DevOps Services (formerly VSTS) therefore recommends Personal Access Tokens for non‑interactive scenarios. A PAT is a scoped, revocable secret that can be sent over HTTPS and works with the same client libraries that expect a NetworkCredential.
Create a scoped PAT in Azure DevOps
Open your Azure DevOps organization, go to **User Settings → Personal access tokens**, click **New Token**, give it a descriptive name, set an expiration date, and select the minimal scopes you need (e.g., **Code → Read & Write**). Copy the generated token – you will never see it again.
Use VssBasicCredential with TfsTeamProjectCollectionFactory
The client library provides VssBasicCredential, which wraps a username (any non‑empty string) and the PAT as the password. Pass an instance of this credential to the factory method. The collection will authenticate on the first request, so there is no need to call Authenticate() manually.
using Microsoft.TeamFoundation.Client;
using Microsoft.VisualStudio.Services.Common;
public TfsTeamProjectCollection GetCollection()
{
var collectionUri = new Uri("https://myserver.visualstudio.com/DefaultCollection");
// The user name can be anything – Azure DevOps ignores it when a PAT is supplied.
var credentials = new VssBasicCredential(string.Empty, "<YOUR_PAT_HERE>");
var tpc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(collectionUri, credentials);
// Ensure the connection is established before returning.
tpc.EnsureAuthenticated();
return tpc;
}
Expose the connection through a WCF operation
Inject the helper method into your service class and use the returned TfsTeamProjectCollection to call any Azure DevOps API (e.g., WorkItemTracking, Git). Because the PAT is stored on the server, mobile clients only need to call your WCF endpoint, never the Azure DevOps SDK directly.
```csharp [ServiceContract] public interface IDevOpsService { [OperationContract] string GetLatestChangeset(int projectId); }
public class DevOpsService : IDevOpsService { public string GetLatestChangeset(int projectId) { var tpc = GetCollection(); var versionControl = tpc.GetService<VersionControlServer>(); var cs = versionControl.GetChangesets(projectId, 1, 0, null).FirstOrDefault(); return cs?.ChangesetId.ToString() ?? "none"; } } ```
Common pitfalls and how to avoid them
• **Do not embed the PAT in source control** – store it in Azure Key Vault, an environment variable, or a protected config file. • **Scope only what you need** – a token with full ‘All scopes’ can be misused if the service is compromised. • **Use HTTPS** – the SDK enforces TLS, but double‑check your WCF binding. • **Refresh the token before expiration** – either generate a long‑lived PAT or implement a rotation script.
Takeaway: Pass a PAT wrapped in VssBasicCredential to GetTeamProjectCollection; the service can then call Azure DevOps APIs without interactive login.
People also ask
Can I use Windows Integrated Authentication instead of a PAT?
Only when the service runs on a domain‑joined machine that the Azure DevOps server trusts. For Azure DevOps Services you must use a PAT or OAuth.
Do I need the Microsoft.TeamFoundation.* assemblies on the mobile client?
No. The mobile app talks to your WCF service, which uses the SDK internally. Keep the heavy SDK on the server side only.
What if I need to call the REST API instead of the client SDK?
You can reuse the same PAT; just add it as a Bearer token in the HTTP Authorization header.
Inspired by a public discussion on Stack Overflow. This article is an original explanation for learners.