@fuzdev/fuz_app 0.62.0 → 0.63.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/actions/CLAUDE.md +15 -13
  2. package/dist/actions/action_rpc.d.ts +10 -0
  3. package/dist/actions/action_rpc.d.ts.map +1 -1
  4. package/dist/actions/action_rpc.js +1 -1
  5. package/dist/actions/action_spec.d.ts +1 -1
  6. package/dist/actions/action_spec.js +1 -1
  7. package/dist/actions/perform_action.d.ts.map +1 -1
  8. package/dist/actions/perform_action.js +1 -0
  9. package/dist/auth/CLAUDE.md +45 -24
  10. package/dist/auth/account_action_specs.d.ts +6 -0
  11. package/dist/auth/account_action_specs.d.ts.map +1 -1
  12. package/dist/auth/account_action_specs.js +11 -4
  13. package/dist/auth/account_actions.d.ts.map +1 -1
  14. package/dist/auth/account_actions.js +9 -4
  15. package/dist/auth/account_routes.d.ts.map +1 -1
  16. package/dist/auth/account_routes.js +8 -4
  17. package/dist/auth/account_schema.d.ts +2 -2
  18. package/dist/auth/account_schema.js +2 -2
  19. package/dist/auth/actor_lookup_actions.d.ts +1 -1
  20. package/dist/auth/actor_lookup_actions.js +1 -1
  21. package/dist/auth/actor_lookup_queries.d.ts +1 -1
  22. package/dist/auth/actor_lookup_queries.js +1 -1
  23. package/dist/auth/actor_search_action_specs.d.ts +1 -1
  24. package/dist/auth/actor_search_action_specs.js +1 -1
  25. package/dist/auth/actor_search_actions.d.ts +1 -1
  26. package/dist/auth/actor_search_actions.js +1 -1
  27. package/dist/auth/actor_search_queries.d.ts +1 -1
  28. package/dist/auth/actor_search_queries.js +1 -1
  29. package/dist/auth/all_action_spec_registries.d.ts +2 -2
  30. package/dist/auth/all_action_spec_registries.js +2 -2
  31. package/dist/auth/audit_log_routes.d.ts +1 -1
  32. package/dist/auth/audit_log_routes.js +1 -1
  33. package/dist/auth/audit_log_schema.d.ts +25 -0
  34. package/dist/auth/audit_log_schema.d.ts.map +1 -1
  35. package/dist/auth/audit_log_schema.js +16 -0
  36. package/dist/auth/request_context.d.ts +1 -1
  37. package/dist/env/update_env_variable.js +1 -1
  38. package/dist/http/CLAUDE.md +15 -15
  39. package/dist/testing/CLAUDE.md +28 -44
  40. package/dist/testing/audit_completeness.d.ts.map +1 -1
  41. package/dist/testing/audit_completeness.js +17 -1
  42. package/dist/ui/CLAUDE.md +13 -18
  43. package/dist/ui/keyed_async_slot.svelte.d.ts +1 -1
  44. package/dist/ui/keyed_async_slot.svelte.js +1 -1
  45. package/package.json +1 -1
@@ -12,12 +12,13 @@ server-authoritative dispatch, role-grant-offer UI integration) see
12
12
  ../../docs/usage.md §Deriving Route/Event Specs, §Single JSON-RPC 2.0 Endpoint,
13
13
  §WebSocket Endpoint. For DEV-only output validation semantics see
14
14
  ../../docs/architecture.md §DEV-only Output Validation. For the SAES
15
- binding matrix and middleware ordering see the root `../../CLAUDE.md`
15
+ binding matrix and middleware ordering see the root ../../CLAUDE.md
16
16
  §Action Spec System (SAES) and §Middleware Ordering.
17
17
 
18
18
  IMPORTANT: Every exported Zod schema is paired with a same-named `z.infer`
19
- type export. When adding new schemas, keep the pair invariant it is the
20
- convention callers rely on for type imports.
19
+ type export the convention callers rely on for type imports. When adding
20
+ new schemas, keep the pair invariant (ecosystem-wide rule; see
21
+ Skill(fuz-stack) zod-schemas).
21
22
 
22
23
  NOTE: `ActionRegistry` keeps a few pre-built getters (auth filters,
23
24
  initiator-direction filters) that codegen doesn't consume today — kept
@@ -53,10 +54,10 @@ declarative metadata for consumers (codegen, UI form-state matching, docs)
53
54
  to read off the spec instead of scanning handler code. No runtime
54
55
  enforcement — drift between declared reasons and what handlers actually
55
56
  throw is caught per-module by source-scanning unit tests (see
56
- `../../test/auth/role_grant_offer_actions.error_reasons.test.ts`). Reuses
57
+ ../../test/auth/role*grant_offer_actions.error_reasons.test.ts). Reuses
57
58
  the same `as const` string constants the handler throws (e.g.
58
- `ERROR_ROLE_GRANT_OFFER_*` from `../auth/role_grant_offer_action_specs.ts`,
59
- `ERROR_ROLE_GRANT_NOT_FOUND` from `../http/error_schemas.ts`) so call
59
+ `ERROR_ROLE_GRANT_OFFER*\*`from`auth/role_grant_offer_action_specs.ts`,
60
+ `ERROR_ROLE_GRANT_NOT_FOUND`from`http/error_schemas.ts`) so call
60
61
  sites can import either side. Standard transport errors (validation,
61
62
  auth, rate-limit) stay implicit.
62
63
 
@@ -119,7 +120,7 @@ The remaining asymmetry today is runtime: there is no
119
120
  `Promise<Result<{value}, {error}>>` shape `FrontendActionsApi` methods
120
121
  return. Closing those gaps is on the deferred follow-up set in the
