Skip to content

Authentication

IdentityScribe supports three authentication methods across all channels and the monitoring endpoint.

Two environment variables enable authentication with Bearer tokens:

Terminal window
SCRIBE_AUTH_ENABLED=true
SCRIBE_AUTH_ISSUER=https://auth.example.com/realms/mycompany

Or in HOCON with named providers:

auth {
enabled = true
providers {
default {
issuer = "https://auth.example.com/realms/mycompany"
audiences = ["scribe"]
}
}
}
Authentication Flow

How requests are authenticated

HTTP Request
? Authorization header?
Bearer token
JWT Validation Verify signature via JWKS
Basic auth
ROPC or LDAP Exchange for token or bind
No header
Anonymous If allowed by config
Authenticated principal
or
401 Unauthorized

Clients authenticate by sending an HTTP Authorization header. Scribe supports two header schemes:

SchemeHeader formatWhat Scribe receives
BearerAuthorization: Bearer <jwt>A pre-obtained JWT token
BasicAuthorization: Basic <base64>Username and password (base64-encoded)

The authentication method determines how Scribe validates what it receives:

MethodHeaderValidation
Bearer tokensBearerVerify JWT signature via JWKS, check claims
ROPCBasicExchange credentials with IdP for JWT, then verify
LDAP bindBasicSearch for user DN, bind to LDAP to verify password

Scribe tries Bearer first. If no Bearer token is present, it falls back to Basic auth methods (ROPC or LDAP, depending on configuration).

Your client…UseWhy
Already has a JWT from your IdPBearerFastest — no network calls per request
Sends username/password, needs OAuth claimsROPCTrades credentials for JWT, gets roles/scopes from IdP
Sends username/password, no IdP availableLDAPDirect validation against directory

Use Bearer tokens unless clients can’t obtain tokens themselves.

The MCP channel uses the same auth: OAuth Bearer first, with Basic (ROPC or LDAP bind) as fallback when tokens are unavailable. See MCP Channel — Authentication for client-specific setup and MCP Cursor callback issues when OAuth callbacks fail.

Clients obtain a JWT from your identity provider and include it in requests:

GET /api/users HTTP/1.1
Authorization: Bearer eyJhbGciOiJSUzI1...
  1. Client authenticates with IdP (browser redirect, client credentials, etc.)
  2. IdP issues a signed JWT
  3. Client sends JWT to Scribe in the Authorization header
  4. Scribe verifies signature against IdP’s public keys (cached from JWKS)
  5. Scribe checks expiration, audience, and issuer claims

No per-request calls to the IdP. After the initial JWKS fetch, validation happens locally.

Bearer Token Validation

JWT verification with JWKS

Client
Scribe
IdP
1
Authenticate (OIDC/OAuth)
2
JWT access token
3
Authorization: Bearer <token>
4
Fetch JWKS public keys
5
JWK Set
6
Validate JWT signature
7
API response

ROPC (Resource Owner Password Credentials)

Section titled “ROPC (Resource Owner Password Credentials)”

Clients send username and password via HTTP Basic auth. Scribe exchanges those credentials with your IdP for a JWT, then validates the token.

GET /api/users HTTP/1.1
Authorization: Basic YWxpY2U6c2VjcmV0
ROPC Authentication

Password-based token exchange

Client
Scribe
IdP
1
Basic auth (user:pass)
2
Token request (ROPC grant)
3
JWT access token
4
Validate JWT signature
5
API response

Configuration:

auth {
enabled = true
methods = [bearer, ropc]
providers {
default {
issuer = "https://auth.example.com"
audiences = ["scribe"]
client-id = "scribe"
client-secret = ${SCRIBE_AUTH_CLIENT_SECRET}
}
}
ropc {
scopes = "openid profile email"
}
}

Clients send username and password via HTTP Basic auth. Scribe searches for the user’s DN, then binds to LDAP with the provided password.

GET /api/users HTTP/1.1
Authorization: Basic YWxpY2U6c2VjcmV0

No IdP required. Authentication happens directly against your LDAP directory. LDAP-only auth does not require OIDC provider credentials — you do not need to configure auth.providers, issuer, client-id, or client-secret.

LDAP Bind Authentication

Direct password verification against directory

Client
Scribe
LDAP
1
Basic auth (user:pass)
2
Search user DN (service bind)
3
User DN found
4
BIND as user DN
5
BIND success
6
Extract identity from attributes
7
API response

Configuration:

auth {
enabled = true
methods = [ldap]
ldap {
base = "ou=users,dc=example,dc=com"
bind-attribute = "uid"
filter = "(objectClass=person)"
}
}

LDAP connection settings (server URL, bind-dn, bind-password) are inherited from the root ldap {} configuration. Configure a service account there — Scribe uses it to search for user DNs before validating passwords. See the auth reference for pattern-based lookup, LDAP role mapping, and attribute configuration.

Access rules let you control who can do what. Rules evaluate top-to-bottom; first match wins. If nothing matches, access is denied.

Out of the box, Scribe allows authenticated requests and denies anonymous access. Prometheus and health endpoints are exceptions — they allow anonymous access for scrapers and Kubernetes.

auth.rules = [
{ id = "admin-bypass", action = allow, where = "subject.roles = admin" }
{ id = "schema-public", action = allow, where = "request.channel = graphql and request.operation = schema" }
{ action = allow, where = "subject.authenticated = true and request.operation in [search, lookup]" }
]

Each rule takes action (allow/deny), an optional where filter expression, and an optional id for log/trace visibility.

Authenticated access with public health checks:

auth.rules = [
{ action = allow, where = "request.path startswith /health" }
{ action = allow, where = "subject.authenticated = true" }
]

Restrict history queries to admins:

auth.rules = [
{ action = allow, where = "subject.roles = admin" }
{ action = deny, where = "request.operation = history" }
{ action = allow, where = "subject.authenticated = true" }
]

LDAP writes require admin role:

channels.ldap.auth.rules = [
{ action = allow, where = "subject.roles = admin" }
{ action = deny, where = "request.operation = modify or request.operation = delete" }
{ action = allow, where = "subject.authenticated = true" }
]
  • Auth configuration reference — All settings: access rule attributes, identity model, LDAP role mapping, credential caching, JWT validation, browser sessions, multi-provider setup, channel overrides
  • Production checklist — TLS, network isolation, token validation hardening
  • Networking — TLS and socket configuration
  • Error Handling — Auth error codes and response formats