assay.dex
Dex OIDC identity provider. Discovery, JWKS, health, and configuration validation. Client:
dex.client(url). Module-level functions also available for backward compatibility.
Discovery (c.discovery)
c.discovery:config()→{issuer, authorization_endpoint, token_endpoint, jwks_uri, ...}— Get OIDC discovery configurationc.discovery:jwks()→{keys}— Get JSON Web Key Set (fetches jwks_uri from discovery)c.discovery:issuer()→ string — Get issuer URL from discoveryc.discovery:has_endpoint(endpoint_name)→ bool — Check if endpoint exists in discovery doc
Health (c.health)
c.health:check()→ bool — Check Dex health via/healthzc.health:ready()→ bool — Check Dex readiness (alias for check)
Scopes (c.scopes)
c.scopes:list()→ [string] — List supported OIDC scopesc.scopes:supports(scope)→ bool — Check if a specific scope is supported
Grants (c.grants)
c.grants:list()→ [string] — List supported grant typesc.grants:supports(grant_type)→ bool — Check if a specific grant type is supportedc.grants:response_types()→ [string] — List supported response types
Top-level
c:validate_config()→{ok, errors}— Validate OIDC configuration completeness (checks issuer, endpoints, jwks_uri)c:admin_version()→ version|nil — Get Dex admin API version (nil if unavailable)
Backward Compatibility
All legacy module-level functions (M.discovery(url), M.health(url), M.supported_scopes(url),
etc.) remain available and delegate to the client sub-objects.
Example:
local dex = require("assay.dex")
-- New client sub-object style
local c = dex.client("http://dex:5556")
assert.eq(c.health:check(), true, "Dex not healthy")
local validation = c:validate_config()
assert.eq(validation.ok, true, "OIDC config invalid: " .. table.concat(validation.errors, ", "))
local scopes = c.scopes:list()
assert.eq(c.scopes:supports("openid"), true)
-- Legacy module-level style still works
assert.eq(dex.health("http://dex:5556"), true, "Dex not healthy")
local validation = dex.validate_config("http://dex:5556")