Skip to main content

Authentication in JARVIS

JARVIS uses JWT bearer tokens for inbound authn on most HTTP endpoints and an OIDC STS for service-to-service tokens (client credentials + token exchange).

Two layers​

1) Inbound JWT validation (per service)​

Each service validates the incoming Authorization: Bearer <jwt> and enforces:

  • signature (via JWKS)
  • iss (issuer)
  • aud (audience, typically the service ID)

Most services exempt /v1/health and /v1/version from auth so you can do liveness checks without a token.

Inbound auth is configured via ARP_AUTH_* (see “Env var cheat sheet” below).

2) Outbound STS tokens (service → service)​

When one JARVIS service calls another, it obtains a token scoped to the callee, so the callee can validate aud properly.

JARVIS uses arp-auth for:

  • client_credentials (mint a service token)
  • RFC 8693 token-exchange (exchange an incoming token into a token for a downstream audience)

Profiles in JARVIS_Release​

JARVIS_Release drives auth posture via STACK_PROFILE (see compose/profiles/*.env):

  • dev-secure-keycloak (default): JWT validation enabled + token exchange via local Keycloak STS
  • dev-insecure: inbound JWT validation disabled (dev only); Keycloak still runs for service-to-service tokens
  • enterprise: template placeholders for an external issuer/STS and external stores

Local Keycloak dev STS (how it’s “set up”)​

In the pinned JARVIS_Release Docker Compose stack, Keycloak is the dev STS:

  • Compose runs Keycloak with --import-realm.
  • The realm import (compose/keycloak/realm-arp-dev.json) defines:
    • realm: arp-dev
    • one confidential client per service (client secret auth, service accounts enabled)
    • an audience mapper so minted tokens include the client ID in the access token aud claim

Where client secrets come from (in the release bundle)​

For local dev, secrets are intentionally “known strings” so the stack boots without manual Keycloak setup:

  1. You copy compose/.env.example → compose/.env.local.
  2. .env.local contains ARP_*_CLIENT_SECRET values that must match the Keycloak realm import.
  3. compose/docker-compose.yml maps those values into each container as ARP_AUTH_CLIENT_SECRET (the variable arp-auth reads).

For real deployments, generate unique client secrets and inject them via your platform’s secret manager (do not commit them).

Calling Run Gateway in dev-secure-keycloak (mint a token)​

In dev-secure-keycloak, /v1/health and /v1/version are unauthenticated, but API calls like POST /v1/runs require Authorization: Bearer <token>.

Recommended dev flow: use the stack-aware CLI (device/browser flow, no service secrets):

arp-jarvis auth login
TOKEN="$(arp-jarvis auth token --audience arp-run-gateway)"

Use the returned access_token as the bearer token when calling Run Gateway.

Default dev user for the local realm:

  • username: dev
  • password: dev

For scripting, you can use:

TOKEN="$(arp-jarvis auth token --audience arp-run-gateway)"

Which components need a client secret?​

Only services that mint/exchange tokens for outbound calls need ARP_AUTH_CLIENT_ID + ARP_AUTH_CLIENT_SECRET.

In the default JARVIS topology:

  • Run Gateway exchanges the inbound token into a coordinator-scoped token before forwarding.
  • Run Coordinator mints service tokens to call downstream executors and internal services.
  • Composite Executor and PDP may mint tokens for their downstream dependencies.

Leaf services that don’t call anything downstream typically only need ARP_AUTH_SERVICE_ID (inbound audience).

Current dev-stack caveat

In JARVIS_Release, Node Registry runs with ARP_AUTH_MODE=optional to allow Selection Service calls (the current Selection client does not attach bearer tokens).

Env var cheat sheet​

Inbound JWT validation (per service):

  • ARP_AUTH_PROFILE (dev-secure-keycloak, dev-insecure, enterprise)
  • ARP_AUTH_MODE (required, optional, disabled)
  • ARP_AUTH_ISSUER (expected iss)
  • ARP_AUTH_AUDIENCE or ARP_AUTH_SERVICE_ID (expected aud)
  • ARP_AUTH_OIDC_DISCOVERY_URL or ARP_AUTH_JWKS_URI (where to fetch JWKS)

Outbound STS token requests (per caller service):

  • ARP_AUTH_CLIENT_ID
  • ARP_AUTH_CLIENT_SECRET
  • ARP_AUTH_TOKEN_ENDPOINT (or ARP_AUTH_ISSUER + /protocol/openid-connect/token)

Downstream audience selection (examples):

  • JARVIS_RUN_COORDINATOR_AUDIENCE
  • JARVIS_*_AUDIENCE