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:

Dependencies

Runtime dependencies are intentionally small and all are at v1.0.0 or newer:

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
Search Document