Releases: HarperFast/oauth
Release list
v2.2.1
Docs-only patch — refreshes the README (and therefore the npm package page), which predated 2.2.0's MCP features.
- Documented headless-agent (machine-to-machine) authentication —
client_credentials+ RFC 7523private_key_jwt, CIMD-first client resolution — in the MCP section. - Added the CIMD default-on security caveat (
mcp.clientIdMetadataDocuments.enabled: false/allowedHoststo control). - Corrected the Database Schema section to the actual table set (see
schema/oauth.graphql). - Retired the closed #86 forward-work pointer in favor of #156.
- Linked the changelog.
No source changes.
v2.2.0
Minor release — headless-agent (machine-to-machine) MCP authentication, plus signing-key rotation.
- Signing-key rotation + multi-key JWKS publication (#158, closes #128). Rotate the MCP signing key without invalidating in-flight tokens; the JWKS publishes current + retiring keys.
- Client-assertion primitives (#165): strict RFC 7523
private_key_jwtverification — EdDSA/Ed25519 via built-innode:crypto(no new dependency),jtireplay store, ≤60sexpwindow. - Client ID Metadata Documents (CIMD) (#167): URL-shaped
client_ids are resolved by fetching the client's metadata document through an SSRF-guarded, pinned-connection fetch, with a consent interstitial for interactive flows.⚠️ Default-on whenmcp.enabled— URL client_ids are now accepted. Disable withmcp.clientIdMetadataDocuments.enabled: false, or restrict withmcp.clientIdMetadataDocuments.allowedHosts.⚠️ Interactive CIMD authorization requires browser cookies (a per-flow__Host-consent cookie binds the interstitial).
client_credentialsgrant (#170, closes #161/#162): headless agents authenticate as themselves withprivate_key_jwt— no browser, no human. CIMD-first client resolution; short-TTL audience-bound tokens; every issuance audit-logged.- Rate limiting (#171, closes #163): token issuance is limited per verified
client_id(mcp.clientCredentials.rateLimit, default 30 req/min,false/0disables — debited post-authentication so unauthenticated requests can't drain a client's quota), and CIMD document fetches are limited at a fixed 10 attempts/min per URL. Over-limit responses are429slow_downwithRetry-After. - Fix: client records use Harper's
@createdTimeinstead of a hand-rolledcreated_at(#169).
Also new: CHANGELOG.md — backfilled for all prior releases and shipped in the npm tarball from this release on.
MCP OAuth remains experimental / opt-in (mcp.enabled).
v2.1.2
Patch release — MCP OAuth hardening batch. All fixes, no features.
- Validate
mcp.issueris a full http(s) origin at config load (#139). Fail-fast on schemeless / path / query / fragment / credential-bearing values. Only enforced whenmcp.enabledis true.⚠️ A deployment withmcp.enabled: trueand a malformedmcp.issuerthat previously started (with broken discovery/endpoint URLs) now refuses to start, with an error naming the bad value.
- Secret redaction hardening (#140). Snake_case/kebab secret keys (
signing_key_pem,initial_access_token,private_key, …) are now redacted from option logging; thepluginDefaultsdebug log is redacted too; non-plain objects pass through redaction unmangled. - Non-Error catch safety (#142, #147). All remaining
(error as Error).messagecatch sites are now safe against thrown strings/null; the wrapped ID-token verification error chains the original viacause.
v2.1.1
Patch release.
- RFC 9207 — emit the
issparameter on all MCP OAuth authorization responses (success + error redirects) and advertiseauthorization_response_iss_parameter_supported: truein the AS metadata (#150, closes #149). Mitigates OAuth mix-up attacks; additive and backward-compatible.
MCP OAuth remains experimental / opt-in (mcp.enabled).
v2.0.0
First GA of the Harper v5 line.
Breaking
Requires Harper v5 — peerDependencies: harper >=5.0.0 (the harperdb v4 → harper v5 package move). Harper v4 users stay on the 1.x line: npm install @harperfast/oauth@1.
Highlights
- Harper v5 support.
- MCP OAuth (experimental, opt-in via
mcp.enabled) — RFC 7591 Dynamic Client Registration, discovery metadata (/.well-known/*),/oauth/mcp/authorize(PKCE-S256), and/oauth/mcp/token(audience-bound RS256 JWT issuance). Token verification (withMCPAuth) and the rest land additively in 2.0.x. - Mature human-OAuth core — multi-provider (GitHub, Google, Azure AD, Auth0, Okta, custom OIDC), automatic token refresh, lifecycle hooks, CSRF protection, multi-tenant SSO.
Publishing this release runs release.yml → npm publish → @harperfast/oauth@2.0.0 on the npm latest tag (moves latest from 1.5.0 → 2.0.0).
v1.5.0
Changed
- Dynamic-provider cache now defaults to a bounded 300s TTL instead of caching forever. Providers resolved via the
onResolveProviderhook are re-resolved once their cache entry expires, so a config change (disabled provider, rotated credentials) takes effect within one TTL window instead of persisting until restart. Configure withcacheDynamicProviders: seconds (number),falseto disable caching (call the hook every request), ortruefor the previous cache-forever behavior. Freshness is TTL-only — there is no manual invalidation API.
Docs
- Documented the dynamic-provider caching model, including
cacheDynamicProviders: falseto disable the plugin cache and cache at youronResolveProviderlookup layer instead.
v1.2.1
- Fix: Disambiguated session OAuth fields — added
providerConfigIdandproviderTypealongside existingproviderto clarify config key vs provider type (#26) - Fix: Provider errors (e.g. GitHub 500 HTML pages) no longer leak raw response bodies to the browser — callback redirects with
?error=auth_failed&reason=token_exchangeinstead - Security: Open redirect prevention on all callback redirect paths (error and success) via
sanitizeRedirect() - Security: Error reason codes in redirect URLs use safe constants instead of raw error messages
- Fix: Response bodies drained in error paths to prevent undici socket/connection pool leaks
- Fix: Error redirect URLs correctly place query params before hash fragments via
buildErrorRedirect()helper - Fix: JSON parse failures in token exchange/refresh fall back gracefully to status code instead of crashing