Skip to main content
Version: Latest

Azure DevOps

Proxy for the Azure DevOps Services REST API via the managed gateway.

What this connector does

Gives agents gated access to an Azure DevOps organization for:

  • Listing projects.
  • Listing Git repositories in a project.
  • Querying and reading work items.

All operations are gated by PBAC policy. Every call flows: agent → gateway → /introspect (with this connector's resource_type) → OPA decision → Azure DevOps API → response.

The connector supports two upstream-auth modes:

  • entra_refresh (default) — PolicyArc uses the refresh token captured at the user's Microsoft sign-in to mint a fresh, correctly-audienced token per Microsoft service at call time. One sign-in works across any combination of Microsoft connectors — Graph (Mail, OneDrive, Teams) and Azure DevOps together. The minted token is cached per (user, resource) and re-minted on expiry. Azure DevOps enforces its own organization membership and permissions, and its audit trail shows the real person making each call.

  • idp_passthrough — forwards the user's Microsoft sign-in token directly to Azure DevOps, with no exchange. That sign-in token carries a single audience, so passthrough works for only one Microsoft resource — either Azure DevOps or Graph (Mail/OneDrive/Teams), not both; don't mix passthrough across Azure DevOps and Graph. Choose this only for strict tenants that disable refresh-token issuance (no offline_access), or that don't want a long-lived refresh token warehoused by PolicyArc. Otherwise prefer entra_refresh.

Prerequisites

entra_refresh mode (default)

  • Entra app registration — a confidential app used for login. It needs:
    • a client secret (stored in PolicyArc's secret store),
    • the federation redirect URI (/oauth2/callback),
    • a delegated Azure DevOps API permission (resource 499b84ac-1321-427f-aa17-267ca6975798, user_impersonation), with admin consent granted,
    • offline_access in the login scopes so a refresh token is captured.
  • PolicyArc Entra IdP registered with provider key microsoft, configured with the app's client_id/client_secret and the tenant authorize/token endpoints (https://login.microsoftonline.com/<tenant>/oauth2/v2.0/{authorize,token}). Login scopes must include offline_access so the gateway captures a refresh token at sign-in. See the Entra ID IdP guide.
  • Azure DevOps organization connected to the same Entra tenant (Org settings → Microsoft Entra), and the user must be a member of the org with permission for the operations you want to gate.
  • PBAC_GATEWAY_CREDENTIAL_KEY set on the AS (encrypts the cached tokens).

idp_passthrough mode (no token exchange)

Passthrough forwards the user's sign-in token directly, so there is no token exchange:

  • Entra app registration — a confidential app used only as a login IdP. It needs a client secret, the /oauth2/callback redirect URI, and the delegated Azure DevOps permission (resource 499b84ac-1321-427f-aa17-267ca6975798, user_impersonation) with admin consent granted.
  • PolicyArc Entra IdP (provider key microsoft) — login scopes must be openid profile email 499b84ac-1321-427f-aa17-267ca6975798/user_impersonation, so the captured token is audienced for Azure DevOps. offline_access is optional in passthrough mode — add it only to have the forwarded token refreshed silently on expiry; omit it for tenants that disable refresh-token issuance (users re-authenticate when the token lapses). Installing the connector auto-merges user_impersonation into the IdP scope list (via IdpScopeMerger); do not also add …/.default — Entra rejects .default combined with a resource-specific scope at sign-in (AADSTS70011).
  • Azure DevOps organization connected to the same Entra tenant and the user a member of the org (same as entra_refresh).
  • PBAC_GATEWAY_CREDENTIAL_KEY set on the AS (encrypts the captured login token).

Install

The install wizard has an Authentication picker (entra_refresh / idp_passthrough). The default is entra_refresh; choose idp_passthrough only if your deployment uses a single Azure-DevOps-audienced token for every connector and you have no Graph connectors configured.

1. Register the Entra IdP

Register the Entra IdP in PolicyArc (provider key microsoft) using the app's client_id/client_secret and tenant endpoints as described in Prerequisites. Confirm a user can log in to PolicyArc through it before installing the connector.

2. Install the connector

From the admin UI:

  1. Resources → Add → Azure DevOps
  2. Fill in the wizard:
    • Authentication — select entra_refresh (default) or idp_passthrough.
    • Azure DevOps organization URLhttps://dev.azure.com/<your-org>.
    • IdP — select the Entra IdP registered in step 1.
  3. Install.

The admin UI reads setup_fields directly from this connector's manifest — same fields shown below in the Setup fields reference.

3. Verify

Log in to PolicyArc through the Entra IdP first (so the gateway has a captured refresh token), then request a token with an Azure DevOps scope and call through the gateway:

curl "https://<your-as>/gateway/azure-devops/_apis/projects?api-version=7.1" \
-H "Authorization: Bearer <token>"

A successful 200 with the project list confirms the full chain end-to-end:

  • entra_refresh — refresh token captured → per-resource token minted → introspect allowed → gateway proxied → Azure DevOps responded.
  • idp_passthrough — no exchange: the captured Azure-DevOps-audienced login token is forwarded verbatim → introspect allowed → gateway proxied → Azure DevOps responded. (If the captured token is audienced for anything else, ADO returns 401; re-check the IdP login scopes per Prerequisites.)

What can go wrong

SymptomCauseFix
502 "no stored IdP token"The caller never logged in through the microsoft IdP (or used client_credentials, which has no user context)Re-authenticate through the Entra IdP so the gateway can capture a refresh token.
502 "admin consent / API permission missing"The Entra app lacks admin-consented delegated Azure DevOps permissionGrant admin consent for the user_impersonation permission on resource 499b84ac-… in the app registration.
502 "refresh failed or token expired"The refresh token is expired or revokedRe-authenticate through the Entra IdP; ensure offline_access is in the login scopes.
401/203 from Azure DevOpsThe org is not connected to the same Entra tenant, or the user isn't a memberConnect the org to the tenant (Org settings → Microsoft Entra) and add the user.
404 at the gatewayWrong pathGateway path is /gateway/<resource-name>/<ADO REST path> — ADO paths start with /_apis/... or /{project}/_apis/....
ADO returns an HTML/redirect page instead of JSONMissing api-version query parameterAppend ?api-version=7.1 (or the version your API requires) to ADO REST calls.
403 from the gatewayAgent lacks the required scopeRequest a token with azuredevops:read.

Scopes

ScopeMeaningRoutes
azuredevops:readRead-only operationslist projects, list repositories, query/get work items

Policy authors can write rules targeting input.resource.type == "urn:connector:identos:azure-devops". Per-project rules use the resource_id (azuredevops://{project}/...).

Setup fields

FieldRequiredDefaultPurpose
base_urlyesAzure DevOps organization URL, e.g. https://dev.azure.com/your-org.

The Entra IdP (provider key microsoft) supplies the client credentials and token endpoint — it is selected at install time, not entered as a secret here.

MCP tools

When the managed gateway's MCP aggregator is enabled, this connector exposes the following tools to agents:

ToolScopeDescription
list_projectsazuredevops:readList projects in the organization.
list_repositoriesazuredevops:readList Git repositories in a project.
list_work_itemsazuredevops:readQuery work items in a project via WIQL.
get_work_itemazuredevops:readGet a single work item by ID.

Each tool's input schema is embedded in the manifest and forwarded verbatim to MCP clients.

Example policy

Restrict work-item access on a sensitive project to members of the security-team group:

package pbac.operator.connectors["identos.azure-devops"]

deny contains msg if {
input.resource.type == "urn:connector:identos:azure-devops"
startswith(input.resource.id, "azuredevops://classified/")
not "security-team" in input.subject.groups
msg := "only security-team may access work items in the classified project"
}

This rule lives in the operator namespace (not this connector's) because "which group is allowed" is tenant-specific.

Manifest reference

  • ID: identos.azure-devops
  • Version: 1.0.0
  • Resource type: urn:connector:identos:azure-devops
  • Capabilities: mcp

Supported auth modes

TypeDetails
entra_refreshrequires IdP microsoft
idp_passthroughrequires IdP microsoft

Setup fields

IDLabelDefaultSecret?Notes
upstream_auth.typeAuthenticationentra_refreshnoAuthentication mode. entra_refresh (default) mints a separate per-resource token for each Microsoft service from your one sign-in, so a single login works across any mix of Microsoft connectors — Graph (Mail/OneDrive/Teams) and Azure DevOps together. idp_passthrough instead forwards your Microsoft sign-in token as-is, and that token is valid for only one audience: passthrough therefore works for either Graph (Mail/OneDrive/Teams) or Azure DevOps, not both. Use entra_refresh if you need more than one.
base_urlAzure DevOps organization URLnoplaceholder: https://dev.azure.com/your-org

Scopes

Scope
azuredevops:read

Routes

MethodPatternScopeResource template
GET/_apis/projectsazuredevops:read
GET/{project}/_apis/git/repositoriesazuredevops:readazuredevops://{{project}}/repositories
POST/{project}/_apis/wit/wiqlazuredevops:readazuredevops://{{project}}/workitems
GET/{project}/_apis/wit/workitems/{id}azuredevops:readazuredevops://{{project}}/workitems/{{id}}

MCP tools

NameScopeDescription
list_projectsazuredevops:readList Azure DevOps projects in the organization.
list_repositoriesazuredevops:readList Git repositories in a project.
list_work_itemsazuredevops:readQuery work items in a project via WIQL (Work Item Query Language).
get_work_itemazuredevops:readGet a single work item by ID.