@atlasauth/backend 0.30.0 → 0.31.1

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 (41) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +4 -0
  3. package/dist/client/index.d.ts +19 -1
  4. package/dist/client/instance-security.d.ts +9 -1
  5. package/dist/client/instance-security.js +6 -1
  6. package/dist/client/instance-security.js.map +1 -1
  7. package/dist/client/instance.d.ts +42 -0
  8. package/dist/client/instance.js +16 -0
  9. package/dist/client/instance.js.map +1 -1
  10. package/dist/client/invitations.d.ts +4 -0
  11. package/dist/client/invitations.js.map +1 -1
  12. package/dist/client/messaging.d.ts +7 -0
  13. package/dist/client/messaging.js.map +1 -1
  14. package/dist/client/oauth-clients.d.ts +70 -0
  15. package/dist/client/oauth-clients.js +18 -0
  16. package/dist/client/oauth-clients.js.map +1 -1
  17. package/dist/client/platform.d.ts +10 -0
  18. package/dist/client/platform.js.map +1 -1
  19. package/dist/client/referrals.d.ts +4 -4
  20. package/dist/client/user-hooks.d.ts +15 -6
  21. package/dist/client/user-hooks.js.map +1 -1
  22. package/dist/client/users.d.ts +2 -0
  23. package/dist/client/users.js.map +1 -1
  24. package/dist/client/webhooks.d.ts +4 -0
  25. package/dist/client/webhooks.js.map +1 -1
  26. package/dist/index.d.ts +0 -4
  27. package/dist/index.js +4 -10
  28. package/dist/index.js.map +1 -1
  29. package/dist/pca-entry.d.ts +11 -0
  30. package/dist/pca-entry.js +18 -0
  31. package/dist/pca-entry.js.map +1 -0
  32. package/dist/rp.d.ts +70 -6
  33. package/dist/rp.js +92 -5
  34. package/dist/rp.js.map +1 -1
  35. package/package.json +16 -4
  36. package/dist/pca/require-pca.d.ts +0 -47
  37. package/dist/pca/require-pca.js +0 -121
  38. package/dist/pca/require-pca.js.map +0 -1
  39. package/dist/pca/verify.d.ts +0 -36
  40. package/dist/pca/verify.js +0 -136
  41. package/dist/pca/verify.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlasauth/backend",
3
- "version": "0.30.0",
3
+ "version": "0.31.1",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "exports": {
@@ -12,6 +12,10 @@
12
12
  "types": "./dist/rp.d.ts",
13
13
  "default": "./dist/rp.js"
14
14
  },
15
+ "./pca": {
16
+ "types": "./dist/pca-entry.d.ts",
17
+ "default": "./dist/pca-entry.js"
18
+ },
15
19
  "./testing": {
16
20
  "types": "./dist/testing.d.ts",
17
21
  "default": "./dist/testing.js"
@@ -33,12 +37,12 @@
33
37
  "@noble/ciphers": "^1.3.0",
34
38
  "@noble/hashes": "^1.8.0",
35
39
  "@noble/curves": "^1.9.1",
36
- "@atlasauth/authz": "0.3.0",
37
- "@atlasauth/pca": "0.1.0"
40
+ "@atlasauth/authz": "0.3.0"
38
41
  },
39
42
  "devDependencies": {
40
43
  "typescript": "^5.6.3",
41
- "vitest": "^2.1.4"
44
+ "vitest": "^2.1.4",
45
+ "@atlasauth/pca": "^0.4.3"
42
46
  },
