@agentcreds/sdk 0.1.1 → 0.2.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.
Files changed (3) hide show
  1. package/index.d.ts +160 -17
  2. package/index.js +5 -1
  3. package/package.json +6 -6
package/index.d.ts CHANGED
@@ -83,6 +83,18 @@ export interface ScopeInit {
83
83
  budgetUsd?: number
84
84
  maxDepth?: number
85
85
  }
86
+ /**
87
+ * The RFC 8785 canonical form of a JSON-representable value.
88
+ *
89
+ * Throws rather than guessing for anything JSON cannot represent (`NaN`, a
90
+ * non-finite number, `undefined` inside an array): a canonicalizer that falls back
91
+ * emits a string the other side cannot reproduce, which presents as tampering on an
92
+ * untampered request. Integers past 2^53 have already been rounded by the time
93
+ * JavaScript hands them over - see the core's `jcs::precision_hazards` note.
94
+ */
95
+ export declare function jcsCanonicalize(value: any): string
96
+ /** The canonicalization profile name every runtime must agree on. */
97
+ export declare function jcsProfile(): string
86
98
  /**
87
99
  * Issue a capability credential to `agentDid`, bound to a verified human
88
100
  * principal. The credential's validity is capped at the human's authorization
@@ -231,6 +243,42 @@ export declare class AdrCheckpoint {
231
243
  /** Parse a checkpoint from its JSON string. */
232
244
  static fromJson(s: string): AdrCheckpoint
233
245
  }
246
+ /**
247
+ * An execution-time human-authorization designation carried inside the delegated
248
+ * authority (R10). Marks a `tool` as requiring human-approval evidence before
249
+ * execution. Monotone: derivations can add gates, never remove one. Mirrors the
250
+ * Python binding's `Gate`.
251
+ */
252
+ export declare class Gate {
253
+ constructor(kind: string, tool: string)
254
+ /** A gate requiring anchor-signed human approval before `tool` may execute. */
255
+ static approval(tool: string): Gate
256
+ /**
257
+ * A gate requiring **approver-key-signed** approval (hybrid R10): the evidence
258
+ * is signed by the individual approver's key, verified against an
259
+ * org-anchor-signed `ApproverDirectory`.
260
+ */
261
+ static approvalKey(tool: string): Gate
262
+ get kind(): string
263
+ get tool(): string
264
+ toString(): string
265
+ }
266
+ /**
267
+ * A relying party's record of approval evidence already relied upon (R10
268
+ * one-time). `tryConsume` returns `true` the first time and `false` on re-use.
269
+ * In-process only: a multi-replica relying party needs a shared store with the
270
+ * same set-if-absent semantics. Mirrors the Python binding's `ConsumedApprovals`.
271
+ */
272
+ export declare class ConsumedApprovals {
273
+ constructor()
274
+ /**
275
+ * Record `approvalId` as relied upon. `true` the first time; `false` on any
276
+ * subsequent call (already used - the action must be refused).
277
+ */
278
+ tryConsume(approvalId: string): boolean
279
+ /** Whether `approvalId` has already been relied upon. */
280
+ contains(approvalId: string): boolean
281
+ }
234
282
  /**
235
283
  * One enrolled human approver: a `did:key` signing identity, roles, and an optional
236
284
  * expiry (`notAfterUnix`, unix seconds).
@@ -584,7 +632,14 @@ export declare class Scope {
584
632
  /**
585
633
  * True if `self` is permitted under `parent` (tools subset, budget and
586
634
  * depth not wider).
587
- */
635
+ * Designate `tool` as requiring execution-time human approval (R10), builder
636
+ * style. Carried in the token; later hops can add gates, never remove one.
637
+ */
638
+ requireApproval(tool: string): Scope
639
+ /** Add execution-time gates (R10), builder style. */
640
+ withGates(gates: Array<Gate>): Scope
641
+ /** The execution-time gate designations in this scope (R10). */
642
+ get gates(): Array<Gate>
588
643
  isSubsetOf(parent: Scope): boolean
589
644
  /** The first tool in `self` that `parent` does not permit, if any. */
590
645
  firstWideningCapability(parent: Scope): string | null
