Skip to main content

OIDC Setup

Configure OpenID Connect (OIDC) authentication so AgentVisor™ validates JWT tokens and establishes real user identities.

How OIDC Works with AgentVisor

OIDC is the standard protocol for verifying identity. When configured:

  1. Clients include a JWT bearer token in the Authorization header
  2. AgentVisor validates the token's signature, expiration, and claims
  3. The token's claims become the principal for policy evaluation
  4. Your existing policies evaluate against the real identity

Configuration

Enable OIDC in your configuration file or via environment variables:

Config File

# agentvisor.yaml
api:
auth:
enabled: true
oidc_issuer: "https://accounts.google.com"
oidc_audience: "your-client-id.apps.googleusercontent.com"

Environment Variables

export AGENTVISOR_API_AUTH_ENABLED=true
export AGENTVISOR_API_AUTH_OIDC_ISSUER=https://accounts.google.com
export AGENTVISOR_API_AUTH_OIDC_AUDIENCE=your-client-id.apps.googleusercontent.com

Configuration Reference

VariableConfig KeyRequiredDescription
AGENTVISOR_API_AUTH_ENABLEDapi.auth.enabledYesSet to true to enable authentication
AGENTVISOR_API_AUTH_OIDC_ISSUERapi.auth.oidc_issuerYesOIDC issuer URL
AGENTVISOR_API_AUTH_OIDC_JWKS_URLapi.auth.oidc_jwks_urlNoOverride JWKS URL (see below)
AGENTVISOR_API_AUTH_OIDC_AUDIENCEapi.auth.oidc_audienceNoExpected aud claim in JWT

Provider Examples

Google

api:
auth:
enabled: true
oidc_issuer: "https://accounts.google.com"
oidc_audience: "your-client-id.apps.googleusercontent.com"

Keycloak

api:
auth:
enabled: true
oidc_issuer: "https://keycloak.example.com/realms/agentvisor"
oidc_audience: "agentvisor-api"

Keycloak (Kubernetes Internal)

When running in Kubernetes, the external OIDC issuer URL may not be reachable from inside the cluster (e.g., self-signed certs). Use oidc_jwks_url to point to an internal endpoint:

api:
auth:
enabled: true
oidc_issuer: "https://keycloak.example.com/realms/agentvisor"
oidc_jwks_url: "https://keycloak-service.keycloak.svc.cluster.local:8443/realms/agentvisor/protocol/openid-connect/certs"
oidc_audience: "agentvisor-api"

The oidc_jwks_url overrides the JWKS endpoint discovered from the issuer's .well-known/openid-configuration. The issuer URL is still used for iss claim validation.

The JWKS URL must be https. A plaintext http:// endpoint lets anyone on the network path substitute the signing keys and mint tokens for any principal. If your in-cluster provider genuinely cannot serve TLS, you can opt in with oidc_allow_insecure: true (AGENTVISOR_API_AUTH_OIDC_ALLOW_INSECURE=true) — a loud warning is logged and this should never be used in production.

Auth0

api:
auth:
enabled: true
oidc_issuer: "https://your-tenant.auth0.com/"
oidc_audience: "https://api.your-app.com"

How Claims Map to the Principal

All JWT claims become top-level fields in the principal map used for policy evaluation — each claim is directly accessible as principal.<claim>:

JWT ClaimPrincipal FieldDescription
subprincipal.subSubject identifier — used in policy rules
mrolesprincipal.mrolesArray of role MRNs for role-based policies (see MPE PORC)
mgroupsprincipal.mgroupsArray of group MRNs for group-based policies
(all others)principal.<claim>All JWT claims are passed through as top-level fields (e.g., principal.iss, principal.aud, principal.email)

Credential delegation: The original JWT is also preserved internally for credential delegation scenarios (e.g., principal_passthrough). This is not a policy-visible field — it is used by credential resolvers to forward the caller's token to upstream services.

Role and Group Mapping

MPE evaluates roles and groups from specific claims in the principal. Your OIDC provider must be configured to include these claims in the JWT:

ClaimTypePurpose
mrolesArray of MRN stringsRole-based access control (e.g., ["mrn:agentvisor:role:admin"])
mgroupsArray of MRN stringsGroup-based policy selection

Configure your identity provider to map user roles/groups to these claim names. For example, in Keycloak, use a "Token Mapper" to emit mroles as a JSON array claim.

Then reference them in your policies:

package authz
import rego.v1

default allow := false

allow if {
"mrn:agentvisor:role:admin" in input.principal.mroles
}

See the MPE PORC documentation for the full list of principal fields MPE supports.

OIDC Discovery

On startup, AgentVisor performs automatic OIDC discovery:

  1. Fetches {issuer}/.well-known/openid-configuration
  2. Discovers the JWKS (JSON Web Key Set) endpoint
  3. Fetches signing keys for JWT validation

If discovery fails, the host runtime will not start — this is fail-fast by design.

Testing Locally

You can test OIDC configuration without a full identity provider deployment:

Use Test Mode Alongside OIDC

Enable test mode to allow X-Test-Principal header injection while OIDC is configured. X-Test-Principal is only parsed when authentication is enabled, so both env vars are required:

AGENTVISOR_API_AUTH_ENABLED=true AGENTVISOR_API_AUTH_TEST_MODE=true agentvisor serve ./my-agent

X-Test-Principal cannot exercise the mroles-based policies described below in Role and Group Mapping — the test authenticator strips any mroles claim from the header before it reaches policy evaluation, so a test principal can never forge a role. Use mgroups instead (not stripped) if you need to grant a role while testing, or test against a real OIDC token.

Verify Token Validation

Send a request with a real JWT to confirm OIDC is working:

TOKEN="eyJhbG..." # Your JWT token

curl -H "Authorization: Bearer $TOKEN" \
-X POST http://localhost:8090/threads

Debug Authentication Failures

Enable debug logging to see detailed authentication information:

AGENTVISOR_LOG_LEVEL=debug agentvisor serve ./my-agent

The logs will show:

  • Token claims (iss, aud, sub, exp, iat)
  • Expected vs. actual values for mismatches
  • JWKS key lookup details

Troubleshooting

"Invalid token" Errors

  • Expired token: Check the exp claim — tokens have a limited lifetime
  • Wrong issuer: Ensure oidc_issuer matches the iss claim exactly (including trailing slashes)
  • Wrong audience: If oidc_audience is configured, the token's aud claim must match

Discovery Failures

  • Network issues: Ensure the issuer URL is reachable from the AgentVisor host
  • Self-signed certs / unreachable issuer from inside the cluster: Use oidc_jwks_url to point to an internal https endpoint that serves the same keys — see Keycloak (Kubernetes Internal) above. The JWKS URL must still be https (or oidc_allow_insecure: true, dev only — see the warning above); a plaintext http:// endpoint is rejected at startup either way
  • Startup failure: Discovery is fail-fast — check logs for the specific error

Missing Principal Fields

  • Ensure your identity provider includes the expected claims (sub, email, roles) in the JWT
  • Some providers require explicit scope requests to include certain claims

See Also