JWT scope checks, ScopeSignal, and server middleware for aihu auth.
clearCurrentScopesfunction clearCurrentScopes(): voidReset both user and scope signals to `null` / `[]`.
createAuthPluginfunction createAuthPlugin(options?: AuthPluginOptions): AuthPluginCreate an `AuthPlugin` compatible with `@aihu/agent-service`.
createScopeSignalfunction createScopeSignal(): ScopeSignalHandleCreate a `ScopeSignalHandle` that exposes `setScopes`, `clearScopes`, and `hasScope` — wired to the module-level singleton signal.
decodeJwtfunction decodeJwt(jwt: string): JwtClaims | nullDecode the payload segment of a JWT without verifying its signature.
getAuthStateasync function getAuthState(ctx: RequestContext, config: AuthConfig): Promise<AuthState>Read the session JWT from the request cookie, verify it with `jwtSecret`, and return the current `AuthState`.
getScopeSignalfunction getScopeSignal(scope: string): () => booleanReturn a reactive getter function that evaluates to `true` when `scope` is present in the current scope list.
hasScopefunction hasScope(claims: JwtClaims, scope: string): booleanReturn `true` when `claims` contains `scope` in any of the three standard scope claim formats: 1.
requireAuthfunction requireAuth(options?: AuthMiddlewareOptions): MiddlewareMiddleware that rejects requests without any JWT in the configured header.
requireScopefunction requireScope(scope: string, options?: AuthMiddlewareOptions): MiddlewareMiddleware that rejects requests where the JWT does not carry the required scope claim.
setCurrentScopesfunction setCurrentScopes(scopes: string[]): voidUpdate the active scope list on both the user signal and the module-level scope-signal singleton (used by `<guard>` lowering via `getScopeSignal`).
signInasync function signIn(token: string, signInPath = '/auth/sign-in'): Promise<User>Client-side sign-in.
signOutasync function signOut(signOutPath = '/auth/sign-out'): Promise<void>Client-side sign-out.
useCurrentUserfunction useCurrentUser(): () => User | nullReturn a reactive getter for the currently signed-in `User`.
verifyJwtasync function verifyJwt( token: string, secret: string, options?: VerifyJwtOptions, ): Promise<Record<string, unknown> | null>AuthErrorclass AuthError extends ErrorCustom error class for auth operation failures.
AuthConfiginterface AuthConfig {
/**
* HMAC-SHA-256 secret used to VERIFY session JWTs. aihu does not sign or
* issue tokens today — tokens come from your identity provider, signed
* with this shared secret. (Issuance lands in the GX issuance phase.)
*/
readonly jwtSecret: string
/** Path for the sign-in endpoint. Default: `/auth/sign-in`. */
readonly signInPath?: string
/** Path for the sign-out endpoint. Default: `/auth/sign-out`. */
readonly signOutPath?: string
/** Path for the token-refresh endpoint. Default: `/auth/refresh`. */
readonly refreshPath?: string
/** Cookie name that stores the session JWT. Default: `aihu_session`. */
readonly cookieName?: string
/** Cookie max-age in seconds. Default: `86400` (24 hours). */
readonly maxAge?: number
/**
* Accept session JWTs that carry no `exp` claim. Default `false` —
* `getAuthState` rejects non-expiring tokens (see `VerifyJwtOptions`).
*/
readonly allowNoExpiry?: boolean
/**
* Expected `aud` for session JWTs. When set, tokens whose `aud` claim does
* not include this value are rejected. When unset, `aud` is not checked.
*/
readonly audience?: string
/** Clock-skew leeway in seconds for `exp`/`nbf` validation. Default 60. */
readonly clockSkewSec?: number
}Configuration for the `auth()` plugin factory and for `createAuthRoutes`.
AuthMiddlewareOptionsinterface AuthMiddlewareOptions {
/**
* The HTTP header to read the JWT from.
* Defaults to `'Authorization'` (expects `Bearer <token>` format).
*/
header?: string
/**
* Custom JWT extractor. When provided, `header` is ignored.
* Return `null` to signal "no token present".
*/
extractJwt?: (req: Request) => string | null
}AuthPluginOptionsinterface AuthPluginOptions {
/**
* Override the JWT decode function (useful for testing or when you need
* to inject claims from a pre-verified token). Defaults to `decodeJwt`.
*/
decodeJwt?: (jwt: string) => JwtClaims | null
}AuthStateinterface AuthState {
readonly user: User | null
readonly scopes: string[]
}Result of `getAuthState`.
JwtClaimsinterface JwtClaims {
sub?: string
/** Space-separated scope string (RFC 6749 §3.3). */
scope?: string
/** Array-form scopes (Auth0 convention). */
scp?: string[]
/** Array-form scopes (Okta convention). */
scopes?: string[]
[key: string]: unknown
}`@aihu/auth` — lightweight JWT decoder.
RouteHandlersinterface RouteHandlers {
readonly signIn: RouteHandler
readonly signOut: RouteHandler
readonly refresh: RouteHandler
}The three `RouteHandler` objects returned by `createAuthRoutes`.
ScopeSignalHandleinterface ScopeSignalHandle {
/** Reactive getter — returns true when `scope` is active. */
readonly hasScope: (scope: string) => boolean
/** Set the current authenticated scopes (call after login). */
setScopes(scopes: string[]): void
/** Clear all scopes (call after logout). */
clearScopes(): void
}Userinterface User {
readonly id: string
readonly email?: string
readonly scopes: string[]
}Authenticated user record.
VerifyJwtOptionsinterface VerifyJwtOptions {
/**
* Accept tokens that carry no `exp` claim. Default **false**: a token
* without an expiry never stops being replayable, which is not acceptable
* for a verified principal. Opt in only for machine credentials that have
* an external revocation story.
*/
readonly allowNoExpiry?: boolean
/**
* Expected audience. When set, the token's `aud` claim (string or array
* of strings, per RFC 7519 §4.1.3) must include this value or the token
* is rejected. When unset, `aud` is not checked.
*/
readonly audience?: string
/**
* Clock-skew leeway in seconds applied to `exp` / `nbf` / `iat`.
* Default {@link DEFAULT_CLOCK_SKEW_SEC} (60).
*/
readonly clockSkewSec?: number
/**
* Clock override returning milliseconds since epoch (same contract as
* `Date.now`). Default `Date.now`. Exists so tests can pin the clock.
*/
readonly now?: () => number
}Registered-claim validation options for `verifyJwt`.
RequestContexttype RequestContext = RequestMinimal request context passed to `getAuthState`.