API / @aihu/auth

@aihu/auth

Agents & governance

JWT scope checks, ScopeSignal, and server middleware for aihu auth.

version
3.0.0
exports
25
values
15
types
10
01

clearCurrentScopes

functionagent
function clearCurrentScopes(): void

Reset both user and scope signals to `null` / `[]`.

02

createAuthPlugin

functionagent
function createAuthPlugin(options?: AuthPluginOptions): AuthPlugin

Create an `AuthPlugin` compatible with `@aihu/agent-service`.

03

createScopeSignal

functionagent
function createScopeSignal(): ScopeSignalHandle

Create a `ScopeSignalHandle` that exposes `setScopes`, `clearScopes`, and `hasScope` — wired to the module-level singleton signal.

04

decodeJwt

functionagent
function decodeJwt(jwt: string): JwtClaims | null

Decode the payload segment of a JWT without verifying its signature.

05

getAuthState

functionagent
async 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`.

06

getScopeSignal

functionagent
function getScopeSignal(scope: string): () => boolean

Return a reactive getter function that evaluates to `true` when `scope` is present in the current scope list.

07

hasScope

functionagent
function hasScope(claims: JwtClaims, scope: string): boolean

Return `true` when `claims` contains `scope` in any of the three standard scope claim formats: 1.

08

requireAuth

functionagent
function requireAuth(options?: AuthMiddlewareOptions): Middleware

Middleware that rejects requests without any JWT in the configured header.

09

requireScope

functionagent
function requireScope(scope: string, options?: AuthMiddlewareOptions): Middleware

Middleware that rejects requests where the JWT does not carry the required scope claim.

10

setCurrentScopes

functionagent
function setCurrentScopes(scopes: string[]): void

Update the active scope list on both the user signal and the module-level scope-signal singleton (used by `<guard>` lowering via `getScopeSignal`).

11

signIn

functionagent
async function signIn(token: string, signInPath = '/auth/sign-in'): Promise<User>

Client-side sign-in.

12

signOut

functionagent
async function signOut(signOutPath = '/auth/sign-out'): Promise<void>

Client-side sign-out.

13

useCurrentUser

functionagent
function useCurrentUser(): () => User | null

Return a reactive getter for the currently signed-in `User`.

14

verifyJwt

functionagent
async function verifyJwt( token: string, secret: string, options?: VerifyJwtOptions, ): Promise<Record<string, unknown> | null>
15

AuthError

classagent
class AuthError extends Error

Custom error class for auth operation failures.

16

AuthConfig

interfaceagent
interface 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`.

17

AuthMiddlewareOptions

interfaceagent
interface 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
}
18

AuthPluginOptions

interfaceagent
interface 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
}
19

AuthState

interfaceagent
interface AuthState {
  readonly user: User | null
  readonly scopes: string[]
}

Result of `getAuthState`.

20

JwtClaims

interfaceagent
interface 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.

21

RouteHandlers

interfaceagent
interface RouteHandlers {
  readonly signIn: RouteHandler
  readonly signOut: RouteHandler
  readonly refresh: RouteHandler
}

The three `RouteHandler` objects returned by `createAuthRoutes`.

22

ScopeSignalHandle

interfaceagent
interface 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
}
23

User

interfaceagent
interface User {
  readonly id: string
  readonly email?: string
  readonly scopes: string[]
}

Authenticated user record.

24

VerifyJwtOptions

interfaceagent
interface 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`.

25

RequestContext

typeagent
type RequestContext = Request

Minimal request context passed to `getAuthState`.