UNPKG

agentfootprint

Version:

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

81 lines • 3.81 kB
/** * verify/discovery — read an issuer's OpenID discovery document, and say which * of three things happened. * * The classification is the point (rule 9: config errors refuse at boot, * outages answer 503). A mistyped issuer path that answers 404 is REACHABLE BUT * WRONG; calling it an outage would turn a typo into a permanent 503 that * nobody is ever told to fix. So: * * • `outage` — a network error, a timeout, or a 5xx. The IdP may come back. * • `misconfigured` — any other non-2xx (a redirect included: it is never * followed), a body that is not a JSON object, a * document with no `issuer` or no `jwks_uri`, an `issuer` that is not the * configured one (compared exactly — OpenID Connect Discovery §4.3), or a * key-set URL that is not `https`. The configuration names the wrong thing. * • `ready` — a document that passed every check above. * * `access_token_issuer` (AD FS) is read from a `ready` document only. AD FS * signs access tokens with `iss` = `http://<host>/adfs/services/trust` while * its discovery `issuer` is `https://<host>/adfs`; a verifier pinned to the * second refuses every AD FS access token. That value is COMPARED, never * fetched, so the https rule does not apply to it. * * Nothing here throws: the three outcomes are values, and the caller decides * what each means at boot and at request time. */ /** The checked facts a verifier needs out of the document. */ export interface DiscoveredIssuer { /** The document's `issuer` — equal to the configured one by construction. */ readonly issuer: string; /** Where the signing keys are. */ readonly jwksUri: string; /** AD FS's second issuer for access tokens, when the document names one. */ readonly accessTokenIssuer?: string; /** Where a browser is sent to sign in — browser sign-in needs it. */ readonly authorizationEndpoint?: string; /** Where the code is exchanged — browser sign-in needs it. */ readonly tokenEndpoint?: string; /** RP-Initiated Logout, when the IdP offers it. */ readonly endSessionEndpoint?: string; /** RFC 9207: the IdP puts `iss` on every authorization response — then it is REQUIRED on the callback. */ readonly issParameterSupported?: boolean; /** The PKCE methods the IdP names, when it names them. */ readonly codeChallengeMethods?: readonly string[]; } export type DiscoveryOutcome = { readonly kind: 'ready'; readonly issuer: DiscoveredIssuer; } | { readonly kind: 'outage'; readonly reason: string; } | { readonly kind: 'misconfigured'; readonly check: string; }; /** The one fetch this module makes — injectable, so tests need no socket. */ export type DiscoveryFetch = (url: string, init: { signal: AbortSignal; headers: Record<string, string>; redirect: 'manual'; }) => Promise<{ status: number; text(): Promise<string>; }>; export interface ReadDiscoveryOptions { readonly fetch: DiscoveryFetch; readonly timeoutMs: number; /** Plain `http` on a loopback host is accepted (development only). */ readonly allowLoopbackHttp: boolean; } /** `<issuer>/.well-known/openid-configuration`, a trailing `/` removed first. */ export declare function discoveryUrlFor(issuer: string): string; /** * Why `raw` is not a URL this library may fetch a credential-bearing answer * from — or `undefined` when it is. `https`, or `http` on a loopback host when * the caller allows it. */ export declare function fetchableUrlProblem(raw: string, allowLoopbackHttp: boolean): string | undefined; /** Fetch and classify. Never throws. */ export declare function readDiscovery(configuredIssuer: string, options: ReadDiscoveryOptions): Promise<DiscoveryOutcome>; //# sourceMappingURL=discovery.d.ts.map