Repository navigation
Releases: AyRickk/opencode-keycloak-auth
Release list
v0.4.2
v0.4.1
Fixed
- Token refresh now happens per request, not just at startup. OpenCode calls
the authloaderonly once — when it builds and memoizes the provider's SDK
client — so returning a static{ apiKey }froze the access token for the life
of the process. After a long idle (e.g. overnight) that token expired and every
request failed withUnauthorized(401) until OpenCode was restarted — no
auth loginrequired, because the stored (offline) refresh token was still
valid. The loader now installs a customfetchthat re-resolves and refreshes
the token on every outgoing request, so freshness no longer depends on how often
OpenCode invokes the loader. Single-flight refresh, rotation handling, and
persistence are preserved.
v0.4.0
Added
- Structured, leveled logging via
OPENCODE_KC_LOG
(silent/error/warn/info/debug, defaultwarn), prefixed with
[keycloak-auth]. Secrets are never logged. ConfigErrorthat names every missing required setting at once.
Changed
- A missing/incomplete configuration now logs a loud
warn
(registered in ERROR mode (missing: …)) instead of failing silently. - The token loader no longer swallows persistence failures — it warns, since a
lost rotated token would otherwise strand auth until re-login. - Login flows (auto-capture, paste-code, device) log the real failure cause
instead of an opaquefailed. - Test suite expanded from 29 to 99 tests, covering
log,errors,keycloak,
browser, andsharedin addition to the existing suites.
v0.3.0
v0.2.3
Fix: intermittent "unexpected server error" on token expiry
Keycloak rotates refresh tokens (each is redeemable only once). Under
concurrent requests near expiry, every loader invocation POSTed the same
stored refresh token — the first rotated it, the rest got invalid_grant and
forced a spurious opencode auth login. The loader now shares a single
in-flight refresh across concurrent calls, so the rotating token is redeemed
exactly once and both callers get the new access token.
src/loader.ts: single-flight refresh (cleared on settle → next expiry retries cleanly).test/loader.test.ts: +5 tests (single-flight, past-expiry, leeway boundary, rotation reuse, retry-after-failure).
Prebuilt plugin — no build needed
Two assets are attached, both produced by npm ci && npm run build in CI:
opencode-keycloak-auth.js— self-contained ESM bundle (zero runtime deps). Drop it straight into OpenCode's auto-load dir:mkdir -p ~/.config/opencode/plugins curl -fsSL -o ~/.config/opencode/plugins/keycloak.js \ https://github.com/AyRickk/opencode-keycloak-auth/releases/latest/download/opencode-keycloak-auth.js # configure via OPENCODE_KC_ISSUER / OPENCODE_KC_CLIENT_ID / ... env vars
opencode-keycloak-auth-0.2.3.tgz— vendored tarball fornpm install ./*.tgz.
Full Changelog: v0.2.2...v0.2.3
v0.2.2
Fix: provider no longer silently disappears on incomplete config
Symptom: opencode auth login reported Unknown provider "keycloak" (and the
provider was absent from the list) when issuer/clientId weren't reaching the
plugin — even though other plugins installed the same way worked.
Cause: the plugin factory called resolveConfig(), which throws when
issuer/clientId are missing. OpenCode drops a plugin that throws at load
(error only visible with --print-logs), so the provider was never registered.
Config-less plugins loaded fine, which is why only this one failed.
Fix: the factory now catches the error, still registers the provider, and
surfaces an actionable message (⚠ not configured — Missing Keycloak issuer …)
when a login method is selected, instead of vanishing.
Also in this release
resolveProviderId()helper that never throws.- New
test/index.test.tscovering configured and incomplete-config paths. - README rewritten around how OpenCode actually loads plugins:
- it resolves a plugin entry by npm registry name (needs network) or by a
filesystem path — it never looks in your project/globalnode_modules; - the documented
~/.config/opencode/plugins/auto-load directory (drop the
builtdist/index.jsas a single file; configure viaOPENCODE_KC_*env vars); OPENCODE_DISABLE_MODELS_FETCH=1/OPENCODE_MODELS_PATHfor air-gapped hosts
(themodels.devfetch failure is non-fatal).
- it resolves a plugin entry by npm registry name (needs network) or by a
Full Changelog: v0.2.1...v0.2.2
v0.2.1
Maintenance release
Updated all dev dependencies to their latest versions:
- eslint 9 → 10 (and
@eslint/js9 → 10) - typescript 5 → 6 (added
ignoreDeprecations: "6.0"for the deprecatedbaseUrlused by tsup's d.ts build) - vitest 2 → 4
- @types/node 22 → 26
- @typescript-eslint/eslint-plugin & parser → 8.62
- tsup → 8.5, prettier → 3.8
- @opencode-ai/plugin → 1.17.11
No runtime or public API changes. Typecheck, lint, tests (18/18), build and format all pass on a clean install.
Full Changelog: v0.2.0...v0.2.1
v0.2.0
Changes
- Removed all AgentGateway references — the plugin is now documented as a generic Keycloak OAuth2/OIDC auth plugin for any OpenAI-compatible provider.
- Breaking: the default
providerIdchanged fromagentgatewaytokeycloak. If you relied on the old default, setOPENCODE_KC_PROVIDER_ID=agentgateway(or theproviderIdplugin option) and make sure it matches your"provider"key inopencode.json. - Genericized README, code comments, package keywords, and examples (scopes, baseURL, provider name).
Full Changelog: v0.1.0...v0.2.0
v0.1.0
First release of opencode-keycloak-auth — an OpenCode auth plugin that logs in to Keycloak via OAuth2/OIDC and feeds short-lived, auto-refreshed access tokens to an OpenAI-compatible AgentGateway provider.
Features
- Authorization Code + PKCE (S256) with localhost auto-capture and a paste-the-code fallback
- Device Authorization Grant fallback, auto-selected on headless / SSH / container hosts
- Automatic token refresh near expiry (<30s), persisted via OpenCode's native store
- Public client, no secret stored; zero runtime dependencies (offline / air-gap friendly)
Install (offline / vendored)
Download opencode-keycloak-auth-0.1.0.tgz from the assets below, then:
```bash
npm install ./opencode-keycloak-auth-0.1.0.tgz
```
See the README for the Keycloak client setup and the `opencode.json` provider snippet.
Assets
- `opencode-keycloak-auth-0.1.0.tgz` — prebuilt npm package (ESM `dist/` + type declarations)