@atlasauth/backend 0.1.7 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,136 @@
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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/pca/verify.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@atlasauth/backend",
3
- "version": "0.1.7",
3
+ "version": "0.4.0",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "dependencies": {
7
7
  "jose": "^5.9.6",
8
- "@atlasauth/authz": "0.1.1"
8
+ "@atlasauth/authz": "0.1.1",
9
+ "@atlasauth/pca": "0.1.0"
9
10
  },
10
11
  "devDependencies": {
11
12
  "typescript": "^5.6.3",