43
47
  "publishConfig": {
44
48
  "access": "public"
@@ -58,6 +62,14 @@
58
62
  "bugs": {
59
63
  "url": "https://github.com/alphajew420/ssoly/issues"
60
64
  },
65
+ "peerDependencies": {
66
+ "@atlasauth/pca": "^0.4.3"
67
+ },
68
+ "peerDependenciesMeta": {
69
+ "@atlasauth/pca": {
70
+ "optional": true
71
+ }
72
+ },
61
73
  "scripts": {
62
74
  "build": "tsc -p tsconfig.build.json",
63
75
  "typecheck": "tsgo -p tsconfig.json --noEmit --module preserve --moduleResolution bundler --incremental --tsBuildInfoFile node_modules/.cache/typecheck.tsbuildinfo",
@@ -1,47 +0,0 @@
1
- import { type Capability, type PCActn, type TrustBudget, type VerifyHooks } from '@atlasauth/pca';
2
- import { type PcaContext, type PcaVerdict } from './verify';
3
- /** Framework-agnostic request shape: anything with headers and (optionally) a parsed/raw body. */
4
- export interface PcaRequestLike {
5
- headers: Record<string, string | string[] | undefined> | {
6
- get(name: string): string | null;
7
- };
8
- body?: unknown;
9
- }
10
- /** Per-holder replay + budget state. Implement over Redis/DB; the in-memory one is for tests/single node. */
11
- export interface PcaStateStore {
12
- get(key: string): Promise<{
13
- budget?: TrustBudget;
14
- lastCounter?: number;
15
- } | undefined>;
16
- put(key: string, state: {
17
- budget?: TrustBudget;
18
- lastCounter?: number;
19
- }): Promise<void>;
20
- }
21
- export declare function memoryPcaStore(): PcaStateStore;
22
- export interface RequirePcaOptions {
23
- /** Resolve the Root Intent Grant from the PCActn's `grant_ref`. null = unknown grant. */
24
- resolveGrant: (grantRef: string, pcactn: PCActn) => Promise<Capability | null>;
25
- hooks?: VerifyHooks;
26
- extract?: (req: PcaRequestLike) => PCActn | string | null;
27
- /** Anti-replay counter + budget persistence. Without it counters are not checked (surfaced in checks). */
28
- budgetStore?: PcaStateStore;
29
- /** Build verification context (params, plan, risk) per request. */
30
- context?: (req: PcaRequestLike, pcactn: PCActn) => PcaContext | Promise<PcaContext>;
31
- now?: () => number;
32
- /** WWW-Authenticate realm (default "pca"). */
33
- realm?: string;
34
- }
35
- export type PcaGuardResult = {
36
- ok: true;
37
- verdict: PcaVerdict;
38
- pcactn: PCActn;
39
- } | {
40
- ok: false;
41
- status: 401 | 403;
42
- verdict: PcaVerdict;
43
- wwwAuthenticate?: string;
44
- };
45
- /** Default extraction: `PCA-Action: <base64url PCActn JSON>` header, else JSON body `{ pcactn }`. */
46
- export declare function defaultExtract(req: PcaRequestLike): PCActn | string | null;
47
- export declare function requirePCA(opts: RequirePcaOptions): (req: PcaRequestLike) => Promise<PcaGuardResult>;
@@ -1,121 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.memoryPcaStore = memoryPcaStore;
4
- exports.defaultExtract = defaultExtract;
5
- exports.requirePCA = requirePCA;
6
- const pca_1 = require("@atlasauth/pca");
7
- const verify_1 = require("./verify");
8
- function memoryPcaStore() {
9
- const m = new Map();
10
- return { get: async (k) => m.get(k), put: async (k, v) => void m.set(k, v) };
11
- }
12
- function header(req, name) {
13
- const h = req.headers;
14
- if (typeof h.get === 'function')
15
- return h.get(name) ?? undefined;
16
- const v = h[name] ?? h[name.toLowerCase()];
17
- return Array.isArray(v) ? v[0] : v;
18
- }
19
- function fromB64u(s) {
20
- const b = s.replace(/-/g, '+').replace(/_/g, '/');
21
- return Buffer.from(b, 'base64').toString('utf8');
22
- }
23
- /** Default extraction: `PCA-Action: <base64url PCActn JSON>` header, else JSON body `{ pcactn }`. */
24
- function defaultExtract(req) {
25
- const h = header(req, 'pca-action');
26
- if (h)
27
- return fromB64u(h.trim());
28
- let b = req.body;
29
- if (typeof b === 'string') {
30
- try {
31
- b = JSON.parse(b);
32
- }
33
- catch {
34
- return null;
35
- }
36
- }
37
- const x = b?.pcactn;
38
- if (typeof x === 'string' || (x !== null && typeof x === 'object'))
39
- return x;
40
- return null;
41
- }
42
- const denyVerdict = (reason) => ({
43
- allow: false,
44
- r: 1,
45
- requiredThreshold: { t: 3, proof: 'strong', optimisticAllowed: false },
46
- checks: { pcactn: 'fail' },
47
- reasons: [reason],
48
- });
49
- function requirePCA(opts) {
50
- const realm = opts.realm ?? 'pca';
51
- const challenge = (error) => `PCA realm="${realm}"${error ? `, error="${error}"` : ''}, hint="send PCA-Action: <base64url PCActn> or JSON body {pcactn}"`;
52
- const unauth = (reason, error = 'invalid_request') => ({
53
- ok: false,
54
- status: 401,
55
- verdict: denyVerdict(reason),
56
- wwwAuthenticate: challenge(error),
57
- });
58
- return async (req) => {
59
- try {
60
- let raw;
61
- try {
62
- raw = (opts.extract ?? defaultExtract)(req);
63
- }
64
- catch (e) {
65
- return unauth(`unreadable PCActn: ${e.message}`);
66
- }
67
- if (raw === null || raw === undefined)
68
- return unauth('no PCActn presented', 'missing_pcactn');
69
- let p;
70
- try {
71
- p = typeof raw === 'string' ? (0, pca_1.decodePCActn)(raw) : raw;
72
- }
73
- catch (e) {
74
- return unauth(`undecodable PCActn: ${e.message}`, 'invalid_pcactn');
75
- }
76
- if (p === null || typeof p !== 'object' || typeof p.grant_ref !== 'string') {
77
- return unauth('malformed PCActn', 'invalid_pcactn');
78
- }
79
- const grant = await opts.resolveGrant(p.grant_ref, p);
80
- if (!grant)
81
- return unauth('unknown grant_ref', 'unknown_grant');
82
- const now = opts.now?.() ?? Date.now();
83
- const leafHolder = p.cap_chain?.[p.cap_chain.length - 1]?.holder;
84
- const key = `${grant.id}:${leafHolder ?? ''}`;
85
- const state = opts.budgetStore && leafHolder ? await opts.budgetStore.get(key) : undefined;
86
- const ctx = { ...(await opts.context?.(req, p)) };
87
- if (state?.budget && ctx.budget === undefined)
88
- ctx.budget = state.budget;
89
- const verdict = await (0, verify_1.verifyPCActn)(p, { grant, hooks: opts.hooks, now, context: ctx });
90
- // Anti-replay (Appendix A step 5): strictly increasing per holder.
91
- if (opts.budgetStore) {
92
- if (state?.lastCounter !== undefined && !(p.counter > state.lastCounter)) {
93
- verdict.allow = false;
94
- verdict.checks.counter = 'fail';
95
- verdict.reasons.push(`counter: ${String(p.counter)} is not greater than last seen ${state.lastCounter} (replay)`);
96
- }
97
- else if (verdict.checks.counter === 'pass') {
98
- verdict.checks.counter = 'pass';
99
- }
100
- }
101
- else if (verdict.checks.counter === 'pass') {
102
- verdict.checks.counter = 'not-enforced';
103
- }
104
- if (!verdict.allow) {
105
- // A bad signature / chain is an authentication failure; policy denial is authorization.
106
- const authnFailed = ['version', 'cap_chain', 'leaf_signature', 'malformed', 'grant_ref'].some((c) => verdict.checks[c] === 'fail');
107
- return authnFailed
108
- ? { ok: false, status: 401, verdict, wwwAuthenticate: challenge('invalid_pcactn') }
109
- : { ok: false, status: 403, verdict };
110
- }
111
- if (opts.budgetStore && leafHolder) {
112
- await opts.budgetStore.put(key, { budget: verdict.budget ?? state?.budget, lastCounter: p.counter });
113
- }
114
- return { ok: true, verdict, pcactn: p };
115
- }
116
- catch (e) {
117
- return { ok: false, status: 403, verdict: denyVerdict(`guard error (fail closed): ${e instanceof Error ? e.message : 'unknown'}`) };
118
- }
119
- };
120
- }
121
- //# sourceMappingURL=require-pca.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"require-pca.js","sourceRoot":"","sources":["../../src/pca/require-pca.ts"],"names":[],"mappings":";;AAeA,wCAGC;AAiCD,wCAcC;AAUD,gCAuEC;AAlJD,wCAAgH;AAChH,qCAA0E;AAc1E,SAAgB,cAAc;IAC5B,MAAM,CAAC,GAAG,IAAI,GAAG,EAA0D,CAAC;IAC5E,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AAC/E,CAAC;AAoBD,SAAS,MAAM,CAAC,GAAmB,EAAE,IAAY;IAC/C,MAAM,CAAC,GAAG,GAAG,CAAC,OAAiG,CAAC;IAChH,IAAI,OAAO,CAAC,CAAC,GAAG,KAAK,UAAU;QAAE,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC;IACjE,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAC3C,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,QAAQ,CAAC,CAAS;IACzB,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAClD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AACnD,CAAC;AAED,qGAAqG;AACrG,SAAgB,cAAc,CAAC,GAAmB;IAChD,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IACpC,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACjC,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC;IACjB,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC1B,IAAI,CAAC;YACH,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,MAAM,CAAC,GAAI,CAA6C,EAAE,MAAM,CAAC;IACjE,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ,CAAC;QAAE,OAAO,CAAoB,CAAC;IAChG,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,WAAW,GAAG,CAAC,MAAc,EAAc,EAAE,CAAC,CAAC;IACnD,KAAK,EAAE,KAAK;IACZ,CAAC,EAAE,CAAC;IACJ,iBAAiB,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,KAAK,EAAE;IACtE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;IAC1B,OAAO,EAAE,CAAC,MAAM,CAAC;CAClB,CAAC,CAAC;AAEH,SAAgB,UAAU,CAAC,IAAuB;IAChD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC;IAClC,MAAM,SAAS,GAAG,CAAC,KAAc,EAAE,EAAE,CACnC,cAAc,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,YAAY,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,oEAAoE,CAAC;IAC/H,MAAM,MAAM,GAAG,CAAC,MAAc,EAAE,KAAK,GAAG,iBAAiB,EAAkB,EAAE,CAAC,CAAC;QAC7E,EAAE,EAAE,KAAK;QACT,MAAM,EAAE,GAAG;QACX,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC;QAC5B,eAAe,EAAE,SAAS,CAAC,KAAK,CAAC;KAClC,CAAC,CAAC;IAEH,OAAO,KAAK,EAAE,GAAG,EAAE,EAAE;QACnB,IAAI,CAAC;YACH,IAAI,GAA2B,CAAC;YAChC,IAAI,CAAC;gBACH,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC;YAC9C,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,MAAM,CAAC,sBAAuB,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;YAC9D,CAAC;YACD,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS;gBAAE,OAAO,MAAM,CAAC,qBAAqB,EAAE,gBAAgB,CAAC,CAAC;YAC9F,IAAI,CAAS,CAAC;YACd,IAAI,CAAC;gBACH,CAAC,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAA,kBAAY,EAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;YACxD,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,MAAM,CAAC,uBAAwB,CAAW,CAAC,OAAO,EAAE,EAAE,gBAAgB,CAAC,CAAC;YACjF,CAAC;YACD,IAAI,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;gBAC3E,OAAO,MAAM,CAAC,kBAAkB,EAAE,gBAAgB,CAAC,CAAC;YACtD,CAAC;YACD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;YACtD,IAAI,CAAC,KAAK;gBAAE,OAAO,MAAM,CAAC,mBAAmB,EAAE,eAAe,CAAC,CAAC;YAEhE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACvC,MAAM,UAAU,GAAG,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC;YACjE,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,EAAE,IAAI,UAAU,IAAI,EAAE,EAAE,CAAC;YAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,IAAI,UAAU,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAC3F,MAAM,GAAG,GAAe,EAAE,GAAG,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9D,IAAI,KAAK,EAAE,MAAM,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS;gBAAE,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;YAEzE,MAAM,OAAO,GAAG,MAAM,IAAA,qBAAY,EAAC,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;YAEvF,mEAAmE;YACnE,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBACrB,IAAI,KAAK,EAAE,WAAW,KAAK,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;oBACzE,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC;oBACtB,OAAO,CAAC,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC;oBAChC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,kCAAkC,KAAK,CAAC,WAAW,WAAW,CAAC,CAAC;gBACpH,CAAC;qBAAM,IAAI,OAAO,CAAC,MAAM,CAAC,OAAO,KAAK,MAAM,EAAE,CAAC;oBAC7C,OAAO,CAAC,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC;gBAClC,CAAC;YACH,CAAC;iBAAM,IAAI,OAAO,CAAC,MAAM,CAAC,OAAO,KAAK,MAAM,EAAE,CAAC;gBAC7C,OAAO,CAAC,MAAM,CAAC,OAAO,GAAG,cAAc,CAAC;YAC1C,CAAC;YAED,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;gBACnB,wFAAwF;gBACxF,MAAM,WAAW,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC,IAAI,CAC3F,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,CACpC,CAAC;gBACF,OAAO,WAAW;oBAChB,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,eAAe,EAAE,SAAS,CAAC,gBAAgB,CAAC,EAAE;oBACnF,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;YAC1C,CAAC;YACD,IAAI,IAAI,CAAC,WAAW,IAAI,UAAU,EAAE,CAAC;gBACnC,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;YACvG,CAAC;YACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QAC1C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,CAAC,8BAA8B,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC;QACtI,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -1,36 +0,0 @@
1
- import { type Capability, type CheckStatus, type PCActn, type PlanNode, type RequiredThreshold, type RiskInputs, type TrustBudget, type VerifyHooks } from '@atlasauth/pca';
2
- /**
3
- * Resource-server side Proof-Carrying Authority verifier (spec §4, §7, Appendix A).
4
- * Deterministic and offline; never throws (any internal error becomes a fail-closed verdict).
5
- */
6
- export interface PcaContext {
7
- /** Plaintext action params. If given they MUST hash to `action.params_digest`; needed by predicates. */
8
- params?: Record<string, unknown>;
9
- subject?: Record<string, unknown>;
10
- env?: Record<string, unknown>;
11
- /** The committed plan, if the RS knows it. Its Merkle root must equal `plan.root`. */
12
- plan?: PlanNode[];
13
- /** Risk inputs the RS can vouch for. Missing ones fail closed (worst case) except `taint`, see below. */
14
- risk?: Partial<RiskInputs>;
15
- /** Current trust budget for the leaf holder. Absent = a full budget (`budget` check reports not-enforced). */
16
- budget?: TrustBudget;
17
- recentActionTimes?: number[];
18
- }
19
- export interface VerifyPCActnOptions {
20
- grant: Capability;
21
- hooks?: VerifyHooks;
22
- /** epoch ms (default Date.now()) */
23
- now?: number;
24
- context?: PcaContext;
25
- }
26
- export interface PcaVerdict {
27
- allow: boolean;
28
- /** Recomputed risk score in [0,1]. */
29
- r: number;
30
- requiredThreshold: RequiredThreshold;
31
- checks: Record<string, CheckStatus>;
32
- reasons: string[];
33
- /** Budget after the decision (leaked, and debited when auto-admitted). Persist it on allow. */
34
- budget?: TrustBudget;
35
- }
36
- export declare function verifyPCActn(pcactn: PCActn | string, opts: VerifyPCActnOptions): Promise<PcaVerdict>;
@@ -1,136 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.verifyPCActn = verifyPCActn;
4
- const pca_1 = require("@atlasauth/pca");
5
- const WORST_THRESHOLD = { t: 3, proof: 'strong', optimisticAllowed: false };
6
- function failClosed(reason, checks = {}) {
7
- return {
8
- allow: false,
9
- r: 1,
10
- requiredThreshold: WORST_THRESHOLD,
11
- checks: { ...checks, malformed: 'fail' },
12
- reasons: [reason],
13
- };
14
- }
15
- async function verifyPCActn(pcactn, opts) {
16
- try {
17
- let p;
18
- try {
19
- p = typeof pcactn === 'string' ? (0, pca_1.decodePCActn)(pcactn) : pcactn;
20
- }
21
- catch (e) {
22
- return failClosed(`undecodable PCActn: ${e.message}`);
23
- }
24
- if (p === null || typeof p !== 'object')
25
- return failClosed('PCActn is not an object');
26
- const now = opts.now ?? Date.now();
27
- const ctx = opts.context ?? {};
28
- const core = await (0, pca_1.verifyPCActnCore)(p, { grant: opts.grant, nowEpoch: now, hooks: opts.hooks });
29
- const checks = { ...core.checks };
30
- const reasons = [];
31
- if (!core.allow && core.reason)
32
- reasons.push(core.reason);
33
- const fail = (name, why) => {
34
- checks[name] = 'fail';
35
- reasons.push(`${name}: ${why}`);
36
- };
37
- // grant_ref binds the object to this grant
38
- if (p.grant_ref === opts.grant.id)
39
- checks.grant_ref = 'pass';
40
- else
41
- fail('grant_ref', 'does not reference the supplied grant');
42
- // params plaintext must open the committed digest
43
- if (ctx.params !== undefined) {
44
- if ((0, pca_1.hashCanonical)(ctx.params) === p.action?.params_digest)
45
- checks.params_digest = 'pass';
46
- else
47
- fail('params_digest', 'supplied params do not hash to action.params_digest');
48
- }
49
- else
50
- checks.params_digest = 'not-enforced';
51
- // the RS's own copy of the plan must be the committed one
52
- if (ctx.plan) {
53
- if ((0, pca_1.merkleRoot)(ctx.plan.map(pca_1.planNodeLeaf)) === p.plan?.root)
54
- checks.plan_root_authorized = 'pass';
55
- else
56
- fail('plan_root_authorized', 'known plan does not match plan.root');
57
- }
58
- const chain = Array.isArray(p.cap_chain) ? p.cap_chain : [];
59
- const leaf = chain[chain.length - 1];
60
- const depth = Math.max(0, chain.length - 1);
61
- const now0 = now;
62
- const budgetIn = ctx.budget ?? { B: Number.POSITIVE_INFINITY, tau: now0, asOf: now0 };
63
- checks.budget = ctx.budget ? 'pass' : 'not-enforced';
64
- // Taint: the agent's claim, used only as a default input (RS-supplied risk.taint wins).
65
- const claimedTaint = p.provenance?.taint_level;
66
- const risk = { ...ctx.risk };
67
- if (risk.taint === undefined && typeof claimedTaint === 'number')
68
- risk.taint = claimedTaint;
69
- const reversibility = p.action?.reversibility_class;
70
- const bMaxProbe = decideBudget(opts.grant, budgetIn, ctx.budget === undefined);
71
- const d = (0, pca_1.decide)({
72
- grant: opts.grant,
73
- action: {
74
- action: { verb: p.action?.verb, resource: p.action?.resource, params: ctx.params, reversibility_class: reversibility },
75
- subject: ctx.subject,
76
- env: ctx.env,
77
- },
78
- plan: ctx.plan,
79
- nodeId: p.plan?.node_id,
80
- risk,
81
- budget: bMaxProbe,
82
- now,
83
- caveatContext: { delegationDepth: depth, recentActionTimes: ctx.recentActionTimes },
84
- });
85
- // Caveats added by delegation hops (beyond the root's) are conjunctive too.
86
- if (leaf) {
87
- const extra = leaf.caveats.slice(opts.grant.caveats.length);
88
- const cv = (0, pca_1.evaluateCaveats)(extra, {
89
- now,
90
- blastRadius: risk.blastRadius,
91
- reversibilityClass: reversibility,
92
- delegationDepth: depth,
93
- recentActionTimes: ctx.recentActionTimes,
94
- });
95
- if (cv.ok)
96
- checks.delegated_caveats = 'pass';
97
- else
98
- fail('delegated_caveats', `delegation caveat(s) not satisfied: ${cv.failed.join(', ')}`);
99
- }
100
- if (d.releaseGuardianShare)
101
- checks.policy = 'pass';
102
- else {
103
- checks.policy = 'fail';
104
- reasons.push(...d.reasons.map((x) => `policy: ${x}`));
105
- }
106
- if (d.releaseGuardianShare) {
107
- // informational reasons (step-up, assumed worst case) are kept even when released
108
- reasons.push(...d.reasons.map((x) => `policy: ${x}`));
109
- }
110
- // Threshold: t > 1 needs a proof we can only get from an enforced threshold hook.
111
- const th = checks.threshold;
112
- if (d.requiredThreshold.t > 1 && d.releaseGuardianShare && th !== 'pass') {
113
- fail('threshold', th === 'fail'
114
- ? `t=${d.requiredThreshold.t} required and the threshold proof was rejected`
115
- : `t=${d.requiredThreshold.t} (${d.requiredThreshold.proof}) required but no threshold verifier is enforced`);
116
- }
117
- const allow = !Object.values(checks).includes('fail') && d.releaseGuardianShare && core.allow;
118
- if (allow) {
119
- return { allow, r: d.r, requiredThreshold: d.requiredThreshold, checks, reasons, budget: ctx.budget ? d.budget : undefined };
120
- }
121
- if (reasons.length === 0)
122
- reasons.push('denied');
123
- return { allow: false, r: d.r, requiredThreshold: d.requiredThreshold, checks, reasons };
124
- }
125
- catch (e) {
126
- return failClosed(`verifier error (fail closed): ${e instanceof Error ? e.message : 'unknown'}`);
127
- }
128
- }
129
- /** Without a caller-supplied budget, use a full budget (grant's bMax) so absence does not itself deny. */
130
- function decideBudget(grant, b, absent) {
131
- if (!absent)
132
- return b;
133
- const bMax = (0, pca_1.readEnvelope)(grant)?.risk_policy.bMax;
134
- return { ...b, B: typeof bMax === 'number' && Number.isFinite(bMax) ? bMax : 0 };
135
- }
136
- //# sourceMappingURL=verify.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/pca/verify.ts"],"names":[],"mappings":";;AAsEA,oCA+GC;AArLD,wCAiBwB;AAyCxB,MAAM,eAAe,GAAsB,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,KAAK,EAAE,CAAC;AAE/F,SAAS,UAAU,CAAC,MAAc,EAAE,SAAsC,EAAE;IAC1E,OAAO;QACL,KAAK,EAAE,KAAK;QACZ,CAAC,EAAE,CAAC;QACJ,iBAAiB,EAAE,eAAe;QAClC,MAAM,EAAE,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE;QACxC,OAAO,EAAE,CAAC,MAAM,CAAC;KAClB,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,YAAY,CAAC,MAAuB,EAAE,IAAyB;IACnF,IAAI,CAAC;QACH,IAAI,CAAS,CAAC;QACd,IAAI,CAAC;YACH,CAAC,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAA,kBAAY,EAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QACjE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,UAAU,CAAC,uBAAwB,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;QACnE,CAAC;QACD,IAAI,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ;YAAE,OAAO,UAAU,CAAC,yBAAyB,CAAC,CAAC;QAEtF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QACnC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,MAAM,IAAA,sBAAgB,EAAC,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QAChG,MAAM,MAAM,GAAgC,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC/D,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC1D,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,GAAW,EAAE,EAAE;YACzC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;YACtB,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,KAAK,GAAG,EAAE,CAAC,CAAC;QAClC,CAAC,CAAC;QAEF,2CAA2C;QAC3C,IAAI,CAAC,CAAC,SAAS,KAAK,IAAI,CAAC,KAAK,CAAC,EAAE;YAAE,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC;;YACxD,IAAI,CAAC,WAAW,EAAE,uCAAuC,CAAC,CAAC;QAEhE,kDAAkD;QAClD,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC7B,IAAI,IAAA,mBAAa,EAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,aAAa;gBAAE,MAAM,CAAC,aAAa,GAAG,MAAM,CAAC;;gBACpF,IAAI,CAAC,eAAe,EAAE,qDAAqD,CAAC,CAAC;QACpF,CAAC;;YAAM,MAAM,CAAC,aAAa,GAAG,cAAc,CAAC;QAE7C,0DAA0D;QAC1D,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;YACb,IAAI,IAAA,gBAAU,EAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,kBAAY,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,IAAI;gBAAE,MAAM,CAAC,oBAAoB,GAAG,MAAM,CAAC;;gBAC7F,IAAI,CAAC,sBAAsB,EAAE,qCAAqC,CAAC,CAAC;QAC3E,CAAC;QAED,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACrC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC5C,MAAM,IAAI,GAAG,GAAG,CAAC;QACjB,MAAM,QAAQ,GAAgB,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,iBAAiB,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACnG,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC;QAErD,wFAAwF;QACxF,MAAM,YAAY,GAAG,CAAC,CAAC,UAAU,EAAE,WAAW,CAAC;QAC/C,MAAM,IAAI,GAAwB,EAAE,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QAClD,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,OAAO,YAAY,KAAK,QAAQ;YAAE,IAAI,CAAC,KAAK,GAAG,YAAY,CAAC;QAE5F,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,EAAE,mBAAmB,CAAC;QACpD,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;QAC/E,MAAM,CAAC,GAAG,IAAA,YAAM,EAAC;YACf,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,MAAM,EAAE;gBACN,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,mBAAmB,EAAE,aAAa,EAAE;gBACtH,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,GAAG,EAAE,GAAG,CAAC,GAAG;aACb;YACD,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO;YACvB,IAAI;YACJ,MAAM,EAAE,SAAS;YACjB,GAAG;YACH,aAAa,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE,iBAAiB,EAAE,GAAG,CAAC,iBAAiB,EAAE;SACpF,CAAC,CAAC;QAEH,4EAA4E;QAC5E,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC5D,MAAM,EAAE,GAAG,IAAA,qBAAe,EAAC,KAAK,EAAE;gBAChC,GAAG;gBACH,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,kBAAkB,EAAE,aAAa;gBACjC,eAAe,EAAE,KAAK;gBACtB,iBAAiB,EAAE,GAAG,CAAC,iBAAiB;aACzC,CAAC,CAAC;YACH,IAAI,EAAE,CAAC,EAAE;gBAAE,MAAM,CAAC,iBAAiB,GAAG,MAAM,CAAC;;gBACxC,IAAI,CAAC,mBAAmB,EAAE,uCAAuC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChG,CAAC;QAED,IAAI,CAAC,CAAC,oBAAoB;YAAE,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;aAC9C,CAAC;YACJ,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;YACvB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,CAAC,CAAC,oBAAoB,EAAE,CAAC;YAC3B,kFAAkF;YAClF,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;QACxD,CAAC;QAED,kFAAkF;QAClF,MAAM,EAAE,GAAG,MAAM,CAAC,SAAS,CAAC;QAC5B,IAAI,CAAC,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,oBAAoB,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC;YACzE,IAAI,CACF,WAAW,EACX,EAAE,KAAK,MAAM;gBACX,CAAC,CAAC,KAAK,CAAC,CAAC,iBAAiB,CAAC,CAAC,gDAAgD;gBAC5E,CAAC,CAAC,KAAK,CAAC,CAAC,iBAAiB,CAAC,CAAC,KAAK,CAAC,CAAC,iBAAiB,CAAC,KAAK,kDAAkD,CAC/G,CAAC;QACJ,CAAC;QAED,MAAM,KAAK,GACT,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,oBAAoB,IAAI,IAAI,CAAC,KAAK,CAAC;QAClF,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,CAAC,CAAC,iBAAiB,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;QAC/H,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACjD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,CAAC,CAAC,iBAAiB,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IAC3F,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,UAAU,CAAC,iCAAiC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;IACnG,CAAC;AACH,CAAC;AAED,0GAA0G;AAC1G,SAAS,YAAY,CAAC,KAAiB,EAAE,CAAc,EAAE,MAAe;IACtE,IAAI,CAAC,MAAM;QAAE,OAAO,CAAC,CAAC;IACtB,MAAM,IAAI,GAAG,IAAA,kBAAY,EAAC,KAAK,CAAC,EAAE,WAAW,CAAC,IAAI,CAAC;IACnD,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC,EAAE,OAAO,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACnF,CAAC"}