@humanagencyp/hap-core 0.4.4 → 0.4.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/dist/index.d.mts +19 -1
- package/dist/index.d.ts +19 -1
- package/dist/index.js +16 -4
- package/dist/index.mjs +16 -4
- package/package.json +11 -12
- package/src/gatekeeper.ts +24 -5
- package/src/types.ts +23 -0
package/dist/index.d.mts
CHANGED
|
@@ -118,6 +118,17 @@ type BoundType =
|
|
|
118
118
|
kind: 'enum';
|
|
119
119
|
values: readonly string[];
|
|
120
120
|
};
|
|
121
|
+
/**
|
|
122
|
+
* The measurement dimension of a numeric bound's value.
|
|
123
|
+
*
|
|
124
|
+
* Orthogonal to `BoundType` (which describes how the bound is *enforced*).
|
|
125
|
+
* `unit` describes what the *value* means — 4 minutes vs 4 hours vs 4 EUR.
|
|
126
|
+
*
|
|
127
|
+
* UI uses this to render the unit next to the input. Future gatekeeper
|
|
128
|
+
* versions can use it to enforce unit alignment between profile bounds
|
|
129
|
+
* and tool payloads.
|
|
130
|
+
*/
|
|
131
|
+
type FieldUnit = 'count' | 'minutes' | 'hours' | 'days' | `currency:${string}` | 'percent';
|
|
121
132
|
/**
|
|
122
133
|
* Bounds field definition within a v0.4 profile.
|
|
123
134
|
*
|
|
@@ -138,6 +149,13 @@ interface ProfileBoundsField {
|
|
|
138
149
|
* treat a missing boundType as an error when running in v0.4 mode.
|
|
139
150
|
*/
|
|
140
151
|
boundType?: BoundType;
|
|
152
|
+
/**
|
|
153
|
+
* The measurement dimension of the bound's value. UI renders the unit
|
|
154
|
+
* inline next to the input (e.g. `4 min`, `100 EUR`). Independent from
|
|
155
|
+
* `boundType` — the same unit can appear under different enforcement
|
|
156
|
+
* kinds, and the same boundType can carry different units.
|
|
157
|
+
*/
|
|
158
|
+
unit?: FieldUnit;
|
|
141
159
|
/** @deprecated v0.4: use boundType instead. */
|
|
142
160
|
constraint?: FieldConstraint;
|
|
143
161
|
/** @deprecated v0.4: use boundType: { kind: 'enum', values: [...] }. */
|
|
@@ -580,4 +598,4 @@ declare function listProfiles(): string[];
|
|
|
580
598
|
declare function getAllProfiles(): AgentProfile[];
|
|
581
599
|
declare function clearProfiles(): void;
|
|
582
600
|
|
|
583
|
-
export { type AgentBoundsParams, type AgentContextParams, type AgentFrameParams, type AgentProfile, type Attestation, type AttestationHeader, type AttestationPayload, type BoundType, type CumulativeFieldDef, type CumulativeWindow, type DeclaredFieldDef, type ExecutionContextFieldDef, type ExecutionLogEntry, type ExecutionLogQuery, type ExecutionMappingTransform, type ExecutionMappingValue, type ExecutionPath, type FieldConstraint, type GateQuestion, type GatekeeperError, type GatekeeperRequest, type GatekeeperResult, type ProfileBoundsField, type ProfileContextField, type ProfileFrameField, type ProfileToolGating, type ProfileToolGatingEntry, type ResolvedDomain, attestationId, canonicalBounds, canonicalContext, canonicalFrame, checkAttestationExpiry, clearProfiles, computeBoundsHash, computeContextHash, computeFrameHash, decodeAttestationBlob, encodeAttestationBlob, frameHash, getAllProfiles, getProfile, isV4Attestation, listProfiles, registerProfile, validateBoundsParams, validateContextParams, validateFrameParams, verify, verifyAttestation, verifyAttestationSignature, verifyAttestationV4, verifyBoundsHash, verifyContextHash, verifyFrameHash };
|
|
601
|
+
export { type AgentBoundsParams, type AgentContextParams, type AgentFrameParams, type AgentProfile, type Attestation, type AttestationHeader, type AttestationPayload, type BoundType, type CumulativeFieldDef, type CumulativeWindow, type DeclaredFieldDef, type ExecutionContextFieldDef, type ExecutionLogEntry, type ExecutionLogQuery, type ExecutionMappingTransform, type ExecutionMappingValue, type ExecutionPath, type FieldConstraint, type FieldUnit, type GateQuestion, type GatekeeperError, type GatekeeperRequest, type GatekeeperResult, type ProfileBoundsField, type ProfileContextField, type ProfileFrameField, type ProfileToolGating, type ProfileToolGatingEntry, type ResolvedDomain, attestationId, canonicalBounds, canonicalContext, canonicalFrame, checkAttestationExpiry, clearProfiles, computeBoundsHash, computeContextHash, computeFrameHash, decodeAttestationBlob, encodeAttestationBlob, frameHash, getAllProfiles, getProfile, isV4Attestation, listProfiles, registerProfile, validateBoundsParams, validateContextParams, validateFrameParams, verify, verifyAttestation, verifyAttestationSignature, verifyAttestationV4, verifyBoundsHash, verifyContextHash, verifyFrameHash };
|
package/dist/index.d.ts
CHANGED
|
@@ -118,6 +118,17 @@ type BoundType =
|
|
|
118
118
|
kind: 'enum';
|
|
119
119
|
values: readonly string[];
|
|
120
120
|
};
|
|
121
|
+
/**
|
|
122
|
+
* The measurement dimension of a numeric bound's value.
|
|
123
|
+
*
|
|
124
|
+
* Orthogonal to `BoundType` (which describes how the bound is *enforced*).
|
|
125
|
+
* `unit` describes what the *value* means — 4 minutes vs 4 hours vs 4 EUR.
|
|
126
|
+
*
|
|
127
|
+
* UI uses this to render the unit next to the input. Future gatekeeper
|
|
128
|
+
* versions can use it to enforce unit alignment between profile bounds
|
|
129
|
+
* and tool payloads.
|
|
130
|
+
*/
|
|
131
|
+
type FieldUnit = 'count' | 'minutes' | 'hours' | 'days' | `currency:${string}` | 'percent';
|
|
121
132
|
/**
|
|
122
133
|
* Bounds field definition within a v0.4 profile.
|
|
123
134
|
*
|
|
@@ -138,6 +149,13 @@ interface ProfileBoundsField {
|
|
|
138
149
|
* treat a missing boundType as an error when running in v0.4 mode.
|
|
139
150
|
*/
|
|
140
151
|
boundType?: BoundType;
|
|
152
|
+
/**
|
|
153
|
+
* The measurement dimension of the bound's value. UI renders the unit
|
|
154
|
+
* inline next to the input (e.g. `4 min`, `100 EUR`). Independent from
|
|
155
|
+
* `boundType` — the same unit can appear under different enforcement
|
|
156
|
+
* kinds, and the same boundType can carry different units.
|
|
157
|
+
*/
|
|
158
|
+
unit?: FieldUnit;
|
|
141
159
|
/** @deprecated v0.4: use boundType instead. */
|
|
142
160
|
constraint?: FieldConstraint;
|
|
143
161
|
/** @deprecated v0.4: use boundType: { kind: 'enum', values: [...] }. */
|
|
@@ -580,4 +598,4 @@ declare function listProfiles(): string[];
|
|
|
580
598
|
declare function getAllProfiles(): AgentProfile[];
|
|
581
599
|
declare function clearProfiles(): void;
|
|
582
600
|
|
|
583
|
-
export { type AgentBoundsParams, type AgentContextParams, type AgentFrameParams, type AgentProfile, type Attestation, type AttestationHeader, type AttestationPayload, type BoundType, type CumulativeFieldDef, type CumulativeWindow, type DeclaredFieldDef, type ExecutionContextFieldDef, type ExecutionLogEntry, type ExecutionLogQuery, type ExecutionMappingTransform, type ExecutionMappingValue, type ExecutionPath, type FieldConstraint, type GateQuestion, type GatekeeperError, type GatekeeperRequest, type GatekeeperResult, type ProfileBoundsField, type ProfileContextField, type ProfileFrameField, type ProfileToolGating, type ProfileToolGatingEntry, type ResolvedDomain, attestationId, canonicalBounds, canonicalContext, canonicalFrame, checkAttestationExpiry, clearProfiles, computeBoundsHash, computeContextHash, computeFrameHash, decodeAttestationBlob, encodeAttestationBlob, frameHash, getAllProfiles, getProfile, isV4Attestation, listProfiles, registerProfile, validateBoundsParams, validateContextParams, validateFrameParams, verify, verifyAttestation, verifyAttestationSignature, verifyAttestationV4, verifyBoundsHash, verifyContextHash, verifyFrameHash };
|
|
601
|
+
export { type AgentBoundsParams, type AgentContextParams, type AgentFrameParams, type AgentProfile, type Attestation, type AttestationHeader, type AttestationPayload, type BoundType, type CumulativeFieldDef, type CumulativeWindow, type DeclaredFieldDef, type ExecutionContextFieldDef, type ExecutionLogEntry, type ExecutionLogQuery, type ExecutionMappingTransform, type ExecutionMappingValue, type ExecutionPath, type FieldConstraint, type FieldUnit, type GateQuestion, type GatekeeperError, type GatekeeperRequest, type GatekeeperResult, type ProfileBoundsField, type ProfileContextField, type ProfileFrameField, type ProfileToolGating, type ProfileToolGatingEntry, type ResolvedDomain, attestationId, canonicalBounds, canonicalContext, canonicalFrame, checkAttestationExpiry, clearProfiles, computeBoundsHash, computeContextHash, computeFrameHash, decodeAttestationBlob, encodeAttestationBlob, frameHash, getAllProfiles, getProfile, isV4Attestation, listProfiles, registerProfile, validateBoundsParams, validateContextParams, validateFrameParams, verify, verifyAttestation, verifyAttestationSignature, verifyAttestationV4, verifyBoundsHash, verifyContextHash, verifyFrameHash };
|
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 (
|
|
443
|
-
const
|
|
444
|
-
if (
|
|
445
|
-
return {
|
|
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 (
|
|
381
|
-
const
|
|
382
|
-
if (
|
|
383
|
-
return {
|
|
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.
|
|
3
|
+
"version": "0.4.6",
|
|
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
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
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
|
|
package/src/types.ts
CHANGED
|
@@ -117,6 +117,22 @@ export type BoundType =
|
|
|
117
117
|
*/
|
|
118
118
|
| { kind: 'enum'; values: readonly string[] };
|
|
119
119
|
|
|
120
|
+
/**
|
|
121
|
+
* The measurement dimension of a numeric bound's value.
|
|
122
|
+
*
|
|
123
|
+
* Orthogonal to `BoundType` (which describes how the bound is *enforced*).
|
|
124
|
+
* `unit` describes what the *value* means — 4 minutes vs 4 hours vs 4 EUR.
|
|
125
|
+
*
|
|
126
|
+
* UI uses this to render the unit next to the input. Future gatekeeper
|
|
127
|
+
* versions can use it to enforce unit alignment between profile bounds
|
|
128
|
+
* and tool payloads.
|
|
129
|
+
*/
|
|
130
|
+
export type FieldUnit =
|
|
131
|
+
| 'count' // dimensionless integer (no unit suffix in UI)
|
|
132
|
+
| 'minutes' | 'hours' | 'days'
|
|
133
|
+
| `currency:${string}` // ISO 4217 code, e.g. 'currency:EUR'
|
|
134
|
+
| 'percent';
|
|
135
|
+
|
|
120
136
|
/**
|
|
121
137
|
* Bounds field definition within a v0.4 profile.
|
|
122
138
|
*
|
|
@@ -137,6 +153,13 @@ export interface ProfileBoundsField {
|
|
|
137
153
|
* treat a missing boundType as an error when running in v0.4 mode.
|
|
138
154
|
*/
|
|
139
155
|
boundType?: BoundType;
|
|
156
|
+
/**
|
|
157
|
+
* The measurement dimension of the bound's value. UI renders the unit
|
|
158
|
+
* inline next to the input (e.g. `4 min`, `100 EUR`). Independent from
|
|
159
|
+
* `boundType` — the same unit can appear under different enforcement
|
|
160
|
+
* kinds, and the same boundType can carry different units.
|
|
161
|
+
*/
|
|
162
|
+
unit?: FieldUnit;
|
|
140
163
|
/** @deprecated v0.4: use boundType instead. */
|
|
141
164
|
constraint?: FieldConstraint;
|
|
142
165
|
/** @deprecated v0.4: use boundType: { kind: 'enum', values: [...] }. */
|