agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
76 lines (75 loc) • 3.72 kB
TypeScript
/**
* hosting/signin/cookie — the sign-in cookie comes OFF the headers, and only
* its key goes onward.
*
* The law (rule 10, "secrets never travel"): a handler never sees the sign-in
* cookie. The transport strips it from the headers it hands onward
* (`HostRequest.headers`, `HostConversation.headers`) and passes the sign-in
* KEY instead — the value's SHA-256, which the store is keyed by and which
* cannot be turned back into a cookie. One consumer that logs its headers would
* otherwise publish an 8-hour credential.
*
* `readSignIn` is that stripping, exported for doors that read raw Node
* headers themselves (an app's own routes beside the host). `withoutCredentials`
* is the other half: every credential-bearing header removed, for anything that
* logs.
*/
/** Header bags this module reads: a Node `IncomingMessage['headers']` or a flat record. */
export type HeaderBag = Readonly<Record<string, string | readonly string[] | undefined>>;
/** What {@link readSignIn} found. */
export interface SignInRead {
/**
* The sign-in key (SHA-256 of the cookie's value, base64url), or absent when
* the request carried no sign-in cookie — or carried TWO. Two cookies of the
* one name name nobody: which one a browser sent first is not a fact this
* door can rely on, so neither is read.
*/
readonly key?: string;
/**
* The headers, names lower-cased, WITHOUT the sign-in cookie or any sign-in
* attempt's transaction cookie (`<name>-tx-*`). Other cookies are kept.
*/
readonly headers: Record<string, string>;
}
/** SHA-256 of a cookie value, base64url — the only form a sign-in is keyed or passed by. */
export declare function signInKeyOf(cookieValue: string): string;
/**
* Take the sign-in cookie off a header bag. Returns the key and the headers
* without the cookie; everything else is left exactly as it was (names
* lower-cased, repeated values joined the way the hosts join them).
*
* @example
* const { key, headers } = readSignIn(req.headers);
* const who = key === undefined ? undefined : await signIns.identify(key);
* log.info({ path: req.url, headers: withoutCredentials(headers) });
*/
export declare function readSignIn(headers: HeaderBag, cookieName?: string): SignInRead;
/**
* The headers minus every one that carries a credential — for a log line, an
* error report, anything that leaves the process. Removes `cookie` and
* `authorization` whole (any cookie may be a credential), every header in
* {@link CREDENTIAL_HEADERS}, and any header named in `also` — pass the
* deployment's own `tokenHeader` there. Names are compared lower-cased.
*/
export declare function withoutCredentials(headers: HeaderBag, options?: {
readonly also?: readonly string[];
}): Record<string, string>;
/**
* Every header name {@link withoutCredentials} removes:
*
* - the standard ones: `authorization`, `proxy-authorization`, `cookie`,
* `set-cookie`;
* - `sec-websocket-protocol`, where a browser dialect carries a bearer token
* (a browser's WebSocket cannot set `authorization`);
* - what authenticating proxies forward a signed token or identity in:
* `x-forwarded-access-token`, `x-auth-request-access-token`,
* `x-pomerium-jwt-assertion`, `x-amzn-oidc-accesstoken`, `x-amzn-oidc-data`,
* `x-amzn-oidc-identity`, `x-goog-iap-jwt-assertion`, `cf-access-jwt-assertion`,
* `x-ms-token-aad-access-token`, `x-ms-token-aad-id-token`,
* `x-ms-token-aad-refresh-token`, `x-ms-client-principal`;
* - `x-api-key`.
*
* A header this list does not know (a custom token header) is removed only
* when named in `also`.
*/
export declare const CREDENTIAL_HEADERS: readonly string[];