External Authorization

Delegate authorization decisions to an external service. Vrata sends a check request before each proxied request, and the external service decides allow or deny.

Configuration

{
  "name": "auth",
  "type": "extAuthz",
  "extAuthz": {
    "destinationId": "<auth-service>",
    "mode": "http",
    "path": "/authorize",
    "decisionTimeout": "5s",
    "failureModeAllow": false,
    "includeBody": false,
    "onCheck": {
      "forwardHeaders": ["Authorization", "Cookie"],
      "injectHeaders": [{"key": "X-Original-URI", "value": "${request.path}"}]
    },
    "onAllow": {
      "copyToUpstream": ["x-auth-request-*"]
    },
    "onDeny": {
      "copyToClient": ["www-authenticate", "location"]
    }
  }
}

All fields

FieldTypeDefaultDescription
destinationIdstringrequiredDestination hosting the auth service
modestringhttphttp or grpc
pathstring/HTTP path for the check request (HTTP mode only)
decisionTimeoutstring5sMax time to wait for auth decision
failureModeAllowboolfalseAllow requests when auth service is unreachable
includeBodyboolfalseSend the request body to the auth service
onCheck.forwardHeadersstring[]Client headers forwarded to auth service
onCheck.injectHeadersarrayExtra headers added to the auth check request
onAllow.copyToUpstreamstring[]Auth response headers copied to the upstream request
onDeny.copyToClientstring[]Auth response headers copied to the client response

Examples

Basic HTTP auth check

{
  "name": "auth",
  "type": "extAuthz",
  "extAuthz": {
    "destinationId": "<auth-service>",
    "mode": "http",
    "path": "/authorize",
    "onCheck": {
      "forwardHeaders": ["Authorization"]
    }
  }
}

Vrata sends POST <auth-service>/authorize with the client’s Authorization header. The auth service returns 200 (allow) or non-200 (deny).

gRPC auth check

{
  "name": "grpc-auth",
  "type": "extAuthz",
  "extAuthz": {
    "destinationId": "<auth-grpc-service>",
    "mode": "grpc",
    "decisionTimeout": "3s"
  }
}

Vrata sends a gRPC CheckRequest to the auth service. The service returns OK (allow) or a non-OK status (deny).

Pass auth context to upstream

{
  "name": "auth-with-context",
  "type": "extAuthz",
  "extAuthz": {
    "destinationId": "<auth-service>",
    "path": "/authorize",
    "onCheck": {
      "forwardHeaders": ["Authorization", "Cookie"]
    },
    "onAllow": {
      "copyToUpstream": ["x-auth-user-id", "x-auth-roles", "x-auth-org"]
    }
  }
}

When the auth service allows the request, it can set response headers like x-auth-user-id: 42. Vrata copies these to the upstream request, so your backend receives the authenticated user identity without re-validating the token.

Redirect to login on deny

{
  "name": "auth-redirect",
  "type": "extAuthz",
  "extAuthz": {
    "destinationId": "<auth-service>",
    "path": "/authorize",
    "onDeny": {
      "copyToClient": ["location", "set-cookie"]
    }
  }
}

When the auth service denies with a 302, its Location and Set-Cookie headers are forwarded to the client, triggering a redirect to the login page.

Header interpolation

{
  "onCheck": {
    "forwardHeaders": ["Authorization", "Cookie"],
    "injectHeaders": [
      {"key": "X-Original-URI", "value": "${request.path}"},
      {"key": "X-Original-Method", "value": "${request.method}"},
      {"key": "X-Original-Host", "value": "${request.host}"},
      {"key": "X-Forwarded-Proto", "value": "${request.scheme}"},
      {"key": "X-Client-IP", "value": "${request.header.X-Forwarded-For}"}
    ]
  }
}

Supported interpolation variables:

Fail open (non-critical auth)

{
  "name": "soft-auth",
  "type": "extAuthz",
  "extAuthz": {
    "destinationId": "<auth-service>",
    "path": "/check",
    "failureModeAllow": true,
    "decisionTimeout": "2s"
  }
}

If the auth service is down or times out, the request is allowed through. Use for non-critical checks like feature flags or optional enrichment.

Include request body

{
  "name": "body-auth",
  "type": "extAuthz",
  "extAuthz": {
    "destinationId": "<auth-service>",
    "path": "/authorize",
    "includeBody": true
  }
}

The entire request body is forwarded to the auth service. Use when authorization depends on the request payload (e.g. checking resource ownership in a POST body).

Failure modes

failureModeAllowAuth service unreachableResult
false (default)timeout / connection errorRequest rejected (fail closed)
truetimeout / connection errorRequest allowed through (fail open)

Auth service protocol (HTTP mode)

Vrata sends:

POST <destination><path>
Content-Type: application/json
[forwarded headers]
[injected headers]

Expected responses: