Connection OAuth2 helper
@inseam/connection-oauth2 is a factory that turns a small bundle of OAuth2 provider config into a ready-made Connection definition. PKCE auth-code via an inbound callback, refresh-on-expiry inside verify, opaque JSON credential serialization. It exists for the common case; plugins that need behavior outside the standard flow write their own ConnectionDefinition from scratch.
How it fits
Section titled “How it fits”The helper is a convenience layer over the Connection contract, not a base class. There are no extension seams — if you outgrow the helper, copy its single source file (pkgs/connection-oauth2/src/index.ts) as a reference implementation and modify against @inseam/connection-contract directly.
Three injectable adapters keep the helper runtime-agnostic and testable: http (HttpAdapter, defaults to WHATWG fetch), clock, and random (defaults to crypto.getRandomValues). Provider/protocol failures surface as OAuth2Error; OAuth2Error does not extend ConnectionError because the helper is a separate package.
Key pieces
Section titled “Key pieces”oauth2(config)— the only export you call. Returns aConnectionDefinition<OAuth2Credential>implementing the full PKCE auth-code flow, refresh-on-expiry insideverify, and no-opteardown.- PKCE auth-code flow. Generates an S256 challenge from random bytes, allocates a one-shot callback URL via
ctx.inboundHttp.allocateCallback(), yields a singleredirectstep, validatesstateon return, exchangescodeattokenUrl. - Refresh-on-expiry inside
verify. WhenexpiresAtis past and arefreshTokenis present, the helper refreshes and returns the rotated bytes viaVerifyResult.credentialso core persists it atomically. InboundHttpServicerequirement. Ifctx.inboundHttpis missing or unavailable, setup yieldsfailedcleanly — it does not throw.
Exact config and credential shapes: @inseam/connection-oauth2 API · arch/connection/spec.md.
When to use this vs alternatives
Section titled “When to use this vs alternatives”Reach for oauth2(config) when the provider’s flow is standard PKCE auth-code with refresh tokens. Write a ConnectionDefinition directly when you need any of:
- A non-S256 challenge method.
- An
audienceor other custom parameter on the auth or token request. - A non-standard token endpoint shape.
- A custom
teardownthat revokes provider-side state. - API-key or webhook-secret flows that don’t involve a browser redirect at all.
For per-provider polish without leaving the helper, deriveDisplayName(cred) can fetch the account’s email/username from the provider on first connect.
See also
Section titled “See also”- LLM summary — dense reference for agents.
- Connection — the port this helper plugs into.
arch/connection/spec.md— theConnectionDefinitioncontract the helper satisfies.