Add @better-auth/ciba implementing OpenID Connect Client-Initiated
Backchannel Authentication (CIBA) with poll and ping delivery modes.
Uses the oauth-provider extension protocol to register the
urn:openid:params:grant-type:ciba grant type and contribute
backchannel_authentication_endpoint to AS metadata.
Includes agent_claims forwarding, authorization_details propagation,
and OAuth Client Attestation header passthrough to sendNotification.
Open the oauth-provider for plugin-based extension via the Plugin
Extension Protocol.
OAuthProviderExtension contract (5 extension points):
- grantTypes: register custom grant type handlers on the token endpoint
- grantTypeURIs: add to allowlist and grant_types_supported metadata
- metadata: contribute fields to discovery endpoints
- tokenClaims: inject claims into access tokens and ID tokens
- tokenEndpointAuthMethods: advertise additional auth methods
Token endpoint:
- Body schema: z.enum() → z.string().trim().min(1) + .passthrough()
- Switch default: dispatches to extension-contributed grant handlers
- GrantType union widened with (string & {}) for custom URIs
Exported utilities for grant handler authors:
- createUserTokens, checkResource, validateClientCredentials,
basicToClientCredentials, getClient, storeToken, getStoredToken
- Types: GrantTypeHandler, OAuthProviderExtension, TokenClaimInfo
Docs:
- New guide: extending-plugins.mdx (full authoring reference)
- Updated oauth-provider docs with extension points section
- Updated plugin index with Building Plugins section
Introduce the foundational Plugin Extension Protocol — a typed,
declarative mechanism for plugins to extend other plugins.
- BetterAuthExtensionRegistry: empty interface augmented by host
plugins via declare module (parallel to BetterAuthPluginRegistry)
- extensions field on BetterAuthPlugin: typed via registry, gives
compile-time checking and IDE autocomplete for extension contracts
- dependencies field on BetterAuthPlugin: validated at startup,
throws BetterAuthError with descriptive message if missing
- getExtensions(hostId) on AuthContext: collects typed extension
contributions from all plugins targeting a host
- Dependency validation in runPluginInit: fail-fast before any
init runs
- Docs: Plugin Extension Protocol section in concepts/plugins.mdx