gloak
Compact Sans-IO Gleam helpers for interacting with Keycloak.
The library deliberately exposes gleam_http request and response values. It never sends HTTP, stores sessions, refreshes tokens, reads the clock, or generates entropy. Hosts choose their own HTTP client. JWT/JWKS verification is delegated to gose through the small gloak/verify seam; JOSE is not implemented locally.
Modules
This rebuild has four source modules, below the five-module limit:
gloak: validated core values (Server,Realm,ClientId, tokens, ids), shared errors, andgleam_httprequest/response helpers.gloak/oidc: OIDC/OAuth2 discovery, authorization, callback, PKCE challenge derivation, token, userinfo, introspection, revocation, logout, and JWKS request/response helpers.gloak/admin: a small Admin API subset for realms, users, groups, and clients.gloak/verify:gose-backed JWKS parsing, algorithm-pinned verifier construction, ID-token verification, and verified claim decoding.
Dependencies
Runtime dependencies are intentionally small and all are at v1.0.0 or newer:
gleam_stdlib >= 1.0.0gleam_http >= 4.3.0gleam_json >= 3.1.0kryptos >= 1.4.0for PKCE S256 hashinggose >= 2.1.0for JOSE/JWT/JWKS verificationgleam_time >= 1.0.0for caller-provided verification timestamps
No transport adapter dependency is included. gleam_httpc belongs in the consuming application if that is the HTTP client it wants.
Public contracts use sum types instead of booleans for domain states such as ResourceEnabled/ResourceDisabled, EmailAddressVerified/EmailAddressUnverified, TokenActive/TokenInactive, ClientRole/RealmRole, and JWT expiration policy. JSON boundary helpers still translate Keycloak booleans internally.
OIDC example
import gleam/http/response
import gloak
import gloak/oidc
pub fn discovery_request() {
let assert Ok(server) = gloak.server("https://auth.example.com")
let assert Ok(realm) = gloak.realm("master")
oidc.discovery_request(server, realm)
}
pub fn discovery_response(body: String) {
response.new(200)
|> response.set_body(body)
|> oidc.discovery_response("https://auth.example.com/realms/master")
}
Client credentials example
import gloak
import gloak/oidc
pub fn token_request(metadata: oidc.Metadata) {
let assert Ok(client_id) = gloak.client_id("service-account")
let assert Ok(secret) = gloak.client_secret("secret")
oidc.client_credentials_request(metadata, client_id, secret, ["profile"])
}
Admin example
import gloak
import gloak/admin
pub fn list_users() {
let assert Ok(server) = gloak.server("https://auth.example.com")
let assert Ok(realm) = gloak.realm("master")
let assert Ok(access_token) = gloak.access_token("admin-token")
let session = admin.session(server:, realm:, access_token:)
admin.user_list_request(session, [#("username", "renata")])
}
JWT verification
Use gloak/verify when you want the package’s Keycloak-shaped error mapping and verified-claim record. It still uses gose for JOSE behavior: JWKS parsing, algorithm pinning, key selection, registered-claim validation, and claim decoding. Configure issuer, audience, clock skew, expiration, and kid policy explicitly.
Verification
gleam format
gleam test