Keycloak authentication and Manager RBAC¶
The Logstrm Manager uses standard OIDC bearer-token validation for its API and Authorization Code + PKCE in the embedded browser UI. The public landing site is not protected by this configuration; the Manager and its /api/v1 control-plane API are.
Roles¶
Create these realm or client roles and assign them to users or groups:
| Role | Permissions |
|---|---|
Viewer |
Read nodes and configuration versions |
Operator |
All Viewer permissions, plus rollout and rollback |
Admin |
All Operator permissions, plus node mutations and version creation |
The backend enforces the hierarchy Admin >= Operator >= Viewer. UI button state is only an operator convenience; it is not an authorization boundary.
Keycloak client¶
Create a public client for the browser Manager UI:
- Client ID: the value used as
SLIMSTREAM_OIDC_CLIENT_ID. - Client authentication: off.
- Standard flow: on.
- Direct access grants: off unless separately required by an approved operational procedure.
- PKCE method: S256.
- Valid redirect URIs: exact Manager origins and paths, for example
https://manager.example.com/. - Web origins: the exact Manager origin, for example
https://manager.example.com. - Do not use wildcard redirect URIs or wildcard web origins in production.
The browser discovers the authorization and token endpoints from the issuer's OIDC discovery document. The Manager exposes only the non-secret issuer and client ID at GET /api/v1/oidc/config.
Manager environment¶
Set these variables in the Manager process:
SLIMSTREAM_OIDC_ISSUER=https://keycloak.example/realms/logstrm
SLIMSTREAM_OIDC_CLIENT_ID=logstrm-manager
SLIMSTREAM_OIDC_REQUIRED=true
SLIMSTREAM_OIDC_ROLES_CLAIM=roles
SLIMSTREAM_OIDC_GROUPS_CLAIM=groups
SLIMSTREAM_OIDC_CLIENT_ROLES_CLAIM=resource_access
SLIMSTREAM_AUDIT_LOG=/var/lib/logstrm-manager/audit.log
Keycloak client roles are read from:
resource_access[SLIMSTREAM_OIDC_CLIENT_ID].roles
The configured roles and groups claims are also accepted. Roles are deduplicated before authorization.
With SLIMSTREAM_OIDC_REQUIRED=true, missing or invalid OIDC configuration fails closed. Do not run a production Manager with OIDC disabled. Local development may omit OIDC only when the Manager is isolated and not exposed to an untrusted network.
Endpoint policy¶
| Endpoint | Viewer |
Operator |
Admin |
|---|---|---|---|
GET /api/v1/nodes |
yes | yes | yes |
POST /api/v1/nodes |
no | no | yes |
DELETE /api/v1/nodes/:id |
no | no | yes |
GET /api/v1/versions |
yes | yes | yes |
POST /api/v1/versions |
no | no | yes |
POST /api/v1/versions/:id/rollback |
no | yes | yes |
POST /api/v1/rollouts |
no | yes | yes |
GET /api/v1/health |
public health check | public health check | public health check |
GET /api/v1/oidc/config |
public bootstrap metadata | public bootstrap metadata | public bootstrap metadata |
All other /api/v1 methods default to Admin authorization. The backend validates issuer, audience, expiration, signing algorithm and JWKS keys. Discovery and JWKS refresh share one in-flight fetch. A trailing slash on the configured issuer is ignored when it is compared with discovery and token iss. Signing keys must be RSA, at least 2048 bits, and either omit use or set use to sig. Keys marked enc or another algorithm are ignored. jwks_uri must use the same scheme and host as the issuer.
Browser security model¶
The embedded UI uses Authorization Code + PKCE with:
- a cryptographically random
statevalue; - a cryptographically random OIDC
nonce; - an S256 PKCE challenge;
- exact
redirect_urireuse during token exchange; - in-memory access and refresh tokens;
sessionStorageonly for the short-lived PKCE verifier/state/nonce transaction;- refresh-on-401 and OIDC logout when supported by discovery.
Tokens are not written to localStorage, URLs, audit logs or request bodies. The API remains authoritative for all permissions.
Because the current browser flow uses an Authorization header rather than authentication cookies, it does not introduce cookie-based CSRF. If a future BFF changes this to cookies, add HttpOnly, Secure, and SameSite cookies plus an explicit CSRF token/origin policy before deployment.
Reverse proxy and TLS¶
Terminate TLS at a trusted reverse proxy and forward only the Manager origin. The proxy should:
- enforce HTTPS and set HSTS only when HTTPS is guaranteed;
- restrict
Originand CORS policy to the Manager origin; - apply request-size, timeout and rate limits;
- avoid logging
Authorizationheaders and query strings containing authorization responses; - preserve
X-Request-IDfor audit correlation.
The Manager sets X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy and Cache-Control: no-store. HSTS is intentionally proxy-owned because local development supports plain HTTP.
Audit and emergency access¶
Mutation and authorization-denial audit entries include timestamp, endpoint, method, source IP, resource, resource ID when present, identity, roles, request ID, result and status code. Request bodies and bearer tokens are not recorded. Each entry is appended and fsynced before the write is treated as durable. If that write or sync fails, the Manager logs audit persistence failed with the endpoint, action, request ID, result, status, and error. It does not log the identity, roles, source IP, or request body.
For an emergency access procedure, use a separately approved, time-limited Keycloak administrative assignment. Do not bypass backend authorization or enable production OIDC fallback without a documented change and rollback plan.