@humanagencyp/hap-core 0.4.4 → 0.4.5

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/dist/index.js CHANGED
@@ -439,10 +439,22 @@ async function verifyV4(request, profile, publicKeyHex, now, executionLog) {
439
439
  if (v4BoundsErrors.length > 0) {
440
440
  return { approved: false, errors: v4BoundsErrors };
441
441
  }
442
- if (context && profile.contextSchema && Object.keys(profile.contextSchema.fields).length > 0) {
443
- const contextErrors = checkContextConstraints(context, request.execution, profile);
444
- if (contextErrors.length > 0) {
445
- return { approved: false, errors: contextErrors };
442
+ if (profile.contextSchema && Object.keys(profile.contextSchema.fields).length > 0) {
443
+ const enforceableFields = Object.entries(profile.contextSchema.fields).filter(([, def]) => def.constraint?.enforceable?.length);
444
+ if (enforceableFields.length > 0 && !context) {
445
+ return {
446
+ approved: false,
447
+ errors: [{
448
+ code: "BOUND_EXCEEDED",
449
+ message: `Declared context required for constraint enforcement but not provided. Fields: ${enforceableFields.map(([n]) => n).join(", ")}`
450
+ }]
451
+ };
452
+ }
453
+ if (context) {
454
+ const contextErrors = checkContextConstraints(context, request.execution, profile);
455
+ if (contextErrors.length > 0) {
456
+ return { approved: false, errors: contextErrors };
457
+ }
446
458
  }
447
459
  }
448
460
  return { approved: true };
package/dist/index.mjs CHANGED
@@ -377,10 +377,22 @@ async function verifyV4(request, profile, publicKeyHex, now, executionLog) {
377
377
  if (v4BoundsErrors.length > 0) {
378
378
  return { approved: false, errors: v4BoundsErrors };
379
379
  }
380
- if (context && profile.contextSchema && Object.keys(profile.contextSchema.fields).length > 0) {
381
- const contextErrors = checkContextConstraints(context, request.execution, profile);
382
- if (contextErrors.length > 0) {
383
- return { approved: false, errors: contextErrors };
380
+ if (profile.contextSchema && Object.keys(profile.contextSchema.fields).length > 0) {
381
+ const enforceableFields = Object.entries(profile.contextSchema.fields).filter(([, def]) => def.constraint?.enforceable?.length);
382
+ if (enforceableFields.length > 0 && !context) {
383
+ return {
384
+ approved: false,
385
+ errors: [{
386
+ code: "BOUND_EXCEEDED",
387
+ message: `Declared context required for constraint enforcement but not provided. Fields: ${enforceableFields.map(([n]) => n).join(", ")}`
388
+ }]
389
+ };
390
+ }
391
+ if (context) {
392
+ const contextErrors = checkContextConstraints(context, request.execution, profile);
393
+ if (contextErrors.length > 0) {
394
+ return { approved: false, errors: contextErrors };
395
+ }
384
396
  }
385
397
  }
386
398
  return { approved: true };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@humanagencyp/hap-core",
3
- "version": "0.4.4",
3
+ "version": "0.4.5",
4
4
  "description": "Core types, cryptographic primitives, and verification logic for the Human Agency Protocol",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -21,16 +21,6 @@
21
21
  "dist",
22
22
  "src"
23
23
  ],
24
- "scripts": {
25
- "build": "tsup src/index.ts --format cjs,esm --dts",
26
- "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
27
- "test": "vitest run",
28
- "test:watch": "vitest",
29
- "prepublishOnly": "pnpm build",
30
- "release:patch": "pnpm version patch && git push --follow-tags",
31
- "release:minor": "pnpm version minor && git push --follow-tags",
32
- "release:major": "pnpm version major && git push --follow-tags"
33
- },
34
24
  "dependencies": {
35
25
  "@noble/ed25519": "^2.1.0"
36
26
  },
@@ -39,5 +29,14 @@
39
29
  "tsup": "^8.0.0",
40
30
  "typescript": "^5.3.0",
41
31
  "vitest": "^1.0.0"
32
+ },
33
+ "scripts": {
34
+ "build": "tsup src/index.ts --format cjs,esm --dts",
35
+ "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
36
+ "test": "vitest run",
37
+ "test:watch": "vitest",
38
+ "release:patch": "pnpm version patch && git push --follow-tags",
39
+ "release:minor": "pnpm version minor && git push --follow-tags",
40
+ "release:major": "pnpm version major && git push --follow-tags"
42
41
  }
43
- }
42
+ }
package/src/gatekeeper.ts CHANGED
@@ -274,11 +274,30 @@ async function verifyV4(
274
274
  return { approved: false, errors: v4BoundsErrors };
275
275
  }
276
276
 
277
- // Check context constraints using contextSchema
278
- if (context && profile.contextSchema && Object.keys(profile.contextSchema.fields).length > 0) {
279
- const contextErrors = checkContextConstraints(context, request.execution, profile);
280
- if (contextErrors.length > 0) {
281
- return { approved: false, errors: contextErrors };
277
+ // Check context constraints using contextSchema.
278
+ // Fail closed: if the profile declares enforceable context constraints but
279
+ // no declared context was supplied, reject — the SP cannot enforce these
280
+ // (it only holds context_hash), so skipping the check would silently
281
+ // bypass scope restrictions like allowed_recipients / allowed_domains.
282
+ if (profile.contextSchema && Object.keys(profile.contextSchema.fields).length > 0) {
283
+ const enforceableFields = Object.entries(profile.contextSchema.fields)
284
+ .filter(([, def]) => def.constraint?.enforceable?.length);
285
+
286
+ if (enforceableFields.length > 0 && !context) {
287
+ return {
288
+ approved: false,
289
+ errors: [{
290
+ code: 'BOUND_EXCEEDED',
291
+ message: `Declared context required for constraint enforcement but not provided. Fields: ${enforceableFields.map(([n]) => n).join(', ')}`,
292
+ }],
293
+ };
294
+ }
295
+
296
+ if (context) {
297
+ const contextErrors = checkContextConstraints(context, request.execution, profile);
298
+ if (contextErrors.length > 0) {
299
+ return { approved: false, errors: contextErrors };
300
+ }
282
301
  }
283
302
  }
284
303