@forgezero/access 0.1.5 → 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 +189 -17
- package/dist/conditions.js +1 -1
- package/dist/effects.js +1 -1
- package/dist/elysia.js +1 -1
- package/dist/fetch.js +1 -1
- package/dist/header.js +10 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/pipeline.js +1 -1
- package/dist/principal-session.d.ts +1 -1
- package/dist/principal-session.js +1 -1
- package/dist/principal.js +1 -1
- package/dist/testing.js +1 -1
- package/package.json +1 -1
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 | [
|
|
39
|
-
| @forgezero/access/conditions | The twelve guards every project writes into `before`, each with the status its refusal deserves. | portable | [
|
|
40
|
-
| @forgezero/access/effects | Audit, emit, meter, invalidate and notify — what happens after a request is decided, never failing it. | portable | [
|
|
41
|
-
| @forgezero/access/security | Constant-time comparison, CSPRNG tokens, HMAC, HKDF, AES-GCM sealing and redaction. Web Crypto only. | portable | [
|
|
42
|
-
| @forgezero/access/rate-limit | Request counters over a window — in memory, in Redis, or in a Durable Object. | portable | [
|
|
43
|
-
| @forgezero/access/fetch | A Fetch-native adapter over the declared access pipeline. | portable | [
|
|
44
|
-
| @forgezero/access/pipeline | The framework-neutral route, principal, factor, policy, rate-limit and effects pipeline. | portable | [
|
|
45
|
-
| @forgezero/access/elysia | Elysia integration over the same access pipeline and route declarations. | portable | [
|
|
46
|
-
| @forgezero/access/client | Typed client helpers that fulfil factors without duplicating the security matrix. | portable | [
|
|
47
|
-
| @forgezero/access/testing | Deterministic access-pipeline fixtures and assertions for consumer tests. | portable | [
|
|
48
|
-
| @forgezero/access/header | Strict configurable header-identity extraction with canonical names and bounded values. | portable | [
|
|
49
|
-
| @forgezero/access/principal | Generic principal-source resolution for browser, API-key, attestation or future identity adapters. | portable | [
|
|
50
|
-
| @forgezero/access/principal-session | Short-lived scope-bound delegated-principal sessions with sliding and absolute expiry. | portable | [
|
|
51
|
-
| @forgezero/access/authenticator | Authentication-source contracts for adding identity mechanisms without changing route policy. | portable | [
|
|
52
|
-
| @forgezero/access/ceremony-modes | Named security-ceremony modes and their session/action fulfilment semantics. | portable | [
|
|
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
|
|
|
@@ -180,6 +180,18 @@ import type {
|
|
|
180
180
|
} from '@forgezero/access/conditions';
|
|
181
181
|
```
|
|
182
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;
|
|
193
|
+
```
|
|
194
|
+
|
|
183
195
|
<a id="forgezero-access-effects"></a>
|
|
184
196
|
## @forgezero/access/effects
|
|
185
197
|
|
|
@@ -214,6 +226,18 @@ import type {
|
|
|
214
226
|
} from '@forgezero/access/effects';
|
|
215
227
|
```
|
|
216
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;
|
|
239
|
+
```
|
|
240
|
+
|
|
217
241
|
<a id="forgezero-access-security"></a>
|
|
218
242
|
## @forgezero/access/security
|
|
219
243
|
|
|
@@ -248,6 +272,18 @@ import type {
|
|
|
248
272
|
} from '@forgezero/access/security';
|
|
249
273
|
```
|
|
250
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.
|
|
278
|
+
|
|
279
|
+
```text
|
|
280
|
+
import {
|
|
281
|
+
fromBase64Url,
|
|
282
|
+
} from '@forgezero/access/security';
|
|
283
|
+
|
|
284
|
+
export const selectedCapability = fromBase64Url;
|
|
285
|
+
```
|
|
286
|
+
|
|
251
287
|
<a id="forgezero-access-rate-limit"></a>
|
|
252
288
|
## @forgezero/access/rate-limit
|
|
253
289
|
|
|
@@ -267,6 +303,18 @@ import type {
|
|
|
267
303
|
} from '@forgezero/access/rate-limit';
|
|
268
304
|
```
|
|
269
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.
|
|
309
|
+
|
|
310
|
+
```text
|
|
311
|
+
import {
|
|
312
|
+
durableObjectStore,
|
|
313
|
+
} from '@forgezero/access/rate-limit';
|
|
314
|
+
|
|
315
|
+
export const selectedCapability = durableObjectStore;
|
|
316
|
+
```
|
|
317
|
+
|
|
270
318
|
<a id="forgezero-access-fetch"></a>
|
|
271
319
|
## @forgezero/access/fetch
|
|
272
320
|
|
|
@@ -284,6 +332,18 @@ import type {
|
|
|
284
332
|
} from '@forgezero/access/fetch';
|
|
285
333
|
```
|
|
286
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;
|
|
345
|
+
```
|
|
346
|
+
|
|
287
347
|
<a id="forgezero-access-pipeline"></a>
|
|
288
348
|
## @forgezero/access/pipeline
|
|
289
349
|
|
|
@@ -309,6 +369,18 @@ import type {
|
|
|
309
369
|
} from '@forgezero/access/pipeline';
|
|
310
370
|
```
|
|
311
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;
|
|
382
|
+
```
|
|
383
|
+
|
|
312
384
|
<a id="forgezero-access-elysia"></a>
|
|
313
385
|
## @forgezero/access/elysia
|
|
314
386
|
|
|
@@ -328,6 +400,18 @@ import type {
|
|
|
328
400
|
} from '@forgezero/access/elysia';
|
|
329
401
|
```
|
|
330
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.
|
|
406
|
+
|
|
407
|
+
```text
|
|
408
|
+
import {
|
|
409
|
+
elysia,
|
|
410
|
+
} from '@forgezero/access/elysia';
|
|
411
|
+
|
|
412
|
+
export const selectedCapability = elysia;
|
|
413
|
+
```
|
|
414
|
+
|
|
331
415
|
<a id="forgezero-access-client"></a>
|
|
332
416
|
## @forgezero/access/client
|
|
333
417
|
|
|
@@ -349,6 +433,18 @@ import type {
|
|
|
349
433
|
} from '@forgezero/access/client';
|
|
350
434
|
```
|
|
351
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;
|
|
446
|
+
```
|
|
447
|
+
|
|
352
448
|
<a id="forgezero-access-testing"></a>
|
|
353
449
|
## @forgezero/access/testing
|
|
354
450
|
|
|
@@ -367,6 +463,18 @@ import type {
|
|
|
367
463
|
} from '@forgezero/access/testing';
|
|
368
464
|
```
|
|
369
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;
|
|
476
|
+
```
|
|
477
|
+
|
|
370
478
|
<a id="forgezero-access-header"></a>
|
|
371
479
|
## @forgezero/access/header
|
|
372
480
|
|
|
@@ -386,6 +494,18 @@ import type {
|
|
|
386
494
|
} from '@forgezero/access/header';
|
|
387
495
|
```
|
|
388
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.
|
|
500
|
+
|
|
501
|
+
```text
|
|
502
|
+
import {
|
|
503
|
+
defineHeaderIdentitySources,
|
|
504
|
+
} from '@forgezero/access/header';
|
|
505
|
+
|
|
506
|
+
export const selectedCapability = defineHeaderIdentitySources;
|
|
507
|
+
```
|
|
508
|
+
|
|
389
509
|
<a id="forgezero-access-principal"></a>
|
|
390
510
|
## @forgezero/access/principal
|
|
391
511
|
|
|
@@ -406,6 +526,18 @@ import type {
|
|
|
406
526
|
} from '@forgezero/access/principal';
|
|
407
527
|
```
|
|
408
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.
|
|
532
|
+
|
|
533
|
+
```text
|
|
534
|
+
import {
|
|
535
|
+
assignmentIsActive,
|
|
536
|
+
} from '@forgezero/access/principal';
|
|
537
|
+
|
|
538
|
+
export const selectedCapability = assignmentIsActive;
|
|
539
|
+
```
|
|
540
|
+
|
|
409
541
|
<a id="forgezero-access-principal-session"></a>
|
|
410
542
|
## @forgezero/access/principal-session
|
|
411
543
|
|
|
@@ -429,6 +561,18 @@ import type {
|
|
|
429
561
|
} from '@forgezero/access/principal-session';
|
|
430
562
|
```
|
|
431
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;
|
|
574
|
+
```
|
|
575
|
+
|
|
432
576
|
<a id="forgezero-access-authenticator"></a>
|
|
433
577
|
## @forgezero/access/authenticator
|
|
434
578
|
|
|
@@ -451,6 +595,18 @@ import type {
|
|
|
451
595
|
} from '@forgezero/access/authenticator';
|
|
452
596
|
```
|
|
453
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;
|
|
608
|
+
```
|
|
609
|
+
|
|
454
610
|
<a id="forgezero-access-ceremony-modes"></a>
|
|
455
611
|
## @forgezero/access/ceremony-modes
|
|
456
612
|
|
|
@@ -469,6 +625,18 @@ import type {
|
|
|
469
625
|
} from '@forgezero/access/ceremony-modes';
|
|
470
626
|
```
|
|
471
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.
|
|
631
|
+
|
|
632
|
+
```text
|
|
633
|
+
import {
|
|
634
|
+
MAX_CUSTODIANS,
|
|
635
|
+
} from '@forgezero/access/ceremony-modes';
|
|
636
|
+
|
|
637
|
+
export const selectedCapability = MAX_CUSTODIANS;
|
|
638
|
+
```
|
|
639
|
+
|
|
472
640
|
## 1. Install
|
|
473
641
|
|
|
474
642
|
Zero runtime dependencies. The core is fetch types plus plain JSON Schema, so it runs on Bun, Node 18+, Cloudflare Workers, Deno and every edge runtime.
|
|
@@ -582,8 +750,12 @@ reachableRoutes(ACCESS, roles, ['member']);
|
|
|
582
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.
|
|
583
751
|
|
|
584
752
|
```text
|
|
585
|
-
import {
|
|
586
|
-
|
|
753
|
+
import {
|
|
754
|
+
loadTarget,
|
|
755
|
+
requireOwner,
|
|
756
|
+
requireState,
|
|
757
|
+
requireBalance,
|
|
758
|
+
} from '@forgezero/access/conditions';
|
|
587
759
|
|
|
588
760
|
beforeHandlers: {
|
|
589
761
|
load: loadTarget({ routes: ['api/orders/[id]/refund'], load: findOrder }),
|
package/dist/conditions.js
CHANGED
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.
|
|
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
package/dist/fetch.js
CHANGED
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.
|
|
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 ([
|
|
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
package/dist/index.js
CHANGED
package/dist/pipeline.js
CHANGED
|
@@ -18,7 +18,7 @@ export interface PrincipalSessionRecord {
|
|
|
18
18
|
absoluteExpiresAtMs: number;
|
|
19
19
|
}
|
|
20
20
|
export interface IssuedPrincipalSession {
|
|
21
|
-
/** Returned once.
|
|
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.
|
|
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
package/dist/testing.js
CHANGED