3.0 KiB
@better-auth/cimd, @better-auth/oauth-provider
| @better-auth/cimd | @better-auth/oauth-provider |
|---|---|
| minor | minor |
Add @better-auth/cimd plugin for Client ID Metadata Document support, and expose a typed clientDiscovery extension point on oauthProvider() so plugins can resolve client_id values from external sources.
@better-auth/cimd (new package)
Install alongside oauthProvider() to let clients identify themselves by hosting an HTTPS metadata document; the URL becomes the client_id. This is the mechanism MCP uses for unauthenticated dynamic client discovery.
import { oauthProvider } from "@better-auth/oauth-provider";
import { cimd } from "@better-auth/cimd";
betterAuth({
plugins: [
oauthProvider({ /* ... */ }),
cimd({
refreshRate: "60m",
allowFetch: (url) => new URL(url).hostname.endsWith(".trusted.example"),
}),
],
});
Ships with §3/§4.1 validation, SSRF protection for private/reserved IPs and cloud metadata endpoints, a 5-second fetch timeout, a 5 KB response size limit (UTF-8 byte-counted), origin binding for redirect URIs, and lifecycle hooks (onClientCreated, onClientRefreshed). Advertises client_id_metadata_document_supported in OAuth/OIDC discovery metadata.
The allowFetch pre-fetch gate lets operators add origin allowlists, per-host rate limits, or DNS-level defenses beyond the built-in IP-literal check.
Admin-controlled fields (disabled, skipConsent, enableEndSession) are preserved across refreshes so admin decisions survive document updates.
@better-auth/oauth-provider: new clientDiscovery option
import type { ClientDiscovery } from "@better-auth/oauth-provider";
oauthProvider({
clientDiscovery: [
{
id: "my-resolver",
matches: (clientId) => clientId.startsWith("custom://"),
resolve: async (ctx, clientId, existing) => {
// create, refresh, or return null to pass through
},
discoveryMetadata: { custom_flow_supported: true },
},
],
});
clientDiscovery accepts a single ClientDiscovery or an array. getClient() walks the entries in order after the database lookup; the first entry whose matches() returns true and whose resolve() returns a non-null client wins. Each entry can also contribute discoveryMetadata fields that are merged into /.well-known/oauth-authorization-server and /.well-known/openid-configuration responses.
Plugins like @better-auth/cimd append an entry here at init time, so multiple discoveries can coexist.
The checkOAuthClient and oauthToSchema helpers are now exported for plugins that create client records directly.
jwks_uri validation now accepts a same-origin URL when the client_id itself is an HTTPS URL, since URL-based discovery flows verify the origin through the client_id itself.
Documentation now recommends removing the oauth-provider configuration allowUnauthenticatedClientRegistration when using CIMD.