UNPKG

agentfootprint

Version:

The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.

103 lines (102 loc) • 5.53 kB
/** * oidcSignIn — browser sign-in for the `oidc-token` strategy: the OpenID * Connect authorization-code flow, through `openid-client`. * * **Pending independent review.** The sign-in door is where the classic * sign-in bugs live; the owner gates the release of this piece on an outside * human security review (design Q5). It is built and tested; it is not yet * cleared for a company install. * * Pattern: Adapter over `openid-client` (an OpenID-certified relying party by * the author of `jose`), behind the door's {@link RedirectSignIn} * port. Optional peer, loaded lazily — the `jose` precedent. * Role: the protocol half. The sign-in door owns the cookies, `returnTo` * and the callback order; this file builds the authorization URL and * turns a callback into a person. * * ── One verification path (design §5.3, Q1) ──────────────────────────────── * The callback does NOT read the person out of the ID token. The same code * exchange returns an ACCESS token for this API, and the strategy's own * `verify` — the person test included — reads the person out of that. So a * person signing in through the browser and the same person calling with a * bearer token get the same `userId` by construction. The ID token only binds * the login to this browser (`nonce`) and is then dropped; nothing is stored. * * ── What `openid-client` checks, and what this file adds ─────────────────── * `openid-client` checks `state`, the code exchange (client authentication + * PKCE verifier), and the ID token (signature, `iss`, `aud` = the client id, * `nonce`, `exp`, the clock tolerance). This file requires an ID token in every * token response (with PKCE off the nonce is the only defence against an * injected code), then runs `verify` on the access token. * * ── Client authentication ─────────────────────────────────────────────────── * A private key (`private_key_jwt`, RFC 7523) is preferred: nothing shared * leaves the server. A client secret (`client_secret_basic`) is accepted — * design §5.2: "a secret file is accepted". Exactly one of the two. */ import { type RedirectSignIn } from '../../hosting/signin/types.js'; import type { OidcIdentity } from './oidc.js'; /** * The slice of `openid-client` v6 this adapter uses, declared structurally so * the optional peer is never a hard type dependency. */ export interface OpenIdClientBackend { Configuration: new (server: Record<string, unknown>, clientId: string, metadata?: Record<string, unknown>, clientAuthentication?: unknown) => unknown; buildAuthorizationUrl(config: unknown, parameters: Record<string, string>): URL; authorizationCodeGrant(config: unknown, currentUrl: URL, checks: Record<string, unknown>): Promise<{ access_token?: string; id_token?: string; }>; buildEndSessionUrl(config: unknown, parameters: Record<string, string>): URL; calculatePKCECodeChallenge(verifier: string): Promise<string>; PrivateKeyJwt(key: unknown): unknown; ClientSecretBasic(secret: string): unknown; allowInsecureRequests(config: unknown): void; readonly clockTolerance: symbol; } /** How the client authenticates at the token endpoint. */ export type OidcClientCredential = { readonly kind: 'private-key'; readonly pem: string; } | { readonly kind: 'secret'; readonly secret: string; }; export interface OidcSignInOptions { /** The strategy's own verifier — its `verify` reads the person from the access token. */ readonly verifier: OidcIdentity; /** The browser client's id at the IdP (never the API's audience). */ readonly clientId: string; readonly credential: OidcClientCredential; /** OAuth scopes to request; must include `openid` and this API's scope. */ readonly scope: string; /** AD FS: the Web API identifier, sent as `resource` (else AD FS issues for userinfo). */ readonly resource?: string; /** PKCE on (`'required'`, default) or off (`'off'`: AD FS 2016). */ readonly pkce?: 'required' | 'off'; /** A claim of the ACCESS token that carries the display name. */ readonly displayNameClaim?: string; /** Seconds of clock skew for the ID token. Default 60. */ readonly clockToleranceSeconds?: number; /** Accept `http` endpoints on a loopback host (development only). */ readonly allowLoopbackHttp?: boolean; /** An already-imported `openid-client`. */ readonly backend?: OpenIdClientBackend; } /** Raised when browser sign-in is configured and `openid-client` is not installed. */ export declare class MissingOpenIdClientError extends Error { readonly code: "ERR_MISSING_OPENID_CLIENT"; constructor(); } /** * A browser sign-in setting that can never work, found by `ready()` at boot — * `setting` names which: the client key (not RSA / EC P-256, or unreadable) * or the IdP's discovery document (no authorization or token endpoint, or * PKCE required and `S256` not offered). */ export declare class OidcSignInSetupError extends Error { readonly code: "ERR_OIDC_SIGN_IN_SETUP"; readonly setting: 'client-key' | 'discovery'; constructor(setting: 'client-key' | 'discovery', sentence: string); } export declare function oidcSignIn(options: OidcSignInOptions): RedirectSignIn;