@@ -673,6 +728,29 @@ export declare class DelegationToken {
673
728
  * status list as it stood then.
674
729
  */
675
730
  verifyRootedAt(action: Action, vc: CapabilityCredential, anchor: TrustAnchor, epochSeconds: number): void
731
+ /**
732
+ * The execution-time gate designations carried by this token (R10), read from
733
+ * the Biscuit's facts.
734
+ */
735
+ gates(): Array<Gate>
736
+ /**
737
+ * The gates designating `action.tool` - the human-authorization requirements
738
+ * to satisfy before executing it (R10).
739
+ */
740
+ requiredGates(action: Action): Array<Gate>
741
+ /**
742
+ * The R10 gate check **alone**, at `nowUnix`, without re-verifying the chain:
743
+ * for every gate designating `action.tool` (carried by this token or by `vc`),
744
+ * require carried, anchor-verified - or, for `approval-key`, directory-verified
745
+ * - principal-bound `evidence`, and return the `approvalId`s relied upon.
746
+ * Record them in a `ConsumedApprovals` and refuse a second reliance.
747
+ *
748
+ * Pair it with a chain check (`verifyRootedAt`, or a verified Presentation) run
749
+ * at the same instant; on its own it proves nothing about the token. A gate
750
+ * kind not in `recognizedKinds`, or one this verifier has no handler for, fails
751
+ * closed.
752
+ */
753
+ checkGatesAt(action: Action, vc: CapabilityCredential, evidence: Array<ApprovalEvidence>, directory: ApproverDirectory | undefined | null, anchor: TrustAnchor, recognizedKinds: Array<string>, nowUnix: number): Array<string>
676
754
  /**
677
755
  * Produce a proof of possession for `challenge`, signed by the token's
678
756
  * leaf agent. Only the leaf agent can do this.
@@ -826,6 +904,11 @@ export declare class OidcProvider {
826
904
  * `act` actor, they must match; `expectedNonce` is checked when supplied.
827
905
  */
828
906
  validateIdToken(idToken: string, expectedAgentDid?: string | undefined | null, expectedNonce?: string | undefined | null): VerifiedHumanPrincipal
907
+ /**
908
+ * `validateIdToken` judged **as of** `epochSeconds` rather than the wall clock:
909
+ * `exp` and `nbf` are checked against that instant (with the leeway).
910
+ */
911
+ validateIdTokenAt(idToken: string, epochSeconds: number, expectedAgentDid?: string | undefined | null, expectedNonce?: string | undefined | null): VerifiedHumanPrincipal
829
912
  }
