Skip to main content

Enterprise agent identity — Okta, Entra, OIDC

Unveilr is not your identity provider. Enterprises keep agents in Okta Cross App Access, Microsoft Entra Agent ID, or any OIDC issuer. Unveilr verifies those JWTs and decides whether a specific tool call is admissible — scopes, detections, and tenant policy — the same path as a lab uvt_ credential.

WhoProves
Your IdPWHO the agent is (signed JWT)
UnveilrWHAT’S ADMISSIBLE right now

Prerequisites

  1. An OIDC issuer that can mint short-lived JWTs for agent workloads.
  2. Console access as a tenant admin (Settings → Identity Providers).
  3. A registered agent identity with allowedTools set.

Configure the provider

Console

  1. Open Settings → Identity Providers.
  2. Pick Okta (Cross App Access), Microsoft Entra Agent ID, or Generic OIDC.
  3. Set Issuer to the exact iss claim your tokens carry.
  4. Click Discover (recommended) — Unveilr fetches /.well-known/openid-configuration and fills JWKS URL.
  5. Set Audience to the API/resource audience your agent tokens use (strongly recommended).
  6. Confirm Subject claim (sub for Okta/OIDC, oid for Entra by default).
  7. Add provider.

API

# Optional: resolve issuer + jwks_uri from discovery
curl -fsS -X POST "$UNVEILR_API/v1/identity-providers/discover" \
-H "Authorization: Bearer $ADMIN_JWT" \
-H "content-type: application/json" \
-d '{"issuerUrl":"https://YOUR_OKTA_DOMAIN/oauth2/default"}'

curl -fsS -X POST "$UNVEILR_API/v1/identity-providers" \
-H "Authorization: Bearer $ADMIN_JWT" \
-H "content-type: application/json" \
-d '{
"provider":"okta_xaa",
"name":"Corp Okta",
"issuer":"https://YOUR_OKTA_DOMAIN/oauth2/default",
"jwksUrl":"https://YOUR_OKTA_DOMAIN/oauth2/default/v1/keys",
"audience":"api://unveilr",
"subjectClaim":"sub"
}'
MethodPathPurpose
GET/v1/identity-providersList
POST/v1/identity-providers/discoverOIDC discovery (no persist)
POST/v1/identity-providersCreate
PATCH/v1/identity-providers/{id}Update (enable/disable, issuer, JWKS, audience, …)
POST/v1/identity-providers/{id}/refresh-jwksClear JWKS cache after key rotation
DELETE/v1/identity-providers/{id}Remove (blocked while agents are bound)

Bind & approve an agent

Configuring a provider grants nothing by itself. Bind a specific IdP subject to a registered agent (same separation-of-duties rule as minting uvt_):

curl -fsS -X POST "$UNVEILR_API/v1/agent-identities/$AGENT_ID/approve-external" \
-H "Authorization: Bearer $ADMIN_JWT" \
-H "content-type: application/json" \
-d '{"providerId":"eip_…","externalSubject":"svc-billing-01"}'

No Unveilr secret is returned — the credential lives at the IdP.

Console: Agents → agent detail → Bind IdP & approve.

Call Govern / Gateway with the IdP JWT

Agents present the IdP-issued JWT as Authorization: Bearer ….

Transport-agnostic PDP

curl -fsS -X POST "$UNVEILR_API/v1/govern/check" \
-H "Authorization: Bearer $IDP_JWT" \
-H "content-type: application/json" \
-d '{"tool":"ledger.query","server":"ledger","arguments":{"sql":"select 1"}}'

MCP Agent Gateway

Point the MCP client at https://gateway/mcp/{tenant}/{server} and use the same IdP JWT. The gateway introspects via the control plane (/internal/introspect): JWT-shaped bearers resolve through the external IdP path; unrecognized JWTs fall back to console OIDC for operators.

Lab/demo without an IdP still uses minted uvt_… tokens.

Fail-closed rules

Denied (never soft-allow):

  • Unrecognized iss / disabled provider
  • Signature, audience, or expiry failure
  • Subject not bound to an approved agent
  • Revoked / pending agent identity
  • Out-of-scope tool / policy deny

After IdP key rotation, use Refresh JWKS (or POST …/refresh-jwks) so the next verify fetches new keys.

Okta / Entra notes

ProviderTypical issuerSubject claimAudience
Okta XAA / Auth Serverhttps://{domain}/oauth2/{authServerId}subCustom API audience
Entra (v2)https://login.microsoftonline.com/{tenant}/v2.0oidApp ID URI / API audience
Generic OIDCYour issuer URLusually subAs configured

Use Discover whenever possible so issuer and jwks_uri match the IdP document exactly (trailing slashes and path segments matter).