121
122
  [SAES RPC closeout](https://github.com/ryanatkn/grimoire/blob/main/quests/HISTORY.md#saes-rpc-direction-2026-04)
122
- (grimoire `lore/fuz_app/TODO.md` § Future Directions tracks the symmetric
123
+ (grimoire `lore/fuz_app/TODO.md` §Future Directions tracks the symmetric
123
124
  backend signature, backend RPC client, and local-call symmetry items) —
124
125
  wait for a second backend runtime case.
125
126
 
@@ -217,7 +218,7 @@ and `FrontendActionHandlers`.
217
218
  - `generate_action_event_datas(specs, imports, {same_file?, collections_path?, include_protocol_actions?})` — `ActionEventDatas` interface; per-spec variant by kind (`ActionEventRequestResponseData` / `ActionEventRemoteNotificationData` / `ActionEventLocalCallData`). `same_file` (default `true`) is the file-layout switch: when `true`, assumes `ActionInputs` / `ActionOutputs` are in the same module and adds no import (the zzz pattern); when `false`, adds the type imports from `collections_path` (default `'./action_collections.js'`). `collections_path` alone is a no-op — the surprising omit-vs-default behavior of earlier versions has been replaced.
218
219
  - `generate_frontend_actions_api(specs, imports, {interface_name?, method_filter?, collections_path?, sync_returns_value?, include_protocol_actions?})` — emits the typed `FrontendActionsApi` interface (configurable via `interface_name`, default `'FrontendActionsApi'`). One method signature per spec via `generate_actions_api_method_signature`. Protocol actions filtered by default; `method_filter: (spec) => boolean` runs after the protocol-action filter. Renamed from `generate_actions_api` in API review III to make the side-of-the-wire intent visible at every consumer site.
219
220
  - `generate_frontend_action_handlers(specs, imports, {collections_path?, include_protocol_actions?})` — `FrontendActionHandlers` interface (Tier 2 only — wraps `generate_phase_handlers` with `action_event_type: 'TypedActionEvent'`). Pair with `generate_typed_action_event_alias`.
220
- - `generate_backend_actions_api(specs, imports, {interface_name?, spec_array_name?, specs_module?, collections_path?, qualify_spec?, include_protocol_actions?})` — `BackendActionsApi` interface AND `broadcast_action_specs: ReadonlyArray<ActionSpecUnion>` array (both names configurable). Filter: `kind === 'remote_notification' && initiator !== 'frontend'`, with `streams`-target methods (request-scoped progress notifications invoked via `ctx.notify`) excluded — the discriminator is `ActionSpec.streams`, not a manual list. Adds `ActionInputs` (from `collections_path`) + `ActionSpecUnion`, plus `* as specs` from `specs_module` unless `qualify_spec` is set. Method shape today is `(input) => Promise<void>` (matches `create_broadcast_api`'s fire-and-forget runtime); generalizing to per-kind shapes via `generate_actions_api_method_signature` is deferred until a second backend runtime constructor lands (tracked in grimoire `lore/fuz_app/TODO.md` § Future Directions, _Symmetric backend signature shape_).
221
+ - `generate_backend_actions_api(specs, imports, {interface_name?, spec_array_name?, specs_module?, collections_path?, qualify_spec?, include_protocol_actions?})` — `BackendActionsApi` interface AND `broadcast_action_specs: ReadonlyArray<ActionSpecUnion>` array (both names configurable). Filter: `kind === 'remote_notification' && initiator !== 'frontend'`, with `streams`-target methods (request-scoped progress notifications invoked via `ctx.notify`) excluded — the discriminator is `ActionSpec.streams`, not a manual list. Adds `ActionInputs` (from `collections_path`) + `ActionSpecUnion`, plus `* as specs` from `specs_module` unless `qualify_spec` is set. Method shape today is `(input) => Promise<void>` (matches `create_broadcast_api`'s fire-and-forget runtime); generalizing to per-kind shapes via `generate_actions_api_method_signature` is deferred until a second backend runtime constructor lands (tracked in grimoire `lore/fuz_app/TODO.md` §Future Directions, _Symmetric backend signature shape_).
221
222
  - `generate_backend_action_handlers_map(imports, options?)` — emits the `BackendActionHandlers` mapped type (`{[K in BackendRequestResponseMethod]: (input: ActionInputs[K], ctx: BackendHandlerContext) => ActionOutputs[K] | Promise<ActionOutputs[K]>}`). Replaces the hand-maintained `Exclude<>` + parallel mapped-type pattern (zzz had this at `zzz/src/lib/server/zzz_action_handlers.ts:42-66`). Configurable type name, method enum name, and context type name; configurable `collections_path` / `metatypes_path` for the type imports.
222
223
 
223
224
  ### Wrapper + multi-source helper
@@ -319,6 +320,7 @@ interface ActionContext {
319
320
  pending_effects: Array<Promise<void>>; // eager pool writes already in flight — see http/CLAUDE.md §Pending Effects
320
321
  post_commit_effects: Array<() => void | Promise<void>>; // deferred — push via `emit_after_commit`
321
322
  client_ip: string;
323
+ credential_type: CredentialType | null; // session | api_token | daemon_token (or null for anonymous) — same value the credential_types gate consumed
322
324
  log: Logger;
323
325
  notify: (method, params) => void; // HTTP: DEV-mode warn + drop (no streaming channel); WS: socket-scoped
324
326
  signal: AbortSignal; // HTTP: client-disconnect; WS: AbortSignal.any([socket_close, request_cancel])
@@ -458,7 +460,7 @@ Fan-out:
458
460
 
459
461
  - `send(notification)` — broadcasts to every connection (current `send(request)` returns an internal_error "not yet implemented" — backend cannot initiate request-response).
460
462
  - `broadcast_filtered(message, predicate)` — per-connection predicate over `ConnectionIdentity`; skips non-matching. Returns count.
461
- - `send_to_account(account_id, message)` — targeted wrapper over `broadcast_filtered`. Mirrors `close_sockets_for_account` on the send side (every connection for the account). Structurally satisfies the `NotificationSender` interface from `auth/role_grant_offer_notifications.ts` (see `../auth/CLAUDE.md` §WS notifications).
463
+ - `send_to_account(account_id, message)` — targeted wrapper over `broadcast_filtered`. Mirrors `close_sockets_for_account` on the send side (every connection for the account). Structurally satisfies the `NotificationSender` interface from `auth/role_grant_offer_notifications.ts` (see `auth/CLAUDE.md` §WS notifications).
462
464
  - `get_connection_count()` — telemetry counter over the connection map.
463
465
 
464
466
  Return values are bookkeeping, not delivery receipts — `0` means no live
@@ -527,7 +529,7 @@ and optional `required_role: RoleName`. Returns `{transport}`. Note:
527
529
  `required_role` is a **coarse upgrade-time gate** — per-action `auth` in
528
530
  each spec still applies at dispatch time via `perform_action`.
529
531
  (`verify_request_source` and `require_auth` / `require_role` are from
530
- `../auth/`; see `../auth/CLAUDE.md` §Middleware for their semantics.)
532
+ `auth/`; see `auth/CLAUDE.md` §Middleware for their semantics.)
531
533
 
532
534
  ### `register_action_ws` (`register_action_ws.ts`) — lower-level
533
535
 
@@ -584,7 +586,7 @@ Per-message side-effect queues: `pending_effects: Array<Promise<void>>`
584
586
  `flush_post_commit_effects`. Both flush in the same `try/finally` that
585
587
  releases the request controller, so fire-and-forget audit / notification
586
588
  effects pushed by the handler complete (or reject visibly) before the
587
- next message dispatches. See `../http/CLAUDE.md` §Pending Effects.
589
+ next message dispatches. See `http/CLAUDE.md` §Pending Effects.
588
590
 
589
591
  Lifecycle hooks on `RegisterActionWsOptions`:
590
592
 
@@ -950,9 +952,9 @@ wiring (zzz-style reactive Cells observing `ActionEvent` lifecycle)
950
952
  don't have to drop down to manual `create_rpc_client` construction
951
953
  (which forfeits the bundled `api` / `api_result` pair).
952
954
 
953
- `all_standard_action_specs` (in `../auth/standard_action_specs.ts`) is
955
+ `all_standard_action_specs` (in `auth/standard_action_specs.ts`) is
954
956
  the matching aggregate spec list mirroring `create_standard_rpc_actions`
955
- on the backend — see `../auth/CLAUDE.md` §`standard_rpc_actions.ts`.
957
+ on the backend — see `auth/CLAUDE.md` §`standard_rpc_actions.ts`.
956
958
 
957
959
  ## Broadcast API (`broadcast_api.ts`)
958
960
 
@@ -17,6 +17,7 @@ import type { Uuid } from '@fuzdev/fuz_util/id.js';
17
17
  import type { RequestResponseActionSpec } from './action_spec.js';
18
18
  import { type RouteSpec } from '../http/route_spec.js';
19
19
  import { type RequestActorContext, type RequestContext } from '../auth/request_context.js';
20
+ import { type CredentialType } from '../hono_context.js';
20
21
  import type { Db } from '../db/db.js';
21
22
  import { type JsonrpcRequestId } from '../http/jsonrpc.js';
22
23
  import type { RateLimiter } from '../rate_limiter.js';
@@ -72,6 +73,15 @@ export interface ActionContext {
72
73
  * `role_grant_offer_expire` cleanup sweep in `auth/cleanup.ts`).
73
74
  */
74
75
  client_ip: string;
76
+ /**
77
+ * Credential channel the request arrived on (`'session'` | `'api_token'` |
78
+ * `'daemon_token'`), or `null` for anonymous requests. Same value the
79
+ * dispatcher's `credential_types` gate consumed at step 4 — exposed here
80
+ * so handlers can record it in audit metadata (defense in depth: the
81
+ * gate may be loosened or bypassed in a future refactor, but the audit
82
+ * row preserves what actually authenticated the request).
83
+ */
84
+ credential_type: CredentialType | null;
75
85
  /** Logger instance. */
76
86
  log: Logger;
77
87
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"action_rpc.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/action_rpc.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"action_rpc.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/action_rpc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AACpD,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,wBAAwB,CAAC;AAEjD,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAoB,KAAK,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAExE,OAAO,EAEN,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAIN,KAAK,cAAc,EACnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AAEpC,OAAO,EAGN,KAAK,gBAAgB,EAErB,MAAM,oBAAoB,CAAC;AAM5B,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAGpD;;;;;;;;;;GAUG;AACH,MAAM,WAAW,aAAa;IAC7B,+DAA+D;IAC/D,IAAI,EAAE,cAAc,GAAG,IAAI,CAAC;IAC5B,iDAAiD;IACjD,UAAU,EAAE,gBAAgB,CAAC;IAC7B;;;;OAIG;IACH,aAAa,CAAC,EAAE,IAAI,CAAC;IACrB;;;;;OAKG;IACH,EAAE,EAAE,EAAE,CAAC;IACP;;;;;OAKG;IACH,eAAe,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACtC;;;;;OAKG;IACH,mBAAmB,EAAE,KAAK,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACvD;;;;;;;OAOG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;;OAOG;IACH,eAAe,EAAE,cAAc,GAAG,IAAI,CAAC;IACvC,uBAAuB;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;;;OAQG;IACH,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAClD;;;;;OAKG;IACH,MAAM,EAAE,WAAW,CAAC;CACpB;AAED;;;;;GAKG;AACH,MAAM,MAAM,aAAa,CAAC,MAAM,GAAG,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,CACxD,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,aAAa,KACd,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEhC;;;;;;;;;GASG;AACH,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC;IACrE,IAAI,EAAE,cAAc,CAAC;CACrB;AAED;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,CAAC,MAAM,GAAG,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,CAC5D,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,iBAAiB,KAClB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEhC;;;;;;;;GAQG;AACH,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC;IACtE,IAAI,EAAE,mBAAmB,CAAC;CAC1B;AAED;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,CAAC,MAAM,GAAG,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,CAC7D,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,kBAAkB,KACnB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEhC;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,yBAAyB,CAAC;IAChC,OAAO,EAAE,aAAa,CAAC;CACvB;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,cAAc,CAAC,KAAK,SAAS,yBAAyB,IAAI;IACrE,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;CACtB,SAAS,CAAC,UAAU,CAAC,GACnB,kBAAkB,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,GACrE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,GAC9C,iBAAiB,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,GACpE,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAErE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,eAAO,MAAM,UAAU,GAAI,KAAK,SAAS,yBAAyB,EACjE,MAAM,KAAK,EACX,SAAS,cAAc,CAAC,KAAK,CAAC,KAC5B,SAGD,CAAC;AAEH,yCAAyC;AACzC,MAAM,WAAW,wBAAwB;IACxC,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAC1B,2CAA2C;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;OAMG;IACH,sBAAsB,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAC5C;;;;;;;OAOG;IACH,2BAA2B,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;CACjD;AAkBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,eAAO,MAAM,mBAAmB,GAAI,SAAS,wBAAwB,KAAG,KAAK,CAAC,SAAS,CAoMtF,CAAC"}
@@ -16,7 +16,7 @@ import { DEV } from 'esm-env';
16
16
  import {} from '../http/route_spec.js';
17
17
  import { get_client_ip } from '../http/proxy.js';
18
18
  import { get_request_context, } from '../auth/request_context.js';
19
- import { ACCOUNT_ID_KEY, CREDENTIAL_TYPE_KEY, TEST_CONTEXT_PRESET_KEY } from '../hono_context.js';
19
+ import { ACCOUNT_ID_KEY, CREDENTIAL_TYPE_KEY, TEST_CONTEXT_PRESET_KEY, } from '../hono_context.js';
20
20
  import { compile_action_registry } from './compile_action_registry.js';
21
21
  import { JSONRPC_VERSION, JsonrpcRequest, } from '../http/jsonrpc.js';
22
22
  import { jsonrpc_error_messages, jsonrpc_error_code_to_http_status, JSONRPC_ERROR_CODES, } from '../http/jsonrpc_errors.js';
@@ -42,7 +42,7 @@ export declare const ActionSpec: z.ZodObject<{
42
42
  * `null` for `remote_notification` and `local_call` — those don't
43
43
  * dispatch through the request/response auth gate.
44
44
  *
45
- * See `../http/auth_shape.ts` for the design rationale (orthogonal
45
+ * See `http/auth_shape.ts` for the design rationale (orthogonal
46
46
  * authentication / account-resolution / actor-resolution / role-and-
47
47
  * credential authorization axes).
48
48
  */
@@ -25,7 +25,7 @@ export const ActionSpec = z.strictObject({
25
25
  * `null` for `remote_notification` and `local_call` — those don't
26
26
  * dispatch through the request/response auth gate.
27
27
  *
28
- * See `../http/auth_shape.ts` for the design rationale (orthogonal
28
+ * See `http/auth_shape.ts` for the design rationale (orthogonal
29
29
  * authentication / account-resolution / actor-resolution / role-and-
30
30
  * credential authorization axes).
31
31
  */
@@ -1 +1 @@
1
- {"version":3,"file":"perform_action.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/perform_action.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAGH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AACpD,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,wBAAwB,CAAC;AAEjD,OAAO,EAGN,KAAK,cAAc,EACnB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAC,KAAK,cAAc,EAAC,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AAEpC,OAAO,EAEN,KAAK,gBAAgB,EAErB,KAAK,kBAAkB,EACvB,MAAM,oBAAoB,CAAC;AAW5B,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAEpD,OAAO,KAAK,EAA+B,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAE7E;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IAClC,kEAAkE;IAClE,MAAM,EAAE,SAAS,CAAC;IAClB,mGAAmG;IACnG,UAAU,EAAE,OAAO,CAAC;IACpB,sDAAsD;IACtD,UAAU,EAAE,gBAAgB,CAAC;IAC7B,yDAAyD;IACzD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,uEAAuE;IACvE,eAAe,EAAE,cAAc,GAAG,IAAI,CAAC;IACvC,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAC;IAClB,oGAAoG;IACpG,MAAM,EAAE,WAAW,CAAC;IACpB,sFAAsF;IACtF,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAClD,uDAAuD;IACvD,aAAa,CAAC,EAAE,IAAI,CAAC;IACrB;;;;OAIG;IACH,MAAM,CAAC,EAAE;QAAC,eAAe,EAAE,cAAc,GAAG,IAAI,CAAA;KAAC,CAAC;CAClD;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,iBAAiB;IACjC,gGAAgG;IAChG,EAAE,EAAE,EAAE,CAAC;IACP;;;OAGG;IACH,eAAe,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACtC;;;OAGG;IACH,mBAAmB,EAAE,KAAK,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACvD,gDAAgD;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,kEAAkE;IAClE,sBAAsB,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3C,uEAAuE;IACvE,2BAA2B,EAAE,WAAW,GAAG,IAAI,CAAC;CAChD;AAED;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAC5B;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAC,GAC7B;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,kBAAkB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAC,CAAC;AAE9D;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,GAC1B,OAAO,kBAAkB,EACzB,MAAM,iBAAiB,KACrB,OAAO,CAAC,mBAAmB,CAuJ7B,CAAC;AA4EF;;;GAGG;AACH,eAAO,MAAM,iCAAiC,GAC7C,IAAI,gBAAgB,EACpB,QAAQ,mBAAmB,KACzB;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,gBAAgB,CAAA;CAAC,GAAG,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAC,GAAG;IAAC,KAAK,EAAE,kBAAkB,CAAA;CAAC,CAK5F,CAAC"}
1
+ {"version":3,"file":"perform_action.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/perform_action.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAGH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AACpD,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,wBAAwB,CAAC;AAEjD,OAAO,EAGN,KAAK,cAAc,EACnB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAC,KAAK,cAAc,EAAC,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AAEpC,OAAO,EAEN,KAAK,gBAAgB,EAErB,KAAK,kBAAkB,EACvB,MAAM,oBAAoB,CAAC;AAW5B,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAEpD,OAAO,KAAK,EAA+B,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAE7E;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IAClC,kEAAkE;IAClE,MAAM,EAAE,SAAS,CAAC;IAClB,mGAAmG;IACnG,UAAU,EAAE,OAAO,CAAC;IACpB,sDAAsD;IACtD,UAAU,EAAE,gBAAgB,CAAC;IAC7B,yDAAyD;IACzD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,uEAAuE;IACvE,eAAe,EAAE,cAAc,GAAG,IAAI,CAAC;IACvC,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAC;IAClB,oGAAoG;IACpG,MAAM,EAAE,WAAW,CAAC;IACpB,sFAAsF;IACtF,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAClD,uDAAuD;IACvD,aAAa,CAAC,EAAE,IAAI,CAAC;IACrB;;;;OAIG;IACH,MAAM,CAAC,EAAE;QAAC,eAAe,EAAE,cAAc,GAAG,IAAI,CAAA;KAAC,CAAC;CAClD;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,iBAAiB;IACjC,gGAAgG;IAChG,EAAE,EAAE,EAAE,CAAC;IACP;;;OAGG;IACH,eAAe,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACtC;;;OAGG;IACH,mBAAmB,EAAE,KAAK,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACvD,gDAAgD;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,kEAAkE;IAClE,sBAAsB,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3C,uEAAuE;IACvE,2BAA2B,EAAE,WAAW,GAAG,IAAI,CAAC;CAChD;AAED;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAC5B;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAC,GAC7B;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,kBAAkB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAC,CAAC;AAE9D;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,GAC1B,OAAO,kBAAkB,EACzB,MAAM,iBAAiB,KACrB,OAAO,CAAC,mBAAmB,CAwJ7B,CAAC;AA4EF;;;GAGG;AACH,eAAO,MAAM,iCAAiC,GAC7C,IAAI,gBAAgB,EACpB,QAAQ,mBAAmB,KACzB;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,gBAAgB,CAAA;CAAC,GAAG,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAC,GAAG;IAAC,KAAK,EAAE,kBAAkB,CAAA;CAAC,CAK5F,CAAC"}
@@ -144,6 +144,7 @@ export const perform_action = async (input, deps) => {
144
144
  pending_effects,
145
145
  post_commit_effects,
146
146
  client_ip,
147
+ credential_type,
147
148
  log,
148
149
  notify,
149
150
  signal,
@@ -2,16 +2,18 @@
2
2
 
3
3
  > Auth domain: identity, crypto primitives, schema + DDL, queries, middleware, routes, RPC actions, cleanup.
4
4
 
5
- Grouped below by theme. For design rationale and threat
6
- model, see `../../../docs/identity.md` and `../../../docs/security.md`. For the
5
+ Grouped below by theme. For design rationale and threat model, see
6
+ ../../../docs/identity.md and ../../../docs/security.md. For the
7
7
  subsystem's place in server assembly and middleware ordering, see
8
- `../../../docs/architecture.md` and the root `../../../CLAUDE.md`.
8
+ ../../../docs/architecture.md and the root ../../../CLAUDE.md. For
9
+ the workspace-wide DI vocabulary (capabilities / options / runtime
10
+ state), see Skill(fuz-stack) dependency-injection.
9
11
 
10
- The DI vocabulary is the stack standard: stateless capabilities in
11
- `AppDeps` / `RouteFactoryDeps`; static config in `*Options`; runtime state
12
- (e.g. `DaemonTokenState`, mutable `AppSettings` ref, `BootstrapStatus`) is
13
- inline, never in `deps`. All `query_*` functions take `deps: QueryDeps = {db}`
14
- as their first arg.
12
+ Auth-specific instances: stateless capabilities in `AppDeps` /
13
+ `RouteFactoryDeps`; static config in `*Options`; runtime state
14
+ (`DaemonTokenState`, mutable `AppSettings` ref, `BootstrapStatus`) is
15
+ inline, never in `deps`. All `query_*` functions take
16
+ `deps: QueryDeps = {db}` as their first arg.
15
17
 
16
18
  ## Crypto primitives
17
19
 
@@ -789,7 +791,7 @@ Per-call `ctx` shape:
789
791
  - `emit` requires `{pending_effects: Array<Promise<void>>}` — the eager
790
792
  queue only. Both `RouteContext` and `ActionContext` satisfy this
791
793
  structurally; `audit.emit` pushes its in-flight pool-write promise
792
- onto the eager queue. See `../http/CLAUDE.md` §Pending Effects for
794
+ onto the eager queue. See `http/CLAUDE.md` §Pending Effects for
793
795
  the eager / deferred split.
794
796
  - `emit_role_grant_target` adds `client_ip: string` (also on `ActionContext`;
795
797
  REST handlers pass `{pending_effects, client_ip: get_client_ip(c)}`).
@@ -919,7 +921,7 @@ consciously violate the contract.
919
921
 
920
922
  ## Middleware
921
923
 
922
- See the root `../../../CLAUDE.md` §Middleware Ordering for the canonical
924
+ See the root ../../../CLAUDE.md §Middleware Ordering for the canonical
923
925
  assembly order. Two-phase identity:
924
926
 
925
927
  - **Authentication** runs in middleware (session / bearer / daemon
@@ -974,7 +976,7 @@ assembly order. Two-phase identity:
974
976
  actor row was deleted between credential validation and the
975
977
  follow-up read). The named per-error shape `AuthorizationFailureBody`
976
978
  is still exported for callers that want to bind the failure body
977
- by type. See the root `../../../CLAUDE.md` § Cleanest architecture
979
+ by type. See the root ../../../CLAUDE.md §Cleanest architecture
978
980
  takes priority for the rationale.
979
981
 
980
982
  Session parsing is separate from auth enforcement — login / bootstrap
@@ -1141,6 +1143,8 @@ Session-based auth route specs. Factory: `create_account_route_specs(deps, optio
1141
1143
  - `POST /logout` — revokes session by hash, clears cookie.
1142
1144
  - **`POST /password`** — `current_password: PasswordProvided` +
1143
1145
  `new_password: Password`. Per-IP + per-account rate limited.
1146
+ Declares `credential_types: ['session']` (see
1147
+ `docs/security.md` §Credential-channel gating).
1144
1148
  **Revokes all sessions + all API tokens** (force re-auth everywhere);
1145
1149
  clears cookie.
1146
1150
  - **`GET /verify`** — empty-body session-validity probe for nginx
@@ -1212,7 +1216,7 @@ gets `require_auth` when `account === 'required'` or `actor === 'required'`;
1212
1216
  `post_authorization` gets `require_credential_types(types)` when
1213
1217
  `credential_types?.length` and `require_role(roles)` when `roles?.length`.
1214
1218
  Injected into `apply_route_specs` so the generic HTTP framework stays
1215
- auth-agnostic (see `../http/CLAUDE.md` §Validation pipeline for where it plugs in).
1219
+ auth-agnostic (see `http/CLAUDE.md` §Validation pipeline for where it plugs in).
1216
1220
 
1217
1221
  ### `audit_log_routes.ts`
1218
1222
 
@@ -1232,7 +1236,7 @@ module produces is now just the optional SSE stream:
1232
1236
  ## RPC actions (SAES)
1233
1237
 
1234
1238
  Three action surfaces that mount on a consumer's JSON-RPC endpoint via
1235
- `create_rpc_endpoint` (see `../actions/CLAUDE.md` §Single JSON-RPC 2.0 endpoint).
1239
+ `create_rpc_endpoint` (see `actions/CLAUDE.md` §Single JSON-RPC 2.0 endpoint).
1236
1240
  Each surface is split across two files:
1237
1241
 
1238
1242
  - `*_action_specs.ts` — Input/Output Zod schemas (paired with `z.infer` type
@@ -1413,16 +1417,16 @@ Error reason constants (exported as `as const` literals):
1413
1417
  - `ERROR_ROLE_GRANT_OFFER_ACTOR_MISMATCH` (`'role_grant_offer_actor_mismatch'` —
1414
1418
  actor-targeted offer was accepted by an actor other than `to_actor_id`)
1415
1419
 
1416
- Plus re-uses from `../http/error_schemas.ts`: `ERROR_ROLE_GRANT_NOT_FOUND`,
1420
+ Plus re-uses from `http/error_schemas.ts`: `ERROR_ROLE_GRANT_NOT_FOUND`,
1417
1421
  `ERROR_ROLE_NOT_WEB_GRANTABLE`, `ERROR_INSUFFICIENT_PERMISSIONS`,
1418
1422
  `ERROR_ACCOUNT_NOT_FOUND`.
1419
1423
 
1420
1424
  Each spec declares the reason codes its handler may surface (see
1421
- `../actions/CLAUDE.md` §Action specs for the field semantics). Only
1425
+ `actions/CLAUDE.md` §Action specs for the field semantics). Only
1422
1426
  domain reasons returned via `error.data.reason` are listed; standard
1423
1427
  transport errors (validation, auth, rate-limit) stay implicit. Drift
1424
1428
  between declared reasons and handler throws is caught by
1425
- `../../test/auth/role_grant_offer_actions.error_reasons.test.ts`.
1429
+ ../../test/auth/role_grant_offer_actions.error_reasons.test.ts.
1426
1430
 
1427
1431
  Failure-outcome audit events emitted (success and failure rows both carry
1428
1432
  `ip: ctx.client_ip` — uniform with the admin and self-service surfaces):
@@ -1442,8 +1446,8 @@ Failure-outcome audit events emitted (success and failure rows both carry
1442
1446
  role_grant).
1443
1447
 
1444
1448
  WS notifications (post-commit via `emit_after_commit` from
1445
- `../http/pending_effects.js` — swallows exceptions so one failed send
1446
- can't starve others; see `../http/CLAUDE.md` §Pending Effects):
1449
+ `http/pending_effects.js` — swallows exceptions so one failed send
1450
+ can't starve others; see `http/CLAUDE.md` §Pending Effects):
1447
1451
 
1448
1452
  - Create → `role_grant_offer_received` to recipient.
1449
1453
  - Retract → `role_grant_offer_retracted` to recipient.
@@ -1506,7 +1510,7 @@ Pair this with `create_app_server`'s `rpc_endpoints` factory form
1506
1510
  (`(ctx) => Array<RpcEndpointSpec>`) so the combined action list gets
1507
1511
  `ctx.deps` + `ctx.app_settings` — `create_app_server` auto-mounts the
1508
1512
  endpoint via `create_rpc_endpoint`, so consumers don't need to mount it
1509
- again in `create_route_specs`. See `../../../docs/usage.md` §Server
1513
+ again in `create_route_specs`. See ../../../docs/usage.md §Server
1510
1514
  Assembly.
1511
1515
 
1512
1516
  Pre-bundle consumers spread `create_admin_actions` and
@@ -1519,7 +1523,7 @@ consumer wiring the admin surface without account actions will hit
1519
1523
  `method not found` on first admin-suite run.
1520
1524
 
1521
1525
  Frontend mirror: `all_standard_action_specs` (in
1522
- `./standard_action_specs.ts`) bundles `all_admin_action_specs +
1526
+ `auth/standard_action_specs.ts`) bundles `all_admin_action_specs +
1523
1527
  all_role_grant_offer_action_specs + all_account_action_specs` into one
1524
1528
  `ReadonlyArray<RequestResponseActionSpec>` for typed-client codegen
1525
1529
  and `create_frontend_rpc_client({specs})` wiring. Self-service role
@@ -1532,7 +1536,7 @@ spread `all_self_service_role_action_specs` separately when needed.
1532
1536
  fuz-auth action-spec bundle (`admin`, `role_grant_offer`, `account`,
1533
1537
  `self_service_role`, `actor_lookup`, `actor_search`). Not a mounting
1534
1538
  surface; protocol specs are excluded. Iterated by registry-wide
1535
- invariant tests in `../../test/auth/`.
1539
+ invariant tests in ../../test/auth/.
1536
1540
 
1537
1541
  ### `account_action_specs.ts` + `account_actions.ts` — seven self-service RPC actions
1538
1542
 
@@ -1553,6 +1557,18 @@ operations are account-scoped via `query_session_revoke_for_account` /
1553
1557
  or token id returns `revoked: false` rather than revealing whether the id
1554
1558
  exists.
1555
1559
 
1560
+ **Credential-channel gating** — `account_token_create`,
1561
+ `account_token_revoke`, `account_session_revoke`, and
1562
+ `account_session_revoke_all` declare `credential_types: ['session']`
1563
+ on their `auth` axis (same gate as REST `POST /password`).
1564
+ `account_session_revoke` is gated alongside `_revoke_all` because a
1565
+ leaked bearer can otherwise compose `account_session_list` + N×revoke
1566
+ to reach the same lockout. Admin token/session revoke specs in
1567
+ `admin_action_specs.ts` deliberately stay unrestricted (admin
1568
+ scripting from CLI/bearer is legitimate operator workflow). For the
1569
+ threat model, the trust-bar rationale, and the defense-in-depth audit
1570
+ metadata see `docs/security.md` §Credential-channel gating.
1571
+
1556
1572
  | Spec | Side effects | Rate limit | Input | Output |
1557
1573
  | ---------------------------------------- | ------------ | ----------- | -------------- | ----------------------- |
1558
1574
  | `account_verify_action_spec` | false | | `z.void()` | `SessionAccountJson` |
@@ -1577,7 +1593,12 @@ vector, so rate caps are symmetry-only and skipped.
1577
1593
  Audit events emitted (via `deps.audit.emit` with `ip: ctx.client_ip`):
1578
1594
  `session_revoke`, `session_revoke_all`, `token_create`, `token_revoke`. The
1579
1595
  IP is the resolved trusted-proxy value from `ActionContext.client_ip`,
1580
- matching the REST handler convention.
1596
+ matching the REST handler convention. Every gated event additionally
1597
+ records `credential_type` (read from `ActionContext.credential_type`)
1598
+ in metadata — defense in depth so forensics survive if the
1599
+ `credential_types: ['session']` spec gate is ever loosened or bypassed.
1600
+ The REST `password_change` audit row mirrors the same field on all
1601
+ three outcomes (success, wrong-password, concurrent-change).
1581
1602
 
1582
1603
  Deps: `Pick<RouteFactoryDeps, 'log' | 'audit'>`.
1583
1604
  Options: `{max_tokens?: number | null}` — defaults to `DEFAULT_MAX_TOKENS`
@@ -1698,7 +1719,7 @@ One static `request_response` action — `actor_search({query, scope_ids?, limit
1698
1719
  powers person-target pickers. Sibling to `actor_lookup`: that resolves a
1699
1720
  batch of known ids to labels; this resolves a partial name to candidate
1700
1721
  actors. Reuses `ActorLookupEntryJson` from
1701
- `./actor_lookup_action_specs.ts` so the labels arc on the consumer side
1722
+ `auth/actor_lookup_action_specs.ts` so the labels arc on the consumer side
1702
1723
  stays uniform. Default limit `ACTOR_SEARCH_LIMIT_DEFAULT = 20`, hard cap
1703
1724
  `ACTOR_SEARCH_LIMIT_MAX = 50`. Query string capped at
1704
1725
  `ACTOR_SEARCH_QUERY_LENGTH_MAX = 50`.
@@ -1805,5 +1826,5 @@ resulting role_grant.
1805
1826
  Action factories take `Pick<RouteFactoryDeps, 'log' | 'audit'>` directly
1806
1827
  (role-grant-offer adds `notification_sender?` inline).
1807
1828
 
1808
- See root `../../../CLAUDE.md` §AppDeps Vocabulary for the
1829
+ See root ../../../CLAUDE.md §AppDeps Vocabulary for the
1809
1830
  capability / options / runtime-state split across the whole project.
@@ -135,6 +135,7 @@ export declare const account_session_revoke_action_spec: {
135
135
  auth: {
136
136
  account: "required";
137
137
  actor: "none";
138
+ credential_types: string[];
138
139
  };
139
140
  side_effects: true;
140
141
  input: z.ZodObject<{
@@ -154,6 +155,7 @@ export declare const account_session_revoke_all_action_spec: {
154
155
  auth: {
155
156
  account: "required";
156
157
  actor: "none";
158
+ credential_types: string[];
157
159
  };
158
160
  side_effects: true;
159
161
  input: z.ZodVoid;
@@ -165,6 +167,8 @@ export declare const account_session_revoke_all_action_spec: {
165
167
  description: string;
166
168
  };
167
169
  /**
170
+ * `credential_types: ['session']` — see `docs/security.md` §Credential-channel gating.
171
+ *
168
172
  * `rate_limit: 'account'` bounds the burn rate of API-token creates. The
169
173
  * outstanding-token count is already capped by `max_tokens` (via
170
174
  * `query_api_token_enforce_limit`), but the per-account *rate* of churn
@@ -179,6 +183,7 @@ export declare const account_token_create_action_spec: {
179
183
  auth: {
180
184
  account: "required";
181
185
  actor: "none";
186
+ credential_types: string[];
182
187
  };
183
188
  side_effects: true;
184
189
  input: z.ZodPrefault<z.ZodObject<{
@@ -225,6 +230,7 @@ export declare const account_token_revoke_action_spec: {
225
230
  auth: {
226
231
  account: "required";
227
232
  actor: "none";
233
+ credential_types: string[];
228
234
  };
229
235
  side_effects: true;
230
236
  input: z.ZodObject<{
@@ -1 +1 @@
1
- {"version":3,"file":"account_action_specs.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/account_action_specs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"account_action_specs.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/account_action_specs.ts"],"names":[],"mappings":"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"}
@@ -90,22 +90,26 @@ export const account_session_list_action_spec = {
90
90
  async: true,
91
91
  description: 'List auth sessions for the current account.',
92
92
  };
93
+ // `credential_types: ['session']` — see `docs/security.md` §Credential-channel gating.
94
+ // A leaked bearer can otherwise compose `account_session_list` + N×revoke to
95
+ // reach the same effect as `account_session_revoke_all`.
93
96
  export const account_session_revoke_action_spec = {
94
97
  method: 'account_session_revoke',
95
98
  kind: 'request_response',
96
99
  initiator: 'frontend',
97
- auth: { account: 'required', actor: 'none' },
100
+ auth: { account: 'required', actor: 'none', credential_types: ['session'] },
98
101
  side_effects: true,
99
102
  input: SessionRevokeInput,
100
103
  output: SessionRevokeOutput,
101
104
  async: true,
102
105
  description: 'Revoke a single auth session for the current account (IDOR-guarded).',
103
106
  };
107
+ // `credential_types: ['session']` — see `docs/security.md` §Credential-channel gating.
104
108
  export const account_session_revoke_all_action_spec = {
105
109
  method: 'account_session_revoke_all',
106
110
  kind: 'request_response',
107
111
  initiator: 'frontend',
108
- auth: { account: 'required', actor: 'none' },
112
+ auth: { account: 'required', actor: 'none', credential_types: ['session'] },
109
113
  side_effects: true,
110
114
  input: SessionRevokeAllInput,
111
115
  output: SessionRevokeAllOutput,
@@ -113,6 +117,8 @@ export const account_session_revoke_all_action_spec = {
113
117
  description: 'Revoke every auth session for the current account.',
114
118
  };
115
119
  /**
120
+ * `credential_types: ['session']` — see `docs/security.md` §Credential-channel gating.
121
+ *
116
122
  * `rate_limit: 'account'` bounds the burn rate of API-token creates. The
117
123
  * outstanding-token count is already capped by `max_tokens` (via
118
124
  * `query_api_token_enforce_limit`), but the per-account *rate* of churn
@@ -124,7 +130,7 @@ export const account_token_create_action_spec = {
124
130
  method: 'account_token_create',
125
131
  kind: 'request_response',
126
132
  initiator: 'frontend',
127
- auth: { account: 'required', actor: 'none' },
133
+ auth: { account: 'required', actor: 'none', credential_types: ['session'] },
128
134
  side_effects: true,
129
135
  input: TokenCreateInput,
130
136
  output: TokenCreateOutput,
@@ -143,11 +149,12 @@ export const account_token_list_action_spec = {
143
149
  async: true,
144
150
  description: 'List API tokens for the current account. Hashes are never returned.',
145
151
  };
152
+ // `credential_types: ['session']` — see `docs/security.md` §Credential-channel gating.
146
153
  export const account_token_revoke_action_spec = {
147
154
  method: 'account_token_revoke',
148
155
  kind: 'request_response',
149
156
  initiator: 'frontend',
150
- auth: { account: 'required', actor: 'none' },
157
+ auth: { account: 'required', actor: 'none', credential_types: ['session'] },
151
158
  side_effects: true,
152
159
  input: TokenRevokeInput,
153
160
  output: TokenRevokeOutput,
@@ -1 +1 @@
1
- {"version":3,"file":"account_actions.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/account_actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAqC,KAAK,SAAS,EAAC,MAAM,0BAA0B,CAAC;AAe5F,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,WAAW,CAAC;AAwBhD,4CAA4C;AAC5C,MAAM,WAAW,oBAAoB;IACpC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,GAClC,MAAM,IAAI,CAAC,gBAAgB,EAAE,KAAK,GAAG,OAAO,CAAC,EAC7C,UAAS,oBAAyB,KAChC,KAAK,CAAC,SAAS,CAsGjB,CAAC"}
1
+ {"version":3,"file":"account_actions.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/account_actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAqC,KAAK,SAAS,EAAC,MAAM,0BAA0B,CAAC;AAe5F,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,WAAW,CAAC;AAwBhD,4CAA4C;AAC5C,MAAM,WAAW,oBAAoB;IACpC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,GAClC,MAAM,IAAI,CAAC,gBAAgB,EAAE,KAAK,GAAG,OAAO,CAAC,EAC7C,UAAS,oBAAyB,KAChC,KAAK,CAAC,SAAS,CA2GjB,CAAC"}
@@ -54,7 +54,8 @@ export const create_account_actions = (deps, options = {}) => {
54
54
  outcome: revoked ? 'success' : 'failure',
55
55
  account_id: ctx.auth.account.id,
56
56
  ip: ctx.client_ip,
57
- metadata: { session_id: input.session_id },
57
+ // `credential_type` defense in depth — see `docs/security.md` §Credential-channel gating.
58
+ metadata: { session_id: input.session_id, credential_type: ctx.credential_type ?? undefined },
58
59
  });
59
60
  return { ok: true, revoked };
60
61
  };
@@ -64,7 +65,7 @@ export const create_account_actions = (deps, options = {}) => {
64
65
  event_type: 'session_revoke_all',
65
66
  account_id: ctx.auth.account.id,
66
67
  ip: ctx.client_ip,
67
- metadata: { count },
68
+ metadata: { count, credential_type: ctx.credential_type ?? undefined },
68
69
  });
69
70
  return { ok: true, count };
70
71
  };
@@ -78,7 +79,11 @@ export const create_account_actions = (deps, options = {}) => {
78
79
  event_type: 'token_create',
79
80
  account_id: ctx.auth.account.id,
80
81
  ip: ctx.client_ip,
81
- metadata: { token_id: id, name: input.name },
82
+ metadata: {
83
+ token_id: id,
84
+ name: input.name,
85
+ credential_type: ctx.credential_type ?? undefined,
86
+ },
82
87
  });
83
88
  return { ok: true, token, id, name: input.name };
84
89
  };
@@ -93,7 +98,7 @@ export const create_account_actions = (deps, options = {}) => {
93
98
  outcome: revoked ? 'success' : 'failure',
94
99
  account_id: ctx.auth.account.id,
95
100
  ip: ctx.client_ip,
96
- metadata: { token_id: input.token_id },
101
+ metadata: { token_id: input.token_id, credential_type: ctx.credential_type ?? undefined },
97
102
  });
98
103
  return { ok: true, revoked };
99
104
  };
@@ -1 +1 @@
1
- {"version":3,"file":"account_routes.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/account_routes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"account_routes.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/account_routes.ts"],"names":[],"mappings":"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"}
@@ -29,7 +29,7 @@ import { hash_session_token, query_session_revoke_all_for_account, query_session
29
29
  import { query_account_by_username_or_email, query_update_account_password, } from './account_queries.js';
30
30
  import { query_revoke_all_api_tokens_for_account } from './api_token_queries.js';
31
31
  import { build_account_context, build_request_context, get_request_context, require_request_context, resolve_acting_actor, } from './request_context.js';
32
- import { ACCOUNT_ID_KEY } from '../hono_context.js';
32
+ import { ACCOUNT_ID_KEY, CREDENTIAL_TYPE_KEY } from '../hono_context.js';
33
33
  import { get_route_input } from '../http/route_spec.js';
34
34
  import { get_client_ip } from '../http/proxy.js';
35
35
  import { rate_limit_exceeded_response } from '../rate_limiter.js';
@@ -355,7 +355,8 @@ export const create_account_route_specs = (deps, options) => {
355
355
  {
356
356
  method: 'POST',
357
357
  path: '/password',
358
- auth: { account: 'required', actor: 'none' },
358
+ // `credential_types: ['session']` see `docs/security.md` §Credential-channel gating.
359
+ auth: { account: 'required', actor: 'none', credential_types: ['session'] },
359
360
  description: 'Change password (revokes all sessions and API tokens)',
360
361
  input: PasswordChangeInput,
361
362
  output: PasswordChangeOutput,
@@ -376,6 +377,8 @@ export const create_account_route_specs = (deps, options) => {
376
377
  }
377
378
  const ctx = require_request_context(c);
378
379
  const { current_password, new_password } = get_route_input(c);
380
+ // Defense in depth — see `docs/security.md` §Credential-channel gating.
381
+ const credential_type = c.get(CREDENTIAL_TYPE_KEY) ?? undefined;
379
382
  // per-account rate limit check (after context resolution, before argon2 work)
380
383
  if (login_account_rate_limiter) {
381
384
  const check = login_account_rate_limiter.check(ctx.account.id);
@@ -394,6 +397,7 @@ export const create_account_route_specs = (deps, options) => {
394
397
  outcome: 'failure',
395
398
  account_id: ctx.account.id,
396
399
  ip: get_client_ip(c),
400
+ metadata: { credential_type },
397
401
  });
398
402
  return c.json({ error: ERROR_INVALID_CREDENTIALS }, 401);
399
403
  }
@@ -426,7 +430,7 @@ export const create_account_route_specs = (deps, options) => {
426
430
  outcome: 'failure',
427
431
  account_id: ctx.account.id,
428
432
  ip: get_client_ip(c),
429
- metadata: { reason: 'concurrent_change' },
433
+ metadata: { reason: 'concurrent_change', credential_type },
430
434
  });
431
435
  return c.json({ error: ERROR_INVALID_CREDENTIALS }, 401);
432
436
  }
@@ -442,7 +446,7 @@ export const create_account_route_specs = (deps, options) => {
442
446
  event_type: 'password_change',
443
447
  account_id: ctx.account.id,
444
448
  ip: get_client_ip(c),
445
- metadata: { sessions_revoked, tokens_revoked },
449
+ metadata: { sessions_revoked, tokens_revoked, credential_type },
446
450
  });
447
451
  return c.json({ ok: true, sessions_revoked, tokens_revoked });
448
452
  },
@@ -5,9 +5,9 @@
5
5
  * `Account`, `Actor`, `RoleGrant`, `AuthSession`, and `ApiToken`.
6
6
  *
7
7
  * Identifier primitives (`Username`, `UsernameProvided`, `Email`) live
8
- * in `../primitive_schemas.ts` — they're general validator shapes that
8
+ * in `primitive_schemas.ts` — they're general validator shapes that
9
9
  * don't depend on the auth domain. The auth-shape request-contract
10
- * primitive `ActingActor` lives in `../http/auth_shape.ts` next to
10
+ * primitive `ActingActor` lives in `http/auth_shape.ts` next to
11
11
  * `RouteAuth` (the two pair: `auth.actor !== 'none'` ⟺ input declares
12
12
  * `acting?: ActingActor`).
13
13
  *