830
913
  export declare class PopChallenge {
831
914
  /**
@@ -1017,8 +1100,15 @@ export declare class SignedTrustConfig {
1017
1100
  get entries(): Array<TrustEntry>
1018
1101
  /** Verify the config's signature against `anchor` (its issuer). */
1019
1102
  verify(anchor: TrustAnchor): void
1103
+ /**
1104
+ * `verify` judged **as of** `epochSeconds` (authenticity only; the instant is
1105
+ * accepted so one `now` can be threaded through every check of a decision).
1106
+ */
1107
+ verifyAt(anchor: TrustAnchor, epochSeconds: number): void
1020
1108
  /** Whether the config is inside its validity window (unbounded = always current). */
1021
1109
  isCurrent(): boolean
1110
+ /** `isCurrent` judged **as of** `epochSeconds` rather than the wall clock. */
1111
+ isCurrentAt(epochSeconds: number): boolean
1022
1112
  /** The sealed expiry (rfc3339), or null if the config is unbounded. */
1023
1113
  get notAfter(): string | null
1024
1114
  /**
@@ -1029,6 +1119,8 @@ export declare class SignedTrustConfig {
1029
1119
  * member and never be believed.
1030
1120
  */
1031
1121
  verifyCurrent(anchor: TrustAnchor): void
1122
+ /** `verifyCurrent` judged **as of** `epochSeconds` rather than the wall clock. */
1123
+ verifyCurrentAt(anchor: TrustAnchor, epochSeconds: number): void
1032
1124
  /** The config as a JSON string (the persisted artifact). */
1033
1125
  toJson(): string
1034
1126
  /** Parse a config from its JSON string. */
@@ -1127,58 +1219,107 @@ export declare class KeyHistory {
1127
1219
  seal(current: TrustAnchor, version: number, notAfterUnix?: number | undefined | null): void
1128
1220
  /** Whether the sealed history is still inside its validity window. */
1129
1221
  isCurrent(): boolean
1222
+ /** `isCurrent` judged **as of** `epochSeconds` rather than the wall clock. */
1223
+ isCurrentAt(epochSeconds: number): boolean
1130
1224
  /** Verify the chain and the seal under the current key (authenticity only). */
1131
1225
  verifySealed(trustedRootDid: string): string
1132
1226
  /** Verify authenticity **and** freshness - what a relying party should use. */
1133
1227
  verifyCurrent(trustedRootDid: string): string
1228
+ /** `verifyCurrent` judged **as of** `epochSeconds` rather than the wall clock. */
1229
+ verifyCurrentAt(trustedRootDid: string, epochSeconds: number): string
1134
1230
  /** The DIDs still trusted for issuance (the chain minus the repudiations). */
1135
1231
  activeDids(): Array<string>
1136
1232
  /** The DIDs withdrawn from issuance. */
1137
1233
  repudiated(): Array<string>
1138
1234
  authorizeIssuer(trustedRootDid: string, issuerDid: string): TrustAnchor
1235
+ /** `authorizeIssuer` judged **as of** `epochSeconds` rather than the wall clock. */
1236
+ authorizeIssuerAt(trustedRootDid: string, issuerDid: string, epochSeconds: number): TrustAnchor
1139
1237
  /** Serialize the history to JSON (the portable artifact relying parties follow). */
1140
1238
  toJson(): string
1141
1239
  /** Parse a history from JSON. */
1142
1240
  static fromJson(s: string): KeyHistory
1143
1241
  }
1144
1242
  /**
1145
- * An SD-JWT capability credential in compact form. The issuer hands the whole
1146
- * thing to the holder; the holder calls `present` to reveal a subset.
1243
+ * A capability credential issued as an **SD-JWT VC**, in compact form. The issuer
1244
+ * hands the whole thing (issuer JWS plus every disclosure) to the holder; the
1245
+ * holder calls `present` to reveal a subset of the advisory claims. Authority
1246
+ * claims (tools, resources, budget, depth, autonomy, on-behalf-of, gates,
1247
+ * accountability) are always disclosed - a verifier decides on them.
1147
1248
  */
1148
1249
  export declare class SdJwt {
1149
1250
  /**
1150
- * Issue an SD-JWT whose disclosable claims are the fields of `claims`
1151
- * (tools, budget, depth, autonomy, and the optional model/artifact/
1152
- * authorizer fields when present).
1251
+ * Issue an SD-JWT VC for `claims`. The credential's lifetime is
1252
+ * `claims.validForSecs`; the advisory claims that are set (`modelVersion`,
1253
+ * `artifactHash`, `authorizedBy`) become selectively disclosable.
1254
+ */
1255
+ static fromCapability(anchor: TrustAnchor, subjectDid: string, claims: CapabilityClaims, revocation?: CredentialStatus | undefined | null): SdJwt
1256
+ /** Wrap an already-issued SD-JWT VC `CapabilityCredential`. */
1257
+ static fromCredential(credential: CapabilityCredential): SdJwt
1258
+ /**
1259
+ * Parse a compact SD-JWT VC (e.g. one received from an issuer). Disclosures
1260
+ * are digest-checked against the signed `_sd` set here; the issuer signature is
1261
+ * checked by `verifyPresentation` / `credential.verify`.
1153
1262
  */
1154
- static fromCapability(anchor: TrustAnchor, subjectDid: string, claims: CapabilityClaims, validForSecs: number): SdJwt
1155
- /** Parse a compact SD-JWT (e.g. one received from an issuer). */
1156
1263
  static parse(s: string): SdJwt
1157
1264
  /** The full compact serialization to hand to the holder. */
1158
1265
  asStr(): string
1159
- /** The names of the claims this SD-JWT can disclose. */
1266
+ /**
1267
+ * The names of the claims this SD-JWT can still disclose or withhold - only
1268
+ * advisory metadata, never an authority claim.
1269
+ */
1160
1270
  disclosableClaims(): Array<string>
1161
1271
  /**
1162
- * Holder side: a presentation revealing only the named claims (plus the
1163
- * always-disclosed registered claims). Unknown names are ignored.
1272
+ * Holder side: a presentation carrying only the named disclosures. Authority
1273
+ * claims are always present; a withheld advisory claim is absent from the bytes
1274
+ * and cryptographically unrecoverable. Unknown names are ignored.
1164
1275
  */
1165
1276
  present(disclose: Array<string>): string
1166
1277
  /**
1167
- * Verifier side: verify a presentation against the issuer `anchor`,
1168
- * returning the disclosed claims. Throws on a bad signature, expiry, or a
1169
- * disclosure not covered by the signed `_sd` set.
1278
+ * Holder side: `present` plus a holder-signed KB-JWT proving the presenter
1279
+ * controls the credential's confirmation key (the subject's `did:key`).
1280
+ * `audience` and `nonce` come from the verifier.
1281
+ */
1282
+ presentWithKeyBinding(holder: AgentIdentity, audience: string, nonce: string, disclose: Array<string>): string
1283
+ /** The underlying credential (usable with `DelegationToken.verifyRooted`). */
1284
+ get credential(): CapabilityCredential
1285
+ /**
1286
+ * Verifier side: parse a presentation, verify the issuer JWS against `anchor`
1287
+ * (as of `nowUnix` if given, else the wall clock), and return the disclosed
1288
+ * credential. Throws on a bad signature, expiry, an issuer other than the
1289
+ * anchor, or a disclosure not covered by the signed `_sd` set.
1170
1290
  */
1171
- static verifyPresentation(presentation: string, anchor: TrustAnchor): DisclosedCredential
1291
+ static verifyPresentation(presentation: string, anchor: TrustAnchor, nowUnix?: number | undefined | null): DisclosedCredential
1292
+ toString(): string
1172
1293
  }
1173
- /** The result of verifying an SD-JWT presentation. */
1294
+ /**
1295
+ * The result of verifying an SD-JWT VC presentation: the full credential as the
1296
+ * verifier sees it - authority claims always present, advisory claims present only
1297
+ * if the holder disclosed them (a withheld one reads as `null`).
1298
+ */
1174
1299
  export declare class DisclosedCredential {
1175
1300
  get issuer(): string
1176
1301
  get subject(): string
1302
+ /** The SD-JWT VC `vct` (verifiable credential type). */
1177
1303
  get vct(): string
1178
1304
  get issuedAt(): string
1179
1305
  get expiresAt(): string
1180
- /** The disclosed claims as a JSON object string (name -> value). */
1306
+ /** The names of the advisory claims the holder disclosed. */
1307
+ get disclosed(): Array<string>
1308
+ /**
1309
+ * The verified claims as a JSON object string. Authority claims are always
1310
+ * present; a withheld advisory claim is `null`.
1311
+ */
1181
1312
  get disclosedJson(): string
1313
+ /** The verified claims. */
1314
+ claims(): CapabilityClaims
1315
+ /** The verified credential, for the anchor-rooted token check. */
1316
+ get credential(): CapabilityCredential
1317
+ /**
1318
+ * Verify the KB-JWT appended by `SdJwt.presentWithKeyBinding`: signed by the
1319
+ * credential subject's key, bound to exactly this presentation, and matching the
1320
+ * verifier's `audience` and `nonce`.
1321
+ */
1322
+ verifyKeyBinding(audience: string, nonce: string): void
1182
1323
  }
1183
1324
  /** A parsed SPIFFE ID (`spiffe://<trust_domain><path>`). */
1184
1325
  export declare class SpiffeId {
@@ -1204,6 +1345,8 @@ export declare class SpiffeTrustBundle {
1204
1345
  addP256Key(publicKey: Buffer, kid?: string | undefined | null): void
1205
1346
  /** Validate a JWT-SVID against this bundle, optionally requiring `expectedAudience`. */
1206
1347
  validateJwtSvid(jwt: string, expectedAudience?: string | undefined | null): ValidatedSvid
1348
+ /** `validateJwtSvid` judged **as of** `epochSeconds` rather than the wall clock. */
1349
+ validateJwtSvidAt(jwt: string, epochSeconds: number, expectedAudience?: string | undefined | null): ValidatedSvid
1207
1350
  /**
1208
1351
  * Export this bundle as a JWKS document (the portable WIMSE trust-bundle
1209
1352
  * exchange form) for peers to import.
package/index.js CHANGED
@@ -310,11 +310,13 @@ if (!nativeBinding) {
310
310
  throw new Error(`Failed to load native binding`)
311
311
  }
312
312
 
313
- const { AuthzDecision, AdrStream, AdrCheckpoint, ApproverEntry, ApproverDirectory, ApprovalEvidence, AuditLog, AuditCompositor, EvidenceReport, EvidenceBundle, IdentityConfig, DelegationConfig, TrustConfig, AgentCredsConfig, CapabilityClaims, CredentialStatus, LinkedDataProof, CapabilityCredential, OwnershipRecord, Scope, Action, ChainEntry, DelegationChain, DelegationToken, PublicKey, VerificationMethod, DidDocument, AgentIdentity, TrustAnchor, InMemoryResolver, VerifiedHumanPrincipal, OidcProvider, issueOnBehalfOf, PopChallenge, ProofOfPossession, Presentation, HumanIdentity, TrustEntry, TrustRegistry, SignedTrustConfig, defaultListSize, RevocationList, RevocationRegistry, RotationStatement, KeyHistory, SdJwt, DisclosedCredential, SpiffeId, ValidatedSvid, SpiffeTrustBundle, issueFromSvid, MockOrg, MockAgent, FederationBridge, FederatedIdentity, version } = nativeBinding
313
+ const { AuthzDecision, AdrStream, AdrCheckpoint, Gate, ConsumedApprovals, ApproverEntry, ApproverDirectory, ApprovalEvidence, AuditLog, AuditCompositor, EvidenceReport, EvidenceBundle, IdentityConfig, DelegationConfig, TrustConfig, AgentCredsConfig, CapabilityClaims, CredentialStatus, LinkedDataProof, CapabilityCredential, OwnershipRecord, Scope, Action, ChainEntry, DelegationChain, DelegationToken, PublicKey, VerificationMethod, DidDocument, AgentIdentity, TrustAnchor, InMemoryResolver, jcsCanonicalize, jcsProfile, VerifiedHumanPrincipal, OidcProvider, issueOnBehalfOf, PopChallenge, ProofOfPossession, Presentation, HumanIdentity, TrustEntry, TrustRegistry, SignedTrustConfig, defaultListSize, RevocationList, RevocationRegistry, RotationStatement, KeyHistory, SdJwt, DisclosedCredential, SpiffeId, ValidatedSvid, SpiffeTrustBundle, issueFromSvid, MockOrg, MockAgent, FederationBridge, FederatedIdentity, version } = nativeBinding
314
314
 
315
315
  module.exports.AuthzDecision = AuthzDecision
316
316
  module.exports.AdrStream = AdrStream
317
317
  module.exports.AdrCheckpoint = AdrCheckpoint
318
+ module.exports.Gate = Gate
319
+ module.exports.ConsumedApprovals = ConsumedApprovals
318
320
  module.exports.ApproverEntry = ApproverEntry
319
321
  module.exports.ApproverDirectory = ApproverDirectory
320
322
  module.exports.ApprovalEvidence = ApprovalEvidence
@@ -342,6 +344,8 @@ module.exports.DidDocument = DidDocument
342
344
  module.exports.AgentIdentity = AgentIdentity
343
345
  module.exports.TrustAnchor = TrustAnchor
344
346
  module.exports.InMemoryResolver = InMemoryResolver
347
+ module.exports.jcsCanonicalize = jcsCanonicalize
348
+ module.exports.jcsProfile = jcsProfile
345
349
  module.exports.VerifiedHumanPrincipal = VerifiedHumanPrincipal
346
350
  module.exports.OidcProvider = OidcProvider
347
351
  module.exports.issueOnBehalfOf = issueOnBehalfOf
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentcreds/sdk",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Verifiable, attenuable delegation for AI agents - org-rooted and verified offline",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -28,7 +28,7 @@
28
28
  "build:debug": "napi build --platform",
29
29
  "docs": "typedoc",
30
30
  "prepublishOnly": "napi prepublish -t npm",
31
- "test": "node examples/quickstart.js && node --test test/conformance.test.js test/accountability.test.js",
31
+ "test": "node examples/quickstart.js && node --test test/conformance.test.js test/accountability.test.js test/as_of.test.js",
32
32
  "test:conformance": "node --test test/conformance.test.js",
33
33
  "version": "napi version"
34
34
  },
@@ -37,9 +37,9 @@
37
37
  "typedoc": "^0.25.0"
38
38
  },
39
39
  "optionalDependencies": {
40
- "@agentcreds/sdk-win32-x64-msvc": "0.1.1",
41
- "@agentcreds/sdk-darwin-x64": "0.1.1",
42
- "@agentcreds/sdk-linux-x64-gnu": "0.1.1",
43
- "@agentcreds/sdk-darwin-arm64": "0.1.1"
40
+ "@agentcreds/sdk-win32-x64-msvc": "0.2.0",
41
+ "@agentcreds/sdk-darwin-x64": "0.2.0",
42
+ "@agentcreds/sdk-linux-x64-gnu": "0.2.0",
43
+ "@agentcreds/sdk-darwin-arm64": "0.2.0"
44
44
  }
45
45
  }