@forgezero/access 0.1.4 → 0.1.6

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.
package/README.md CHANGED
@@ -35,21 +35,21 @@ Every row links to the detailed explanation and named-import/example area below.
35
35
 
36
36
  | public entry | short description | runtime | details |
37
37
  |---|---|---|---|
38
- | @forgezero/access | Declare routes, factors and policies as orthogonal lists; authorise against them. | portable | [Details + example](#forgezero-access) |
39
- | @forgezero/access/conditions | The twelve guards every project writes into `before`, each with the status its refusal deserves. | portable | [Details + example](#forgezero-access-conditions) |
40
- | @forgezero/access/effects | Audit, emit, meter, invalidate and notify — what happens after a request is decided, never failing it. | portable | [Details + example](#forgezero-access-effects) |
41
- | @forgezero/access/security | Constant-time comparison, CSPRNG tokens, HMAC, HKDF, AES-GCM sealing and redaction. Web Crypto only. | portable | [Details + example](#forgezero-access-security) |
42
- | @forgezero/access/rate-limit | Request counters over a window — in memory, in Redis, or in a Durable Object. | portable | [Details + example](#forgezero-access-rate-limit) |
43
- | @forgezero/access/fetch | A Fetch-native adapter over the declared access pipeline. | portable | [Details + example](#forgezero-access-fetch) |
44
- | @forgezero/access/pipeline | The framework-neutral route, principal, factor, policy, rate-limit and effects pipeline. | portable | [Details + example](#forgezero-access-pipeline) |
45
- | @forgezero/access/elysia | Elysia integration over the same access pipeline and route declarations. | portable | [Details + example](#forgezero-access-elysia) |
46
- | @forgezero/access/client | Typed client helpers that fulfil factors without duplicating the security matrix. | portable | [Details + example](#forgezero-access-client) |
47
- | @forgezero/access/testing | Deterministic access-pipeline fixtures and assertions for consumer tests. | portable | [Details + example](#forgezero-access-testing) |
48
- | @forgezero/access/header | Strict configurable header-identity extraction with canonical names and bounded values. | portable | [Details + example](#forgezero-access-header) |
49
- | @forgezero/access/principal | Generic principal-source resolution for browser, API-key, attestation or future identity adapters. | portable | [Details + example](#forgezero-access-principal) |
50
- | @forgezero/access/principal-session | Short-lived scope-bound delegated-principal sessions with sliding and absolute expiry. | portable | [Details + example](#forgezero-access-principal-session) |
51
- | @forgezero/access/authenticator | Authentication-source contracts for adding identity mechanisms without changing route policy. | portable | [Details + example](#forgezero-access-authenticator) |
52
- | @forgezero/access/ceremony-modes | Named security-ceremony modes and their session/action fulfilment semantics. | portable | [Details + example](#forgezero-access-ceremony-modes) |
38
+ | @forgezero/access | Declare routes, factors and policies as orthogonal lists; authorise against them. | portable | [Reference + usage](#forgezero-access) |
39
+ | @forgezero/access/conditions | The twelve guards every project writes into `before`, each with the status its refusal deserves. | portable | [Reference + usage](#forgezero-access-conditions) |
40
+ | @forgezero/access/effects | Audit, emit, meter, invalidate and notify — what happens after a request is decided, never failing it. | portable | [Reference + usage](#forgezero-access-effects) |
41
+ | @forgezero/access/security | Constant-time comparison, CSPRNG tokens, HMAC, HKDF, AES-GCM sealing and redaction. Web Crypto only. | portable | [Reference + usage](#forgezero-access-security) |
42
+ | @forgezero/access/rate-limit | Request counters over a window — in memory, in Redis, or in a Durable Object. | portable | [Reference + usage](#forgezero-access-rate-limit) |
43
+ | @forgezero/access/fetch | A Fetch-native adapter over the declared access pipeline. | portable | [Reference + usage](#forgezero-access-fetch) |
44
+ | @forgezero/access/pipeline | The framework-neutral route, principal, factor, policy, rate-limit and effects pipeline. | portable | [Reference + usage](#forgezero-access-pipeline) |
45
+ | @forgezero/access/elysia | Elysia integration over the same access pipeline and route declarations. | portable | [Reference + usage](#forgezero-access-elysia) |
46
+ | @forgezero/access/client | Typed client helpers that fulfil factors without duplicating the security matrix. | portable | [Reference + usage](#forgezero-access-client) |
47
+ | @forgezero/access/testing | Deterministic access-pipeline fixtures and assertions for consumer tests. | portable | [Reference + usage](#forgezero-access-testing) |
48
+ | @forgezero/access/header | Strict configurable header-identity extraction with canonical names and bounded values. | portable | [Reference + usage](#forgezero-access-header) |
49
+ | @forgezero/access/principal | Generic principal-source resolution for browser, API-key, attestation or future identity adapters. | portable | [Reference + usage](#forgezero-access-principal) |
50
+ | @forgezero/access/principal-session | Short-lived scope-bound delegated-principal sessions with sliding and absolute expiry. | portable | [Reference + usage](#forgezero-access-principal-session) |
51
+ | @forgezero/access/authenticator | Authentication-source contracts for adding identity mechanisms without changing route policy. | portable | [Reference + usage](#forgezero-access-authenticator) |
52
+ | @forgezero/access/ceremony-modes | Named security-ceremony modes and their session/action fulfilment semantics. | portable | [Reference + usage](#forgezero-access-ceremony-modes) |
53
53
 
54
54
  ## Commands
55
55
 
@@ -62,18 +62,62 @@ bun add @forgezero/access
62
62
  <a id="forgezero-access"></a>
63
63
  ## @forgezero/access
64
64
 
65
- Declare routes, factors and policies as orthogonal lists; authorise against them. Named value imports: AccessError, Refusal, SCHEMA_VERSION, Settled, VERSION, action, assertReadable, authorise, codePolicy, defineAccessControl, defineFactors, defineRoutes, externalPolicy, fulfilledActionFactors, grantsRoute, impactOfDisabling, isRefusal, isSettled, page, resolveActionFactors, stemOf. Named type imports: AccessControl, AccessControlConfig, ActionPolicy, ActionRoute, AfterHandler, BeforeHandler, Binding, FactorContext, FactorKind, FactorRegistry, FactorSpec, GrantOptions, Method, Outcome, PageRoute, PolicySource, Problem, RatePolicy, RequestContext, Role, RouteBase, RouteContract, RouteRegistry, RouteSpec, SessionContext, SessionPolicy, Versioned. Import only the names used by this file.
65
+ Declare routes, factors and policies as orthogonal lists; authorise against them. This entry exposes 21 named value exports and 27 named type exports. The generated import block lists one name per line for scanning and copying; keep only the names used by your file.
66
66
 
67
67
  ```text
68
- import { AccessError, Refusal, SCHEMA_VERSION, Settled, VERSION, action } from '@forgezero/access';
69
- import { assertReadable, authorise, codePolicy, defineAccessControl, defineFactors, defineRoutes } from '@forgezero/access';
70
- import { externalPolicy, fulfilledActionFactors, grantsRoute, impactOfDisabling, isRefusal, isSettled } from '@forgezero/access';
71
- import { page, resolveActionFactors, stemOf } from '@forgezero/access';
72
- import type { AccessControl, AccessControlConfig, ActionPolicy, ActionRoute, AfterHandler, BeforeHandler } from '@forgezero/access';
73
- import type { Binding, FactorContext, FactorKind, FactorRegistry, FactorSpec, GrantOptions } from '@forgezero/access';
74
- import type { Method, Outcome, PageRoute, PolicySource, Problem, RatePolicy } from '@forgezero/access';
75
- import type { RequestContext, Role, RouteBase, RouteContract, RouteRegistry, RouteSpec } from '@forgezero/access';
76
- import type { SessionContext, SessionPolicy, Versioned } from '@forgezero/access';
68
+ import {
69
+ AccessError,
70
+ Refusal,
71
+ SCHEMA_VERSION,
72
+ Settled,
73
+ VERSION,
74
+ action,
75
+ assertReadable,
76
+ authorise,
77
+ codePolicy,
78
+ defineAccessControl,
79
+ defineFactors,
80
+ defineRoutes,
81
+ externalPolicy,
82
+ fulfilledActionFactors,
83
+ grantsRoute,
84
+ impactOfDisabling,
85
+ isRefusal,
86
+ isSettled,
87
+ page,
88
+ resolveActionFactors,
89
+ stemOf,
90
+ } from '@forgezero/access';
91
+
92
+ import type {
93
+ AccessControl,
94
+ AccessControlConfig,
95
+ ActionPolicy,
96
+ ActionRoute,
97
+ AfterHandler,
98
+ BeforeHandler,
99
+ Binding,
100
+ FactorContext,
101
+ FactorKind,
102
+ FactorRegistry,
103
+ FactorSpec,
104
+ GrantOptions,
105
+ Method,
106
+ Outcome,
107
+ PageRoute,
108
+ PolicySource,
109
+ Problem,
110
+ RatePolicy,
111
+ RequestContext,
112
+ Role,
113
+ RouteBase,
114
+ RouteContract,
115
+ RouteRegistry,
116
+ RouteSpec,
117
+ SessionContext,
118
+ SessionPolicy,
119
+ Versioned,
120
+ } from '@forgezero/access';
77
121
  ```
78
122
 
79
123
  ## @forgezero/access — Declare routes before handlers
@@ -81,7 +125,11 @@ import type { SessionContext, SessionPolicy, Versioned } from '@forgezero/access
81
125
  Routes and their access policy are data; Fetch and Elysia adapters enforce the same declaration.
82
126
 
83
127
  ```text
84
- import { defineRoutes, action, page } from '@forgezero/access';
128
+ import {
129
+ defineRoutes,
130
+ action,
131
+ page,
132
+ } from '@forgezero/access';
85
133
 
86
134
  export const routes = defineRoutes({
87
135
  orders: page('Orders'),
@@ -92,153 +140,501 @@ export const routes = defineRoutes({
92
140
  <a id="forgezero-access-conditions"></a>
93
141
  ## @forgezero/access/conditions
94
142
 
95
- The twelve guards every project writes into `before`, each with the status its refusal deserves. Named value imports: assertDeclaredRefusals, loadTarget, refusalsFor, requireApproval, requireBalance, requireIdempotency, requireNotFrozen, requireOwner, requireQuota, requireService, requireState, requireTier, requireUnlocked, requireVersion. Named type imports: ApprovalState, Condition, IdempotencyStore, LoadTargetOptions, RefusalSpec, RequireApprovalOptions, RequireBalanceOptions, RequireIdempotencyOptions, RequireNotFrozenOptions, RequireOwnerOptions, RequireQuotaOptions, RequireServiceOptions, RequireStateOptions, RequireTierOptions, RequireUnlockedOptions, RequireVersionOptions. Import only the names used by this file.
143
+ The twelve guards every project writes into `before`, each with the status its refusal deserves. This entry exposes 14 named value exports and 16 named type exports. The generated import block lists one name per line for scanning and copying; keep only the names used by your file.
96
144
 
97
145
  ```text
98
- import { assertDeclaredRefusals, loadTarget, refusalsFor, requireApproval, requireBalance, requireIdempotency } from '@forgezero/access/conditions';
99
- import { requireNotFrozen, requireOwner, requireQuota, requireService, requireState, requireTier } from '@forgezero/access/conditions';
100
- import { requireUnlocked, requireVersion } from '@forgezero/access/conditions';
101
- import type { ApprovalState, Condition, IdempotencyStore, LoadTargetOptions, RefusalSpec, RequireApprovalOptions } from '@forgezero/access/conditions';
102
- import type { RequireBalanceOptions, RequireIdempotencyOptions, RequireNotFrozenOptions, RequireOwnerOptions, RequireQuotaOptions, RequireServiceOptions } from '@forgezero/access/conditions';
103
- import type { RequireStateOptions, RequireTierOptions, RequireUnlockedOptions, RequireVersionOptions } from '@forgezero/access/conditions';
146
+ import {
147
+ assertDeclaredRefusals,
148
+ loadTarget,
149
+ refusalsFor,
150
+ requireApproval,
151
+ requireBalance,
152
+ requireIdempotency,
153
+ requireNotFrozen,
154
+ requireOwner,
155
+ requireQuota,
156
+ requireService,
157
+ requireState,
158
+ requireTier,
159
+ requireUnlocked,
160
+ requireVersion,
161
+ } from '@forgezero/access/conditions';
162
+
163
+ import type {
164
+ ApprovalState,
165
+ Condition,
166
+ IdempotencyStore,
167
+ LoadTargetOptions,
168
+ RefusalSpec,
169
+ RequireApprovalOptions,
170
+ RequireBalanceOptions,
171
+ RequireIdempotencyOptions,
172
+ RequireNotFrozenOptions,
173
+ RequireOwnerOptions,
174
+ RequireQuotaOptions,
175
+ RequireServiceOptions,
176
+ RequireStateOptions,
177
+ RequireTierOptions,
178
+ RequireUnlockedOptions,
179
+ RequireVersionOptions,
180
+ } from '@forgezero/access/conditions';
181
+ ```
182
+
183
+ ## @forgezero/access/conditions — Use this entry point
184
+
185
+ This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
186
+
187
+ ```text
188
+ import {
189
+ assertDeclaredRefusals,
190
+ } from '@forgezero/access/conditions';
191
+
192
+ export const selectedCapability = assertDeclaredRefusals;
104
193
  ```
105
194
 
106
195
  <a id="forgezero-access-effects"></a>
107
196
  ## @forgezero/access/effects
108
197
 
109
- Audit, emit, meter, invalidate and notify — what happens after a request is decided, never failing it. Named value imports: audit, emit, invalidate, meter, notify, settlementOf. Named type imports: AuditOptions, AuditRecord, AuditSink, CacheInvalidator, Effect, EmitOptions, InvalidateOptions, MeterOptions, Notification, Notifier, NotifyOptions, Outbox, OutboxEvent, Settlement, UsageMeter. Import only the names used by this file.
198
+ Audit, emit, meter, invalidate and notify — what happens after a request is decided, never failing it. This entry exposes 6 named value exports and 15 named type exports. The generated import block lists one name per line for scanning and copying; keep only the names used by your file.
110
199
 
111
200
  ```text
112
- import { audit, emit, invalidate, meter, notify, settlementOf } from '@forgezero/access/effects';
113
- import type { AuditOptions, AuditRecord, AuditSink, CacheInvalidator, Effect, EmitOptions } from '@forgezero/access/effects';
114
- import type { InvalidateOptions, MeterOptions, Notification, Notifier, NotifyOptions, Outbox } from '@forgezero/access/effects';
115
- import type { OutboxEvent, Settlement, UsageMeter } from '@forgezero/access/effects';
201
+ import {
202
+ audit,
203
+ emit,
204
+ invalidate,
205
+ meter,
206
+ notify,
207
+ settlementOf,
208
+ } from '@forgezero/access/effects';
209
+
210
+ import type {
211
+ AuditOptions,
212
+ AuditRecord,
213
+ AuditSink,
214
+ CacheInvalidator,
215
+ Effect,
216
+ EmitOptions,
217
+ InvalidateOptions,
218
+ MeterOptions,
219
+ Notification,
220
+ Notifier,
221
+ NotifyOptions,
222
+ Outbox,
223
+ OutboxEvent,
224
+ Settlement,
225
+ UsageMeter,
226
+ } from '@forgezero/access/effects';
227
+ ```
228
+
229
+ ## @forgezero/access/effects — Use this entry point
230
+
231
+ This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
232
+
233
+ ```text
234
+ import {
235
+ audit,
236
+ } from '@forgezero/access/effects';
237
+
238
+ export const selectedCapability = audit;
116
239
  ```
117
240
 
118
241
  <a id="forgezero-access-security"></a>
119
242
  ## @forgezero/access/security
120
243
 
121
- Constant-time comparison, CSPRNG tokens, HMAC, HKDF, AES-GCM sealing and redaction. Web Crypto only. Named value imports: fromBase64Url, fromHex, hashToken, hkdf, hmacSha256, isLive, nowSeconds, open, randomDigits, randomHex, randomInt, randomToken, redact, seal, secretFieldPattern, sha256, timingSafeEqual, toBase64Url, toHex, verifyHmac. Named type imports: Sealed. Import only the names used by this file.
244
+ Constant-time comparison, CSPRNG tokens, HMAC, HKDF, AES-GCM sealing and redaction. Web Crypto only. This entry exposes 20 named value exports and 1 named type export. The generated import block lists one name per line for scanning and copying; keep only the names used by your file.
245
+
246
+ ```text
247
+ import {
248
+ fromBase64Url,
249
+ fromHex,
250
+ hashToken,
251
+ hkdf,
252
+ hmacSha256,
253
+ isLive,
254
+ nowSeconds,
255
+ open,
256
+ randomDigits,
257
+ randomHex,
258
+ randomInt,
259
+ randomToken,
260
+ redact,
261
+ seal,
262
+ secretFieldPattern,
263
+ sha256,
264
+ timingSafeEqual,
265
+ toBase64Url,
266
+ toHex,
267
+ verifyHmac,
268
+ } from '@forgezero/access/security';
269
+
270
+ import type {
271
+ Sealed,
272
+ } from '@forgezero/access/security';
273
+ ```
274
+
275
+ ## @forgezero/access/security — Use this entry point
276
+
277
+ This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
122
278
 
123
279
  ```text
124
- import { fromBase64Url, fromHex, hashToken, hkdf, hmacSha256, isLive } from '@forgezero/access/security';
125
- import { nowSeconds, open, randomDigits, randomHex, randomInt, randomToken } from '@forgezero/access/security';
126
- import { redact, seal, secretFieldPattern, sha256, timingSafeEqual, toBase64Url } from '@forgezero/access/security';
127
- import { toHex, verifyHmac } from '@forgezero/access/security';
128
- import type { Sealed } from '@forgezero/access/security';
280
+ import {
281
+ fromBase64Url,
282
+ } from '@forgezero/access/security';
283
+
284
+ export const selectedCapability = fromBase64Url;
129
285
  ```
130
286
 
131
287
  <a id="forgezero-access-rate-limit"></a>
132
288
  ## @forgezero/access/rate-limit
133
289
 
134
- Request counters over a window — in memory, in Redis, or in a Durable Object. Named value imports: durableObjectStore, memoryStore, redisStore, slidingWindowStore. Named type imports: DurableStorageLike, RedisLike. Import only the names used by this file.
290
+ Request counters over a window — in memory, in Redis, or in a Durable Object. This entry exposes 4 named value exports and 2 named type exports. The generated import block lists one name per line for scanning and copying; keep only the names used by your file.
291
+
292
+ ```text
293
+ import {
294
+ durableObjectStore,
295
+ memoryStore,
296
+ redisStore,
297
+ slidingWindowStore,
298
+ } from '@forgezero/access/rate-limit';
299
+
300
+ import type {
301
+ DurableStorageLike,
302
+ RedisLike,
303
+ } from '@forgezero/access/rate-limit';
304
+ ```
305
+
306
+ ## @forgezero/access/rate-limit — Use this entry point
307
+
308
+ This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
135
309
 
136
310
  ```text
137
- import { durableObjectStore, memoryStore, redisStore, slidingWindowStore } from '@forgezero/access/rate-limit';
138
- import type { DurableStorageLike, RedisLike } from '@forgezero/access/rate-limit';
311
+ import {
312
+ durableObjectStore,
313
+ } from '@forgezero/access/rate-limit';
314
+
315
+ export const selectedCapability = durableObjectStore;
139
316
  ```
140
317
 
141
318
  <a id="forgezero-access-fetch"></a>
142
319
  ## @forgezero/access/fetch
143
320
 
144
- A Fetch-native adapter over the declared access pipeline. Named value imports: compileRoute, matchRoute, toFetch. Named type imports: FetchHandler. Import only the names used by this file.
321
+ A Fetch-native adapter over the declared access pipeline. This entry exposes 3 named value exports and 1 named type export. The generated import block lists one name per line for scanning and copying; keep only the names used by your file.
145
322
 
146
323
  ```text
147
- import { compileRoute, matchRoute, toFetch } from '@forgezero/access/fetch';
148
- import type { FetchHandler } from '@forgezero/access/fetch';
324
+ import {
325
+ compileRoute,
326
+ matchRoute,
327
+ toFetch,
328
+ } from '@forgezero/access/fetch';
329
+
330
+ import type {
331
+ FetchHandler,
332
+ } from '@forgezero/access/fetch';
333
+ ```
334
+
335
+ ## @forgezero/access/fetch — Use this entry point
336
+
337
+ This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
338
+
339
+ ```text
340
+ import {
341
+ compileRoute,
342
+ } from '@forgezero/access/fetch';
343
+
344
+ export const selectedCapability = compileRoute;
149
345
  ```
150
346
 
151
347
  <a id="forgezero-access-pipeline"></a>
152
348
  ## @forgezero/access/pipeline
153
349
 
154
- The framework-neutral route, principal, factor, policy, rate-limit and effects pipeline. Named value imports: createPipeline, defineHandlers, windowSeconds. Named type imports: Handler, HandlerRegistry, Pipeline, PipelineOptions, RateStore, SessionResolver, StepUpStore, Telemetry, Validator. Import only the names used by this file.
350
+ The framework-neutral route, principal, factor, policy, rate-limit and effects pipeline. This entry exposes 3 named value exports and 9 named type exports. The generated import block lists one name per line for scanning and copying; keep only the names used by your file.
155
351
 
156
352
  ```text
157
- import { createPipeline, defineHandlers, windowSeconds } from '@forgezero/access/pipeline';
158
- import type { Handler, HandlerRegistry, Pipeline, PipelineOptions, RateStore, SessionResolver } from '@forgezero/access/pipeline';
159
- import type { StepUpStore, Telemetry, Validator } from '@forgezero/access/pipeline';
353
+ import {
354
+ createPipeline,
355
+ defineHandlers,
356
+ windowSeconds,
357
+ } from '@forgezero/access/pipeline';
358
+
359
+ import type {
360
+ Handler,
361
+ HandlerRegistry,
362
+ Pipeline,
363
+ PipelineOptions,
364
+ RateStore,
365
+ SessionResolver,
366
+ StepUpStore,
367
+ Telemetry,
368
+ Validator,
369
+ } from '@forgezero/access/pipeline';
370
+ ```
371
+
372
+ ## @forgezero/access/pipeline — Use this entry point
373
+
374
+ This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
375
+
376
+ ```text
377
+ import {
378
+ createPipeline,
379
+ } from '@forgezero/access/pipeline';
380
+
381
+ export const selectedCapability = createPipeline;
160
382
  ```
161
383
 
162
384
  <a id="forgezero-access-elysia"></a>
163
385
  ## @forgezero/access/elysia
164
386
 
165
- Elysia integration over the same access pipeline and route declarations. Named value imports: elysia, forbiddenTelemetryAttribute, telemetryFrom, toElysiaPath. Named type imports: ElysiaAdapterOptions, OtelTracer. Import only the names used by this file.
387
+ Elysia integration over the same access pipeline and route declarations. This entry exposes 4 named value exports and 2 named type exports. The generated import block lists one name per line for scanning and copying; keep only the names used by your file.
388
+
389
+ ```text
390
+ import {
391
+ elysia,
392
+ forbiddenTelemetryAttribute,
393
+ telemetryFrom,
394
+ toElysiaPath,
395
+ } from '@forgezero/access/elysia';
396
+
397
+ import type {
398
+ ElysiaAdapterOptions,
399
+ OtelTracer,
400
+ } from '@forgezero/access/elysia';
401
+ ```
402
+
403
+ ## @forgezero/access/elysia — Use this entry point
404
+
405
+ This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
166
406
 
167
407
  ```text
168
- import { elysia, forbiddenTelemetryAttribute, telemetryFrom, toElysiaPath } from '@forgezero/access/elysia';
169
- import type { ElysiaAdapterOptions, OtelTracer } from '@forgezero/access/elysia';
408
+ import {
409
+ elysia,
410
+ } from '@forgezero/access/elysia';
411
+
412
+ export const selectedCapability = elysia;
170
413
  ```
171
414
 
172
415
  <a id="forgezero-access-client"></a>
173
416
  ## @forgezero/access/client
174
417
 
175
- Typed client helpers that fulfil factors without duplicating the security matrix. Named value imports: buildPath, createClient. Named type imports: ChallengeHandler, ClientOptions, ClientResult, Problem, RequestArgs, SecurityChallenge. Import only the names used by this file.
418
+ Typed client helpers that fulfil factors without duplicating the security matrix. This entry exposes 2 named value exports and 6 named type exports. The generated import block lists one name per line for scanning and copying; keep only the names used by your file.
176
419
 
177
420
  ```text
178
- import { buildPath, createClient } from '@forgezero/access/client';
179
- import type { ChallengeHandler, ClientOptions, ClientResult, Problem, RequestArgs, SecurityChallenge } from '@forgezero/access/client';
421
+ import {
422
+ buildPath,
423
+ createClient,
424
+ } from '@forgezero/access/client';
425
+
426
+ import type {
427
+ ChallengeHandler,
428
+ ClientOptions,
429
+ ClientResult,
430
+ Problem,
431
+ RequestArgs,
432
+ SecurityChallenge,
433
+ } from '@forgezero/access/client';
434
+ ```
435
+
436
+ ## @forgezero/access/client — Use this entry point
437
+
438
+ This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
439
+
440
+ ```text
441
+ import {
442
+ buildPath,
443
+ } from '@forgezero/access/client';
444
+
445
+ export const selectedCapability = buildPath;
180
446
  ```
181
447
 
182
448
  <a id="forgezero-access-testing"></a>
183
449
  ## @forgezero/access/testing
184
450
 
185
- Deterministic access-pipeline fixtures and assertions for consumer tests. Named value imports: reachableRoutes, simulate, unreachableRoutes. Named type imports: SimulateArgs, Verdict. Import only the names used by this file.
451
+ Deterministic access-pipeline fixtures and assertions for consumer tests. This entry exposes 3 named value exports and 2 named type exports. The generated import block lists one name per line for scanning and copying; keep only the names used by your file.
186
452
 
187
453
  ```text
188
- import { reachableRoutes, simulate, unreachableRoutes } from '@forgezero/access/testing';
189
- import type { SimulateArgs, Verdict } from '@forgezero/access/testing';
454
+ import {
455
+ reachableRoutes,
456
+ simulate,
457
+ unreachableRoutes,
458
+ } from '@forgezero/access/testing';
459
+
460
+ import type {
461
+ SimulateArgs,
462
+ Verdict,
463
+ } from '@forgezero/access/testing';
464
+ ```
465
+
466
+ ## @forgezero/access/testing — Use this entry point
467
+
468
+ This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
469
+
470
+ ```text
471
+ import {
472
+ reachableRoutes,
473
+ } from '@forgezero/access/testing';
474
+
475
+ export const selectedCapability = reachableRoutes;
190
476
  ```
191
477
 
192
478
  <a id="forgezero-access-header"></a>
193
479
  ## @forgezero/access/header
194
480
 
195
- Strict configurable header-identity extraction with canonical names and bounded values. Named value imports: defineHeaderIdentitySources, headerIdentityResolver. Named type imports: HeaderAssignmentResolver, HeaderIdentity, HeaderIdentitySource, HeaderPrincipal. Import only the names used by this file.
481
+ Strict configurable header-identity extraction with canonical names and bounded values. This entry exposes 2 named value exports and 4 named type exports. The generated import block lists one name per line for scanning and copying; keep only the names used by your file.
482
+
483
+ ```text
484
+ import {
485
+ defineHeaderIdentitySources,
486
+ headerIdentityResolver,
487
+ } from '@forgezero/access/header';
488
+
489
+ import type {
490
+ HeaderAssignmentResolver,
491
+ HeaderIdentity,
492
+ HeaderIdentitySource,
493
+ HeaderPrincipal,
494
+ } from '@forgezero/access/header';
495
+ ```
496
+
497
+ ## @forgezero/access/header — Use this entry point
498
+
499
+ This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
196
500
 
197
501
  ```text
198
- import { defineHeaderIdentitySources, headerIdentityResolver } from '@forgezero/access/header';
199
- import type { HeaderAssignmentResolver, HeaderIdentity, HeaderIdentitySource, HeaderPrincipal } from '@forgezero/access/header';
502
+ import {
503
+ defineHeaderIdentitySources,
504
+ } from '@forgezero/access/header';
505
+
506
+ export const selectedCapability = defineHeaderIdentitySources;
200
507
  ```
201
508
 
202
509
  <a id="forgezero-access-principal"></a>
203
510
  ## @forgezero/access/principal
204
511
 
205
- Generic principal-source resolution for browser, API-key, attestation or future identity adapters. Named value imports: assignmentIsActive, decidePrincipalAccess, defineRbacPrincipal, touchPrincipalAssignment. Named type imports: PrincipalAccessDecision, PrincipalAssignment, RbacPrincipal. Import only the names used by this file.
512
+ Generic principal-source resolution for browser, API-key, attestation or future identity adapters. This entry exposes 4 named value exports and 3 named type exports. The generated import block lists one name per line for scanning and copying; keep only the names used by your file.
513
+
514
+ ```text
515
+ import {
516
+ assignmentIsActive,
517
+ decidePrincipalAccess,
518
+ defineRbacPrincipal,
519
+ touchPrincipalAssignment,
520
+ } from '@forgezero/access/principal';
521
+
522
+ import type {
523
+ PrincipalAccessDecision,
524
+ PrincipalAssignment,
525
+ RbacPrincipal,
526
+ } from '@forgezero/access/principal';
527
+ ```
528
+
529
+ ## @forgezero/access/principal — Use this entry point
530
+
531
+ This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
206
532
 
207
533
  ```text
208
- import { assignmentIsActive, decidePrincipalAccess, defineRbacPrincipal, touchPrincipalAssignment } from '@forgezero/access/principal';
209
- import type { PrincipalAccessDecision, PrincipalAssignment, RbacPrincipal } from '@forgezero/access/principal';
534
+ import {
535
+ assignmentIsActive,
536
+ } from '@forgezero/access/principal';
537
+
538
+ export const selectedCapability = assignmentIsActive;
210
539
  ```
211
540
 
212
541
  <a id="forgezero-access-principal-session"></a>
213
542
  ## @forgezero/access/principal-session
214
543
 
215
- Short-lived scope-bound delegated-principal sessions with sliding and absolute expiry. Named value imports: DEFAULT_PRINCIPAL_ABSOLUTE_TTL_MS, DEFAULT_PRINCIPAL_IDLE_TTL_MS, MAX_PRINCIPAL_ABSOLUTE_TTL_MS, MAX_PRINCIPAL_IDLE_TTL_MS, authenticatePrincipalSession, issuePrincipalSession, principalSessionIsActive, touchPrincipalSession. Named type imports: IssuedPrincipalSession, PrincipalSessionRecord. Import only the names used by this file.
544
+ Short-lived scope-bound delegated-principal sessions with sliding and absolute expiry. This entry exposes 8 named value exports and 2 named type exports. The generated import block lists one name per line for scanning and copying; keep only the names used by your file.
216
545
 
217
546
  ```text
218
- import { DEFAULT_PRINCIPAL_ABSOLUTE_TTL_MS, DEFAULT_PRINCIPAL_IDLE_TTL_MS, MAX_PRINCIPAL_ABSOLUTE_TTL_MS, MAX_PRINCIPAL_IDLE_TTL_MS, authenticatePrincipalSession, issuePrincipalSession } from '@forgezero/access/principal-session';
219
- import { principalSessionIsActive, touchPrincipalSession } from '@forgezero/access/principal-session';
220
- import type { IssuedPrincipalSession, PrincipalSessionRecord } from '@forgezero/access/principal-session';
547
+ import {
548
+ DEFAULT_PRINCIPAL_ABSOLUTE_TTL_MS,
549
+ DEFAULT_PRINCIPAL_IDLE_TTL_MS,
550
+ MAX_PRINCIPAL_ABSOLUTE_TTL_MS,
551
+ MAX_PRINCIPAL_IDLE_TTL_MS,
552
+ authenticatePrincipalSession,
553
+ issuePrincipalSession,
554
+ principalSessionIsActive,
555
+ touchPrincipalSession,
556
+ } from '@forgezero/access/principal-session';
557
+
558
+ import type {
559
+ IssuedPrincipalSession,
560
+ PrincipalSessionRecord,
561
+ } from '@forgezero/access/principal-session';
562
+ ```
563
+
564
+ ## @forgezero/access/principal-session — Use this entry point
565
+
566
+ This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
567
+
568
+ ```text
569
+ import {
570
+ DEFAULT_PRINCIPAL_ABSOLUTE_TTL_MS,
571
+ } from '@forgezero/access/principal-session';
572
+
573
+ export const selectedCapability = DEFAULT_PRINCIPAL_ABSOLUTE_TTL_MS;
221
574
  ```
222
575
 
223
576
  <a id="forgezero-access-authenticator"></a>
224
577
  ## @forgezero/access/authenticator
225
578
 
226
- Authentication-source contracts for adding identity mechanisms without changing route policy. Named value imports: createAuthenticator, encoding. Named type imports: AuthenticationOptions, AuthenticationResponse, Authenticator, AuthenticatorOptions, Credential, RegistrationOptions, RegistrationResponse. Import only the names used by this file.
579
+ Authentication-source contracts for adding identity mechanisms without changing route policy. This entry exposes 2 named value exports and 7 named type exports. The generated import block lists one name per line for scanning and copying; keep only the names used by your file.
227
580
 
228
581
  ```text
229
- import { createAuthenticator, encoding } from '@forgezero/access/authenticator';
230
- import type { AuthenticationOptions, AuthenticationResponse, Authenticator, AuthenticatorOptions, Credential, RegistrationOptions } from '@forgezero/access/authenticator';
231
- import type { RegistrationResponse } from '@forgezero/access/authenticator';
582
+ import {
583
+ createAuthenticator,
584
+ encoding,
585
+ } from '@forgezero/access/authenticator';
586
+
587
+ import type {
588
+ AuthenticationOptions,
589
+ AuthenticationResponse,
590
+ Authenticator,
591
+ AuthenticatorOptions,
592
+ Credential,
593
+ RegistrationOptions,
594
+ RegistrationResponse,
595
+ } from '@forgezero/access/authenticator';
596
+ ```
597
+
598
+ ## @forgezero/access/authenticator — Use this entry point
599
+
600
+ This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
601
+
602
+ ```text
603
+ import {
604
+ createAuthenticator,
605
+ } from '@forgezero/access/authenticator';
606
+
607
+ export const selectedCapability = createAuthenticator;
232
608
  ```
233
609
 
234
610
  <a id="forgezero-access-ceremony-modes"></a>
235
611
  ## @forgezero/access/ceremony-modes
236
612
 
237
- Named security-ceremony modes and their session/action fulfilment semantics. Named value imports: MAX_CUSTODIANS, THRESHOLD_MODES, thresholdMode. Named type imports: ThresholdMode, ThresholdModeId. Import only the names used by this file.
613
+ Named security-ceremony modes and their session/action fulfilment semantics. This entry exposes 3 named value exports and 2 named type exports. The generated import block lists one name per line for scanning and copying; keep only the names used by your file.
614
+
615
+ ```text
616
+ import {
617
+ MAX_CUSTODIANS,
618
+ THRESHOLD_MODES,
619
+ thresholdMode,
620
+ } from '@forgezero/access/ceremony-modes';
621
+
622
+ import type {
623
+ ThresholdMode,
624
+ ThresholdModeId,
625
+ } from '@forgezero/access/ceremony-modes';
626
+ ```
627
+
628
+ ## @forgezero/access/ceremony-modes — Use this entry point
629
+
630
+ This minimal executable use imports one concrete value from this exact entry point without a wildcard or package-root detour. Keep the value or values the application actually needs; the full named inventory remains directly above it.
238
631
 
239
632
  ```text
240
- import { MAX_CUSTODIANS, THRESHOLD_MODES, thresholdMode } from '@forgezero/access/ceremony-modes';
241
- import type { ThresholdMode, ThresholdModeId } from '@forgezero/access/ceremony-modes';
633
+ import {
634
+ MAX_CUSTODIANS,
635
+ } from '@forgezero/access/ceremony-modes';
636
+
637
+ export const selectedCapability = MAX_CUSTODIANS;
242
638
  ```
243
639
 
244
640
  ## 1. Install
@@ -254,7 +650,12 @@ bun add @forgezero/access
254
650
  Routes carry their contract — label, method, and the shapes they accept and return. WHO may reach them is a separate list, because the two change for different reasons and on different schedules.
255
651
 
256
652
  ```text
257
- import { defineRoutes, defineAccessControl, page, action } from '@forgezero/access';
653
+ import {
654
+ defineRoutes,
655
+ defineAccessControl,
656
+ page,
657
+ action,
658
+ } from '@forgezero/access';
258
659
 
259
660
  export const ROUTES = defineRoutes({
260
661
  orders: page('Orders'),
@@ -278,11 +679,15 @@ One line per runtime. The pipeline is written once and shared, so an adapter nev
278
679
 
279
680
  ```text
280
681
  // anywhere fetch exists — Workers, Deno, Node, Bun
281
- import { toFetch } from '@forgezero/access/fetch';
682
+ import {
683
+ toFetch,
684
+ } from '@forgezero/access/fetch';
282
685
  export default { fetch: toFetch({ access: ACCESS, handlers: HANDLERS }) };
283
686
 
284
687
  // Elysia
285
- import { elysia } from '@forgezero/access/elysia';
688
+ import {
689
+ elysia,
690
+ } from '@forgezero/access/elysia';
286
691
  app.use(elysia({ access: ACCESS, handlers: HANDLERS, Elysia }));
287
692
  ```
288
693
 
@@ -328,7 +733,10 @@ impactOfDisabling(ACCESS, ['passkey'])
328
733
  simulate() reports which policy decided, which a browser 403 never tells you. reachableRoutes() answers what a role can actually do — worth running, because stem inheritance grants more than a grant list reads like.
329
734
 
330
735
  ```text
331
- import { simulate, reachableRoutes } from '@forgezero/access/testing';
736
+ import {
737
+ simulate,
738
+ reachableRoutes,
739
+ } from '@forgezero/access/testing';
332
740
 
333
741
  simulate(ACCESS, { route: 'api/settings', roles, as: 'member' });
334
742
  // { allowed: false, status: 403, reason: 'ACCESS_DENIED', sessionPolicy: 'admin' }
@@ -342,8 +750,12 @@ reachableRoutes(ACCESS, roles, ['member']);
342
750
  Every project writes the same dozen checks into its before-handlers. These are those checks, each declaring the status it refuses with. requireOwner answers 404 rather than 403 on purpose — a 403 confirms the record exists, which turns sequential identifiers into an enumeration oracle.
343
751
 
344
752
  ```text
345
- import { loadTarget, requireOwner, requireState, requireBalance }
346
- from '@forgezero/access/conditions';
753
+ import {
754
+ loadTarget,
755
+ requireOwner,
756
+ requireState,
757
+ requireBalance,
758
+ } from '@forgezero/access/conditions';
347
759
 
348
760
  beforeHandlers: {
349
761
  load: loadTarget({ routes: ['api/orders/[id]/refund'], load: findOrder }),
@@ -379,7 +791,11 @@ assertDeclaredRefusals({ routes: ROUTES, conditions: CONDITIONS });
379
791
  Audit, emit, meter, invalidate and notify. None can fail the request — a dead audit sink must not turn a completed transfer into a 500. Audit records denials as well as successes, because a run of 403s from one session is the signal an incident is reconstructed from. Every payload is redacted first.
380
792
 
381
793
  ```text
382
- import { audit, emit, meter } from '@forgezero/access/effects';
794
+ import {
795
+ audit,
796
+ emit,
797
+ meter,
798
+ } from '@forgezero/access/effects';
383
799
 
384
800
  afterHandlers: {
385
801
  trail: audit({ routes: [...], sink }),
@@ -275,7 +275,7 @@ function impactOfDisabling(access, enabledAfter) {
275
275
  }
276
276
  return broken;
277
277
  }
278
- var VERSION = "0.1.4";
278
+ var VERSION = "0.1.6";
279
279
 
280
280
  // src/conditions.ts
281
281
  function define(condition, routes, refusals, run) {
package/dist/effects.js CHANGED
@@ -275,7 +275,7 @@ function impactOfDisabling(access, enabledAfter) {
275
275
  }
276
276
  return broken;
277
277
  }
278
- var VERSION = "0.1.4";
278
+ var VERSION = "0.1.6";
279
279
 
280
280
  // src/security.ts
281
281
  var HEX = Array.from({ length: 256 }, (_, index) => index.toString(16).padStart(2, "0"));
package/dist/elysia.js CHANGED
@@ -275,7 +275,7 @@ function impactOfDisabling(access, enabledAfter) {
275
275
  }
276
276
  return broken;
277
277
  }
278
- var VERSION = "0.1.4";
278
+ var VERSION = "0.1.6";
279
279
 
280
280
  // src/pipeline.ts
281
281
  function defineHandlers(routes, handlers) {
package/dist/fetch.js CHANGED
@@ -275,7 +275,7 @@ function impactOfDisabling(access, enabledAfter) {
275
275
  }
276
276
  return broken;
277
277
  }
278
- var VERSION = "0.1.4";
278
+ var VERSION = "0.1.6";
279
279
 
280
280
  // src/pipeline.ts
281
281
  function defineHandlers(routes, handlers) {
package/dist/header.js CHANGED
@@ -275,7 +275,7 @@ function impactOfDisabling(access, enabledAfter) {
275
275
  }
276
276
  return broken;
277
277
  }
278
- var VERSION = "0.1.4";
278
+ var VERSION = "0.1.6";
279
279
 
280
280
  // src/principal.ts
281
281
  var ATOM = /^[A-Za-z0-9][A-Za-z0-9_.:@/-]{0,255}$/;
@@ -374,7 +374,15 @@ function defineHeaderIdentitySources(sources) {
374
374
  if (!KEY.test(source.key) || !HEADER.test(header)) {
375
375
  throw new AccessError("HEADER_SOURCE_INVALID", "Header identity source keys and names must be bounded atoms.");
376
376
  }
377
- if (["cookie", "authorization", "x-fz-key", "x-fz-node", "x-fz-signature"].includes(header)) {
377
+ if ([
378
+ "cookie",
379
+ "authorization",
380
+ "x-fz-key",
381
+ "x-fz-node",
382
+ "x-fz-signature",
383
+ "x-fz-delegated-session",
384
+ "x-fz-delegated-binding"
385
+ ].includes(header)) {
378
386
  throw new AccessError("HEADER_SOURCE_RESERVED", `Header identity source "${source.key}" uses a reserved credential header.`);
379
387
  }
380
388
  if (keys.has(source.key) || headers.has(header)) {
package/dist/index.d.ts CHANGED
@@ -379,4 +379,4 @@ export declare function impactOfDisabling<R extends RouteRegistry>(access: Acces
379
379
  available: number;
380
380
  required: number;
381
381
  }[];
382
- export declare const VERSION = "0.1.4";
382
+ export declare const VERSION = "0.1.6";
package/dist/index.js CHANGED
@@ -275,7 +275,7 @@ function impactOfDisabling(access, enabledAfter) {
275
275
  }
276
276
  return broken;
277
277
  }
278
- var VERSION = "0.1.4";
278
+ var VERSION = "0.1.6";
279
279
  export {
280
280
  stemOf,
281
281
  resolveActionFactors,
package/dist/pipeline.js CHANGED
@@ -275,7 +275,7 @@ function impactOfDisabling(access, enabledAfter) {
275
275
  }
276
276
  return broken;
277
277
  }
278
- var VERSION = "0.1.4";
278
+ var VERSION = "0.1.6";
279
279
 
280
280
  // src/pipeline.ts
281
281
  function defineHandlers(routes, handlers) {
@@ -18,7 +18,7 @@ export interface PrincipalSessionRecord {
18
18
  absoluteExpiresAtMs: number;
19
19
  }
20
20
  export interface IssuedPrincipalSession {
21
- /** Returned once. Store in an HttpOnly Secure cookie, never localStorage. */
21
+ /** Returned once. Keep in memory or an HttpOnly Secure cookie; never localStorage. */
22
22
  credential: string;
23
23
  record: PrincipalSessionRecord;
24
24
  }
@@ -275,7 +275,7 @@ function impactOfDisabling(access, enabledAfter) {
275
275
  }
276
276
  return broken;
277
277
  }
278
- var VERSION = "0.1.4";
278
+ var VERSION = "0.1.6";
279
279
 
280
280
  // src/security.ts
281
281
  var HEX = Array.from({ length: 256 }, (_, index) => index.toString(16).padStart(2, "0"));
package/dist/principal.js CHANGED
@@ -275,7 +275,7 @@ function impactOfDisabling(access, enabledAfter) {
275
275
  }
276
276
  return broken;
277
277
  }
278
- var VERSION = "0.1.4";
278
+ var VERSION = "0.1.6";
279
279
 
280
280
  // src/principal.ts
281
281
  var ATOM = /^[A-Za-z0-9][A-Za-z0-9_.:@/-]{0,255}$/;
package/dist/testing.js CHANGED
@@ -275,7 +275,7 @@ function impactOfDisabling(access, enabledAfter) {
275
275
  }
276
276
  return broken;
277
277
  }
278
- var VERSION = "0.1.4";
278
+ var VERSION = "0.1.6";
279
279
 
280
280
  // src/testing.ts
281
281
  function nameOf(policies, route) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forgezero/access",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public",