auth/daemon_token_middleware.ts

Daemon token rotation, persistence, and middleware.

Manages the lifecycle of filesystem-resident daemon tokens: writing to disk, rotation on an interval, and HTTP middleware for authentication.

Pure token primitives (schema, generation, validation) live in auth/daemon_token.ts. See docs/identity.md for design rationale.

Declarations
#

9 declarations

view source

create_daemon_token_middleware
#

auth/daemon_token_middleware.ts view source

(state: DaemonTokenState, _deps: QueryDeps): MiddlewareHandler

Create middleware that authenticates via daemon token.

Checks the X-Daemon-Token header. Behavior: - No header: pass through (don't touch existing context). - Header present + Zod-invalid: return 401 (fail-closed). - Header present + invalid value: return 401 (fail-closed, no downgrade). - Header present + valid + keeper_account_id null: return 503. - Header present + valid + ok: set `c.var.auth_account_id = state.keeper_account_id, CREDENTIAL_TYPE_KEY = 'daemon_token'` (overrides any existing session / bearer identity).

Acting-actor resolution + RequestContext construction are deferred to the dispatcher's authorization phase. Multi-actor keeper accounts surface actor_required from there if a daemon caller doesn't pass an explicit acting value.

state

the daemon token runtime state

_deps

returns

MiddlewareHandler

DaemonTokenRotation
#

DaemonTokenRotationOptions
#

auth/daemon_token_middleware.ts view source

DaemonTokenRotationOptions

Options for daemon token rotation.

app_name

Application name (for ~/.{name}/run/daemon_token).

type string

rotation_interval_ms

Rotation interval in ms. Default: 30000 (30s).

type number

DaemonTokenWriteDeps
#

DEFAULT_ROTATION_INTERVAL_MS
#

get_daemon_token_path
#

auth/daemon_token_middleware.ts view source

(runtime: Pick<EnvDeps, "env_get">, name: string): string | null

Get the daemon token file path (~/.{name}/run/daemon_token).

runtime

runtime with env_get capability

type Pick<EnvDeps, "env_get">

name

application name

type string

returns

string | null

path to daemon_token, or null if $HOME is not set

resolve_keeper_account_id
#

auth/daemon_token_middleware.ts view source

(deps: QueryDeps): Promise<string | null>

Resolve the keeper account ID by querying for the account with an active keeper role_grant.

There is exactly one keeper account (the bootstrap account). Runs once at server startup — the result is cached in DaemonTokenState.keeper_account_id. The acting actor is resolved per-request by the dispatcher's authorization phase (which runs resolve_acting_actor against this account id), so multi-actor keeper accounts surface actor_required if a daemon caller doesn't pass an explicit acting.

deps

query dependencies

returns

Promise<string | null>

the keeper account ID, or null if no keeper exists yet (pre-bootstrap)

start_daemon_token_rotation
#

auth/daemon_token_middleware.ts view source

(runtime: Pick<EnvDeps, "env_get"> & Pick<FsWriteDeps, "mkdir" | "write_text_file" | "rename"> & { chmod?: ((path: string, mode: number) => Promise<...>) | undefined; } & FsRemoveDeps, deps: QueryDeps, options: DaemonTokenRotationOptions, log: Logger): Promise<...>

Start daemon token rotation.

Generates an initial token, writes it to disk, resolves the keeper account, and sets up periodic rotation. Returns the mutable state object and a stop function.

runtime

runtime with file, env, and remove capabilities

type Pick<EnvDeps, "env_get"> & Pick<FsWriteDeps, "mkdir" | "write_text_file" | "rename"> & { chmod?: ((path: string, mode: number) => Promise<void>) | undefined; } & FsRemoveDeps

deps

query dependencies for resolving keeper account

options

rotation configuration

log

the logger instance

type Logger

returns

Promise<DaemonTokenRotation>

rotation state and stop function

throws

  • Error - if `$HOME` is not set so the daemon token path cannot be resolved

write_daemon_token
#

auth/daemon_token_middleware.ts view source

(runtime: DaemonTokenWriteDeps, token_path: string, token: string): Promise<void>

Write the current token to disk atomically.

Uses write_file_atomic (temp file + rename) and optionally sets mode 0600.

runtime

runtime with file write capabilities

token_path

path to write the token

type string

token

the raw token string

type string

returns

Promise<void>

Depends on
#

Imported by
#