/** * Shared OAuth/install `state` signing for web integrations. * * The GitHub, Linear, and Slack OAuth/OIDC flows each round-trip a signed `state` * value * through the third party to bind the callback to the `(orgId, userId)` tenant * that initiated it (CSRF protection + tenant routing). The signer is a system * facility: `MastraFactory` creates ONE signer at boot and hands it to every * registered integration through `IntegrationContext` (see * `./factory-integration.ts`), so all integrations sign and verify with the * same secret. * * Secret resolution happens in the factory, not here: explicit * `config.stateSecret` → the GitHub integration's webhook secret → a * per-process random secret. A random secret is NOT stable across replicas — * a `state` signed by one replica cannot be verified by another — which is * what the `stable` flag reports. The factory fails loud at boot when a * registered integration requires a stable signer but only a random one is * available. * * The wire format (base64url JSON payload + `.` + HMAC-SHA256 base64url * signature) is unchanged from the previous `github/config.ts` implementation * so in-flight OAuth states survive a deploy. */ /** Verified tenant and optional Factory context carried by a signed `state`. */ export interface StateTenant { orgId: string; userId: string; /** Factory that initiated the integration flow, when the caller supplied one. */ factoryProjectId?: string; /** * Per-`state` random value. A signed `state` stays valid for its whole * lifetime, so a flow that must not run twice off one `state` (account * binding, for instance) can key single-use bookkeeping on this. */ nonce: string; } /** Signs and verifies OAuth `state` values bound to a tenant and optional Factory. */ export interface StateSigner { /** Build a signed `state` bound to the tenant and optional initiating Factory. */ sign(orgId: string, userId: string, context?: { factoryProjectId?: string; }): string; /** Verify a signed `state`; returns the bound tenant, or `null` if invalid. */ verify(state: string | undefined): StateTenant | null; /** * True when the signer was built from an explicit deployment-stable secret. * False means a per-process random secret: fine for single-process/local * dev, broken for multi-replica deploys (see module docs). */ readonly stable: boolean; } /** * Create a state signer. With a `secret`, the signer is deployment-stable * (`stable: true`); without one it falls back to a per-process random secret * (`stable: false`). */ export declare function createStateSigner(secret?: string): StateSigner; //# sourceMappingURL=state-signing.d.ts.map