All notable changes to Authorizer will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
--rate-limit-fail-closed: when the rate-limit backend returns an error, respond with503instead of allowing the request (default remains fail-open).--metrics-host: bind address for the dedicated/metricslistener (default127.0.0.1). Use0.0.0.0when a scraper on another host/pod must reach the metrics port over the network; keep the metrics port off public ingress.- OIDC Discovery —
grant_types_supportedincludesimplicit: honestly reflects that/authorizeacceptsresponse_type=tokenandresponse_type=id_token.
- Prometheus
/metrics: always served on a dedicated HTTP listener (--metrics-host:--metrics-port, default127.0.0.1:8081).--http-portand--metrics-portmust differ;/metricsis not registered on the main Gin server. - HTTP metrics: unmatched Gin routes use the fixed path label
unmatchedinstead of the raw request URL (prevents cardinality attacks). - GraphQL metrics: the
operationlabel is nowanonymousorop_<sha256-prefix>so client-supplied operation names cannot explode time-series cardinality. - Health/readiness JSON: failure responses return a generic
errorstring; details remain in server logs. - OAuth callback JSON: generic OAuth-style error body on provider processing failure; details remain in logs.
/playgroundis subject to the same per-IP rate limits as other routes (health and OIDC discovery paths stay exempt)./metricsis not on the main HTTP router.- BREAKING:
/userinfonow strictly filters claims by scope per OIDC Core §5.4. The endpoint returns onlysubplus the claims permitted by the standard scope groups (profile,email,phone,address) encoded in the access token. Previously,/userinforeturned the full user object regardless of scopes. Clients that request only theopenidscope but read profile/email claims from/userinfomust now request those scopes explicitly. Seedocs/oauth2-oidc-endpoints.mdfor the full scope→claim mapping.
authorizer_client_id_not_found_total: replaced byauthorizer_client_id_header_missing_total, which matches the actual behavior (header omitted, request still allowed). Update dashboards and alerts accordingly.- OIDC Discovery —
registration_endpoint: previously pointed to the signup UI rather than an RFC 7591 dynamic client registration endpoint. It will return when RFC 7591 is implemented.
- OIDC ID token
at_hash: now correctly set tobase64url(sha256(access_token)[:16])for all flows. Previously the implicit/token branch incorrectly setat_hashto the nonce value (OIDC Core §3.2.2.10). - OIDC ID token
nonce: now echoed in the ID token whenever it was supplied in the auth request, regardless of the flow used (OIDC Core §2).
Pre-release. See 2.2.1-rc.0 on GitHub.
- CSRF protection (middleware).
- Per-IP rate limiting with Redis and in-memory backends.
- GraphQL query complexity limit.
- 5-second execution timeout for custom access token scripts.
- Crypto: AES-GCM with HKDF key derivation (replaces AES-CFB); RSA 4096, improved
DecryptRSAerror handling and base64-related naming;crypto/randfor HMAC key generation. - JWT / tokens: Verify JWT algorithm in parse keyfunc; safe type assertions for claims; bearer extraction case-sensitivity fix; shorter session and refresh token lifetimes; reserved claim blocklist for custom token scripts.
- Cookies:
HttpOnlyon all cookies; reduced cookie max-age;SameSiteon admin cookie (with broader security-header and CORS credential fixes). - OAuth / redirects: Apple ID token signature verified via OIDC;
redirect_urivalidation hardened against open redirects and wildcard abuse. - GraphQL: SSRF protection for
_test_endpoint; constant-time admin secret comparison; user enumeration mitigated via generic error messages. - HTTP / parsers: Host header validation to reduce injection risk.
- Storage / DB: Parameterized AQL in ArangoDB
UpdateUsers; Cassandra client TLS verification enabled; GORMAllowGlobalUpdatedisabled;DeleteSessionimplemented for SQL and ArangoDB. - Email / templates: Explicit TLS
ServerNamefor SMTP;html/templatefor email rendering (SSTI mitigation);template.JSXSS-related fix. - Webhooks: SSRF protection, HMAC signatures, and response size limits.
- Data exposure: Password hash excluded from JSON serialization; JWKS no longer leaks HMAC keys.
- Operational: Sanitized errors, panics replaced with errors where appropriate; Dockerfiles hardened (defaults, signals, healthcheck); client ID audit logging and CSRF origin validation tightened.
- GitHub OAuth display name handling and POST logout behavior.
- MongoDB driver update and related compilation issues.
- Tests: custom script timeout coverage, client-ID metric behavior, and ArangoDB-related test hardening.
Full changelog: 2.2.0...2.2.1-rc.0
See 2.2.0 on GitHub.
- Prometheus metrics, health checks, and readiness HTTP endpoints (#528).
Full changelog: 2.1.0...2.2.0
See 2.1.0 on GitHub.
- Structured audit logging system.
- Audit logging consolidated behind an
internal/auditprovider.
- Open redirect: stricter validation for
redirect_uri.
Full changelog: 2.0.1...2.1.0
- CLI-based configuration: All configuration is now passed at server start via CLI root arguments. No env store in cache or database.
- New security flags:
--disable-admin-header-auth: Whentrue, server does not acceptX-Authorizer-Admin-Secretheader; only secure admin cookie is honored. Recommended for production.--enable-graphql-introspection: Controls GraphQL introspection on/graphql(defaulttrue; setfalsefor hardened production).
- Metrics endpoint: Metrics server on port 8081 (configurable via
--metrics-port). - Restructured project layout:
- Root-level
main.goandcmd/for CLI internal/for core packages (config, graph, storage, etc.)web/appandweb/dashboardfor embedded UIsweb/templatesfor HTML templates
- Root-level
- Build outputs: Binary named
authorizer; output tobuild/<os>/<arch>/authorizer. - Docker improvements:
- Multi-arch builds (linux/amd64, linux/arm64)
ENTRYPOINT [ "./authorizer" ]for passing CLI args at runtime- Alpine 3.23 base images
- Makefile targets:
make dev,make bootstrap,make build-local-image,make build-push-image.
- BREAKING: Configuration is no longer read from
.envor OS environment variables. Pass config via CLI flags. - BREAKING:
--client-idand--client-secretare required; server exits if missing. - BREAKING: Deprecated mutations
_admin_signup,_update_env,_generate_jwt_keysnow return errors directing users to configure via CLI. - BREAKING: Dashboard cannot update server configuration. Admin secret, JWT keys, and all env must be set at startup.
- BREAKING: Flag names use kebab-case (e.g.
--database-urlinstead ofdatabase_url). - BREAKING: Some inverted boolean flags (e.g.
DISABLE_LOGIN_PAGE→--enable-login-pagewithfalseto disable). - BREAKING: Go version requirement: >= 1.24 (see
go.mod). - BREAKING: Node.js >= 18 for web app and dashboard builds.
- Database provider template path:
internal/storage/db/provider_template(wasserver/db/providers/provider_template). - GraphQL schema and resolvers moved to
internal/graph/. - Tests moved to
internal/integration_tests/; run withgo test -v ./...from repo root.
database_url,database_type,log_level,redis_urlflags (use kebab-case--database-url, etc.).env_fileflag (no longer supported).
- Corrected Makefile
generate-db-templateand DB-specific test targets to use current project structure. - Docker build and release workflow updated for v2 layout and binary name.
See MIGRATION.md for a detailed guide from v1 to v2.
Authorizer v1 used environment-based configuration stored in cache/DB and configurable via dashboard or _update_env mutation. For v1 documentation, see docs.authorizer.dev and the v1 release branch.