This is the production security model, recommended for enterprise and ISO 27001 / SOC 2 reviews. If you just want the quickest connection and are comfortable with delegated OAuth, see the standard Azure DevOps integration instead. Both give Mjolnir access to the same repositories.
How it works
The integration authenticates as a service principal that you create and own. The connection is app-only — there is no signed-in user and no delegated OAuth token. Rather than a client secret or certificate, the service principal trusts a federated credential. At connection time, Borg’s GCP-hosted backend mints a short-lived, Google-signed OIDC token (issuerhttps://accounts.google.com) and presents it as the client_assertion in an OAuth2 client_credentials grant against your Entra tenant. Your tenant validates that token against the federated credential you configured and issues a short-lived Azure DevOps access token in return.
The practical consequence: Borg holds no client secret and no certificate for your service principal, ever. There is nothing of that kind to store, rotate, leak, or revoke on our side — the only thing we hold is a short-lived access token, valid until its own expiry (see Data handling).
Authentication vs authorisation
The split of responsibility between the two systems is the basis for why this integration is low-risk and fully customer-controlled:- Entra ID only authenticates the identity. The federated credential lets your tenant confirm that a request really comes from Borg’s GCP identity. It says nothing about what that identity is allowed to do.
- Azure DevOps authorises via its own permission model, entirely independent of Entra. The permissions you grant the service principal are what actually constrain what the connection can do.
What you will set up
You will create three things, in this order. Odin shows you the exact federation values to use after the first step, so keep the setup dialog open as you go.1
Register a service principal in Entra ID
In the Microsoft Entra admin centre, go to App registrations → New registration. Give it a dedicated name (e.g.
borg-odin-integration), single-tenant, with no redirect URI. Register it.From the app’s Overview, note the Directory (tenant) ID and Application (client) ID. Do not create a client secret or certificate — federation replaces them.2
Save the connection in Odin
In Odin, go to Management → Integrations, click Connect next to Azure DevOps, and choose Service principal. Enter your Tenant ID, Client (application) ID, and Azure DevOps organisation (the
{org} slug from dev.azure.com/{org}), then Save.Odin then displays the three federation values you need for the next step.3
Add a federated credential in Entra
Back on the app registration, go to Certificates & secrets → Federated credentials → Add credential, and choose the Other issuer scenario. Fill in exactly the values Odin shows (use the copy buttons — no trailing spaces):
Give the credential a name and save. No client secret or certificate is created — this is what lets your tenant trust Borg’s identity without any shared secret.
4
Grant least-privilege repository access in Azure DevOps
Add the service principal as a member of your Azure DevOps organisation, then grant it — on the nominated repository only:
- Code (Read) — clone the repository and read pull requests
- Contribute to Pull Requests — post PR review comments and the status check
5
Test the connection
Back in Odin, click Test connection. Odin mints a token and lists the repositories the service principal can see. A non-zero count confirms both the federation and the Azure DevOps permissions are correct.
- “Could not mint a token…” → the federation values do not match; recheck the issuer, subject, and audience for typos or a trailing slash.
- “Token minted, but the service principal is not authorised…” → federation works; the repository permissions from the previous step are missing or have not propagated yet.
6
Register a Service Hook for PR reviews (optional)
Only needed if you want PR Reviews — skip it for pentest-only use.After you save, Odin also shows a Webhook URL and an
X-Mjolnir-Token header value. Because a least-privilege service principal cannot register webhooks itself (that would require organisation subscription-admin rights), an Azure DevOps organisation admin registers them by hand:- In the project → Project settings → Service hooks → + (Create subscription) → Web Hooks.
- Create one subscription triggering on Pull request created, and a second on Pull request updated.
- For each, set the URL to the Webhook URL (copy the full value — it includes a query parameter), and paste the
X-Mjolnir-Token: …string into the HTTP headers field. - Use the wizard’s Test button to confirm Odin returns a
2xx, then finish.
Revocation
You can revoke Borg’s access unilaterally, at any time, without contacting Borg, by either:- Removing the federated credential from the service principal’s app registration in Entra ID — Borg can then no longer authenticate as the service principal at all; or
- Removing the service principal from your Azure DevOps organisation (or removing its permissions on the nominated repository) — authentication may still succeed, but Azure DevOps will no longer authorise any access.
Data handling
- Token lifetime — minted Azure DevOps access tokens are short-lived (approximately one hour) and are re-minted on expiry using the same federation flow. There is no long-lived refresh token, because
client_credentialsgrants do not issue one. - Storage — minted access tokens are cached, encrypted, in Google Secret Manager, scoped to your organisation’s integration record. No client secret or certificate is ever stored, because none is used.
- Scope of use — tokens minted under this connection are used only within the Azure DevOps organisation you nominate, bounded by the least-privilege permissions you grant: cloning the nominated repository for a whitebox penetration test, and reading pull requests, posting review comments, and posting a pull-request status check as part of PR Reviews. No other Azure DevOps organisation is accessed under this connection.
Permissions reference
Everything else — code push, branch write, work-item access, and organisation or project administration — is neither requested nor required.
Related
- Azure DevOps integration overview — including the delegated OAuth alternative
- PR Reviews — what Mjolnir posts on your pull requests
- Mjolnir Configuration — enabling PR reviews per repository