@kya-os/mcp 1.6.1 → 1.9.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.
- package/CHANGELOG.md +117 -0
- package/README.md +228 -3
- package/dist/authz/index.d.ts +1 -0
- package/dist/authz/index.d.ts.map +1 -1
- package/dist/authz/index.js +1 -0
- package/dist/authz/index.js.map +1 -1
- package/dist/authz/oidc/oidc-adapter.d.ts +10 -2
- package/dist/authz/oidc/oidc-adapter.d.ts.map +1 -1
- package/dist/authz/oidc/oidc-adapter.js +18 -9
- package/dist/authz/oidc/oidc-adapter.js.map +1 -1
- package/dist/authz/oidc/pending-flow-store.d.ts +80 -0
- package/dist/authz/oidc/pending-flow-store.d.ts.map +1 -0
- package/dist/authz/oidc/pending-flow-store.js +82 -0
- package/dist/authz/oidc/pending-flow-store.js.map +1 -0
- package/dist/card/build.d.ts +41 -0
- package/dist/card/build.d.ts.map +1 -0
- package/dist/card/build.js +47 -0
- package/dist/card/build.js.map +1 -0
- package/dist/card/builder.d.ts +99 -0
- package/dist/card/builder.d.ts.map +1 -0
- package/dist/card/builder.js +147 -0
- package/dist/card/builder.js.map +1 -0
- package/dist/card/cimd.d.ts +92 -0
- package/dist/card/cimd.d.ts.map +1 -0
- package/dist/card/cimd.js +225 -0
- package/dist/card/cimd.js.map +1 -0
- package/dist/card/delegation.d.ts +145 -0
- package/dist/card/delegation.d.ts.map +1 -0
- package/dist/card/delegation.js +293 -0
- package/dist/card/delegation.js.map +1 -0
- package/dist/card/emit.d.ts +133 -0
- package/dist/card/emit.d.ts.map +1 -0
- package/dist/card/emit.js +127 -0
- package/dist/card/emit.js.map +1 -0
- package/dist/card/index.d.ts +43 -0
- package/dist/card/index.d.ts.map +1 -0
- package/dist/card/index.js +46 -0
- package/dist/card/index.js.map +1 -0
- package/dist/card/middleware.d.ts +112 -0
- package/dist/card/middleware.d.ts.map +1 -0
- package/dist/card/middleware.js +121 -0
- package/dist/card/middleware.js.map +1 -0
- package/dist/card/proof/build.d.ts +22 -0
- package/dist/card/proof/build.d.ts.map +1 -0
- package/dist/card/proof/build.js +55 -0
- package/dist/card/proof/build.js.map +1 -0
- package/dist/card/proof/canonical.d.ts +66 -0
- package/dist/card/proof/canonical.d.ts.map +1 -0
- package/dist/card/proof/canonical.js +131 -0
- package/dist/card/proof/canonical.js.map +1 -0
- package/dist/card/proof/http-sig.d.ts +69 -0
- package/dist/card/proof/http-sig.d.ts.map +1 -0
- package/dist/card/proof/http-sig.js +101 -0
- package/dist/card/proof/http-sig.js.map +1 -0
- package/dist/card/proof/index.d.ts +25 -0
- package/dist/card/proof/index.d.ts.map +1 -0
- package/dist/card/proof/index.js +25 -0
- package/dist/card/proof/index.js.map +1 -0
- package/dist/card/proof/nonce-cache.d.ts +67 -0
- package/dist/card/proof/nonce-cache.d.ts.map +1 -0
- package/dist/card/proof/nonce-cache.js +88 -0
- package/dist/card/proof/nonce-cache.js.map +1 -0
- package/dist/card/proof/signer.d.ts +32 -0
- package/dist/card/proof/signer.d.ts.map +1 -0
- package/dist/card/proof/signer.js +59 -0
- package/dist/card/proof/signer.js.map +1 -0
- package/dist/card/proof/types.d.ts +219 -0
- package/dist/card/proof/types.d.ts.map +1 -0
- package/dist/card/proof/types.js +87 -0
- package/dist/card/proof/types.js.map +1 -0
- package/dist/card/proof/verify.d.ts +27 -0
- package/dist/card/proof/verify.d.ts.map +1 -0
- package/dist/card/proof/verify.js +236 -0
- package/dist/card/proof/verify.js.map +1 -0
- package/dist/card/resolve.d.ts +97 -0
- package/dist/card/resolve.d.ts.map +1 -0
- package/dist/card/resolve.js +223 -0
- package/dist/card/resolve.js.map +1 -0
- package/dist/card/revocation.d.ts +96 -0
- package/dist/card/revocation.d.ts.map +1 -0
- package/dist/card/revocation.js +190 -0
- package/dist/card/revocation.js.map +1 -0
- package/dist/card/schema.d.ts +177 -0
- package/dist/card/schema.d.ts.map +1 -0
- package/dist/card/schema.js +119 -0
- package/dist/card/schema.js.map +1 -0
- package/dist/card/verify.d.ts +144 -0
- package/dist/card/verify.d.ts.map +1 -0
- package/dist/card/verify.js +132 -0
- package/dist/card/verify.js.map +1 -0
- package/dist/delegation/bitstring.d.ts +9 -7
- package/dist/delegation/bitstring.d.ts.map +1 -1
- package/dist/delegation/bitstring.js +70 -37
- package/dist/delegation/bitstring.js.map +1 -1
- package/dist/delegation/did-linkage.d.ts +23 -0
- package/dist/delegation/did-linkage.d.ts.map +1 -0
- package/dist/delegation/did-linkage.js +57 -0
- package/dist/delegation/did-linkage.js.map +1 -0
- package/dist/delegation/did-resolver-registry.d.ts +7 -0
- package/dist/delegation/did-resolver-registry.d.ts.map +1 -0
- package/dist/delegation/did-resolver-registry.js +20 -0
- package/dist/delegation/did-resolver-registry.js.map +1 -0
- package/dist/delegation/did-web-resolver.d.ts +29 -18
- package/dist/delegation/did-web-resolver.d.ts.map +1 -1
- package/dist/delegation/did-web-resolver.js +65 -35
- package/dist/delegation/did-web-resolver.js.map +1 -1
- package/dist/delegation/index.d.ts +3 -0
- package/dist/delegation/index.d.ts.map +1 -1
- package/dist/delegation/index.js +3 -0
- package/dist/delegation/index.js.map +1 -1
- package/dist/delegation/statuslist-manager.d.ts.map +1 -1
- package/dist/delegation/statuslist-manager.js +16 -1
- package/dist/delegation/statuslist-manager.js.map +1 -1
- package/dist/delegation/vc-jwt-verify.d.ts +61 -0
- package/dist/delegation/vc-jwt-verify.d.ts.map +1 -0
- package/dist/delegation/vc-jwt-verify.js +131 -0
- package/dist/delegation/vc-jwt-verify.js.map +1 -0
- package/dist/delegation/vc-verification-checks.d.ts +50 -0
- package/dist/delegation/vc-verification-checks.d.ts.map +1 -0
- package/dist/delegation/vc-verification-checks.js +212 -0
- package/dist/delegation/vc-verification-checks.js.map +1 -0
- package/dist/delegation/vc-verifier.d.ts +24 -61
- package/dist/delegation/vc-verifier.d.ts.map +1 -1
- package/dist/delegation/vc-verifier.js +57 -180
- package/dist/delegation/vc-verifier.js.map +1 -1
- package/dist/delegation/vc-verifier.types.d.ts +88 -0
- package/dist/delegation/vc-verifier.types.d.ts.map +1 -0
- package/dist/delegation/vc-verifier.types.js +9 -0
- package/dist/delegation/vc-verifier.types.js.map +1 -0
- package/dist/index.d.ts +8 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -3
- package/dist/index.js.map +1 -1
- package/dist/integrations/cheqd/dlr.d.ts +44 -0
- package/dist/integrations/cheqd/dlr.d.ts.map +1 -0
- package/dist/integrations/cheqd/dlr.js +86 -0
- package/dist/integrations/cheqd/dlr.js.map +1 -0
- package/dist/integrations/cheqd/index.d.ts +5 -0
- package/dist/integrations/cheqd/index.d.ts.map +1 -0
- package/dist/integrations/cheqd/index.js +5 -0
- package/dist/integrations/cheqd/index.js.map +1 -0
- package/dist/integrations/cheqd/linkage.d.ts +20 -0
- package/dist/integrations/cheqd/linkage.d.ts.map +1 -0
- package/dist/integrations/cheqd/linkage.js +32 -0
- package/dist/integrations/cheqd/linkage.js.map +1 -0
- package/dist/integrations/cheqd/registrar.d.ts +85 -0
- package/dist/integrations/cheqd/registrar.d.ts.map +1 -0
- package/dist/integrations/cheqd/registrar.js +304 -0
- package/dist/integrations/cheqd/registrar.js.map +1 -0
- package/dist/integrations/cheqd/resolver.d.ts +38 -0
- package/dist/integrations/cheqd/resolver.d.ts.map +1 -0
- package/dist/integrations/cheqd/resolver.js +156 -0
- package/dist/integrations/cheqd/resolver.js.map +1 -0
- package/dist/middleware/index.d.ts +2 -0
- package/dist/middleware/index.d.ts.map +1 -1
- package/dist/middleware/index.js +5 -0
- package/dist/middleware/index.js.map +1 -1
- package/dist/middleware/kya-os-transport.d.ts +2 -1
- package/dist/middleware/kya-os-transport.d.ts.map +1 -1
- package/dist/middleware/kya-os-transport.js +2 -1
- package/dist/middleware/kya-os-transport.js.map +1 -1
- package/dist/middleware/with-kya-os-server.d.ts +21 -4
- package/dist/middleware/with-kya-os-server.d.ts.map +1 -1
- package/dist/middleware/with-kya-os-server.js +4 -0
- package/dist/middleware/with-kya-os-server.js.map +1 -1
- package/dist/middleware/with-kya-os.config-types.d.ts +139 -0
- package/dist/middleware/with-kya-os.config-types.d.ts.map +1 -0
- package/dist/middleware/with-kya-os.config-types.js +9 -0
- package/dist/middleware/with-kya-os.config-types.js.map +1 -0
- package/dist/middleware/with-kya-os.d.ts +10 -238
- package/dist/middleware/with-kya-os.d.ts.map +1 -1
- package/dist/middleware/with-kya-os.delegation-gate.d.ts +19 -0
- package/dist/middleware/with-kya-os.delegation-gate.d.ts.map +1 -0
- package/dist/middleware/with-kya-os.delegation-gate.js +175 -0
- package/dist/middleware/with-kya-os.delegation-gate.js.map +1 -0
- package/dist/middleware/with-kya-os.delegation-verify.d.ts +51 -0
- package/dist/middleware/with-kya-os.delegation-verify.d.ts.map +1 -0
- package/dist/middleware/with-kya-os.delegation-verify.js +165 -0
- package/dist/middleware/with-kya-os.delegation-verify.js.map +1 -0
- package/dist/middleware/with-kya-os.deps.d.ts +40 -0
- package/dist/middleware/with-kya-os.deps.d.ts.map +1 -0
- package/dist/middleware/with-kya-os.deps.js +9 -0
- package/dist/middleware/with-kya-os.deps.js.map +1 -0
- package/dist/middleware/with-kya-os.grants.d.ts +30 -0
- package/dist/middleware/with-kya-os.grants.d.ts.map +1 -0
- package/dist/middleware/with-kya-os.grants.js +145 -0
- package/dist/middleware/with-kya-os.grants.js.map +1 -0
- package/dist/middleware/with-kya-os.helpers.d.ts +24 -0
- package/dist/middleware/with-kya-os.helpers.d.ts.map +1 -0
- package/dist/middleware/with-kya-os.helpers.js +57 -0
- package/dist/middleware/with-kya-os.helpers.js.map +1 -0
- package/dist/middleware/with-kya-os.js +65 -703
- package/dist/middleware/with-kya-os.js.map +1 -1
- package/dist/middleware/with-kya-os.policy-gate.d.ts +16 -0
- package/dist/middleware/with-kya-os.policy-gate.d.ts.map +1 -0
- package/dist/middleware/with-kya-os.policy-gate.js +98 -0
- package/dist/middleware/with-kya-os.policy-gate.js.map +1 -0
- package/dist/middleware/with-kya-os.protocol.d.ts +29 -0
- package/dist/middleware/with-kya-os.protocol.d.ts.map +1 -0
- package/dist/middleware/with-kya-os.protocol.js +121 -0
- package/dist/middleware/with-kya-os.protocol.js.map +1 -0
- package/dist/middleware/with-kya-os.session.d.ts +32 -0
- package/dist/middleware/with-kya-os.session.d.ts.map +1 -0
- package/dist/middleware/with-kya-os.session.js +201 -0
- package/dist/middleware/with-kya-os.session.js.map +1 -0
- package/dist/middleware/with-kya-os.types.d.ts +178 -0
- package/dist/middleware/with-kya-os.types.d.ts.map +1 -0
- package/dist/middleware/with-kya-os.types.js +13 -0
- package/dist/middleware/with-kya-os.types.js.map +1 -0
- package/dist/proof/generator.d.ts +21 -0
- package/dist/proof/generator.d.ts.map +1 -1
- package/dist/proof/generator.js +21 -0
- package/dist/proof/generator.js.map +1 -1
- package/dist/proof/index.d.ts +1 -1
- package/dist/proof/index.d.ts.map +1 -1
- package/dist/proof/index.js +1 -1
- package/dist/proof/index.js.map +1 -1
- package/dist/proof/verifier.d.ts +26 -3
- package/dist/proof/verifier.d.ts.map +1 -1
- package/dist/proof/verifier.js +54 -24
- package/dist/proof/verifier.js.map +1 -1
- package/dist/providers/grant-store.d.ts +10 -1
- package/dist/providers/grant-store.d.ts.map +1 -1
- package/dist/providers/grant-store.js.map +1 -1
- package/dist/providers/runtime-fetch.d.ts +8 -0
- package/dist/providers/runtime-fetch.d.ts.map +1 -1
- package/dist/providers/runtime-fetch.js +17 -0
- package/dist/providers/runtime-fetch.js.map +1 -1
- package/dist/providers/web-crypto.d.ts.map +1 -1
- package/dist/providers/web-crypto.js +15 -7
- package/dist/providers/web-crypto.js.map +1 -1
- package/dist/session/index.d.ts +1 -0
- package/dist/session/index.d.ts.map +1 -1
- package/dist/session/index.js +1 -0
- package/dist/session/index.js.map +1 -1
- package/dist/session/manager.d.ts +17 -6
- package/dist/session/manager.d.ts.map +1 -1
- package/dist/session/manager.js +16 -26
- package/dist/session/manager.js.map +1 -1
- package/dist/session/session-store.d.ts +78 -0
- package/dist/session/session-store.d.ts.map +1 -0
- package/dist/session/session-store.js +79 -0
- package/dist/session/session-store.js.map +1 -0
- package/dist/types/protocol.d.ts +9 -3
- package/dist/types/protocol.d.ts.map +1 -1
- package/dist/types/protocol.js.map +1 -1
- package/dist/utils/guards.d.ts +2 -0
- package/dist/utils/guards.d.ts.map +1 -0
- package/dist/utils/guards.js +4 -0
- package/dist/utils/guards.js.map +1 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +3 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/ip-classifier.d.ts +12 -0
- package/dist/utils/ip-classifier.d.ts.map +1 -0
- package/dist/utils/ip-classifier.js +153 -0
- package/dist/utils/ip-classifier.js.map +1 -0
- package/dist/utils/safe-fetch-transports.d.ts +40 -0
- package/dist/utils/safe-fetch-transports.d.ts.map +1 -0
- package/dist/utils/safe-fetch-transports.js +121 -0
- package/dist/utils/safe-fetch-transports.js.map +1 -0
- package/dist/utils/safe-fetch-types.d.ts +66 -0
- package/dist/utils/safe-fetch-types.d.ts.map +1 -0
- package/dist/utils/safe-fetch-types.js +10 -0
- package/dist/utils/safe-fetch-types.js.map +1 -0
- package/dist/utils/safe-fetch.d.ts +40 -0
- package/dist/utils/safe-fetch.d.ts.map +1 -0
- package/dist/utils/safe-fetch.js +188 -0
- package/dist/utils/safe-fetch.js.map +1 -0
- package/dist/utils/statuslist-purpose.d.ts +12 -0
- package/dist/utils/statuslist-purpose.d.ts.map +1 -0
- package/dist/utils/statuslist-purpose.js +19 -0
- package/dist/utils/statuslist-purpose.js.map +1 -0
- package/dist/utils/url.d.ts +2 -0
- package/dist/utils/url.d.ts.map +1 -0
- package/dist/utils/url.js +8 -0
- package/dist/utils/url.js.map +1 -0
- package/package.json +25 -5
- package/schemas/README.md +2 -1
- package/schemas/card-delegation-credential.json +239 -0
- package/schemas/kya-os-card.schema.json +284 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KYA-OS Entity Card — stateless per-request holder-of-key proof: shapes + seams.
|
|
3
|
+
*
|
|
4
|
+
* `org.kya-os/proof@1` is the STATELESS, sender-constrained proof profile. It rides its OWN
|
|
5
|
+
* `_meta` key ({@link KYA_OS_CARD_PROOF_META_KEY} = `org.kya-os/proof@1`), DISTINCT from the legacy
|
|
6
|
+
* session-bound `ProofMeta` (which carries `sessionId` + a handshake nonce under
|
|
7
|
+
* `org.kya-os/proof`). Separate keys let the two regimes coexist on one server without either guard
|
|
8
|
+
* seeing — or rejecting — the other's proof. Every request self-proves; there is no session state.
|
|
9
|
+
*
|
|
10
|
+
* All crypto is INJECTED via seams ({@link ProofSigner} for minting, {@link VerifyProofDeps}
|
|
11
|
+
* for verifying) so no runtime (`mcp-i-core`) dependency leaks into `@kya-os/mcp`; the module
|
|
12
|
+
* uses only `jose` + `json-canonicalize`, already direct dependencies.
|
|
13
|
+
*/
|
|
14
|
+
import { z } from 'zod';
|
|
15
|
+
import { type ProofPublicJwk } from '../schema.js';
|
|
16
|
+
/** The stateless per-request proof profile tag (the `prf` discriminator). */
|
|
17
|
+
export declare const PROOF_PROFILE_V1 = "org.kya-os/proof@1";
|
|
18
|
+
/**
|
|
19
|
+
* The `_meta` key the STATELESS card proof rides under — DISTINCT from the legacy session proof's
|
|
20
|
+
* `org.kya-os/proof` (`KYA_OS_PROOF_META_KEY`). Sharing one key made the two regimes mutually
|
|
21
|
+
* exclusive on a server (a legacy proof failed the card schema and was 401'd; a card proof failed
|
|
22
|
+
* the legacy structure check). With separate keys each guard reads its OWN key and simply does not
|
|
23
|
+
* see the other's proof, so both can run on one server — genuinely additive, no legacy coupling. The
|
|
24
|
+
* key equals the `prf` profile id, so it is self-describing and versioned.
|
|
25
|
+
*/
|
|
26
|
+
export declare const KYA_OS_CARD_PROOF_META_KEY = "org.kya-os/proof@1";
|
|
27
|
+
/** Default proof lifetime in seconds (SPEC §8: short-lived, ≤ 60s). */
|
|
28
|
+
export declare const DEFAULT_TTL_SEC = 60;
|
|
29
|
+
/** Maximum accepted proof lifetime in seconds — a longer window fails closed. */
|
|
30
|
+
export declare const MAX_TTL_SEC = 60;
|
|
31
|
+
/** Default accepted clock skew in seconds (±) for the created/expires window. */
|
|
32
|
+
export declare const DEFAULT_SKEW_SEC = 5;
|
|
33
|
+
/**
|
|
34
|
+
* Minimum time a consumed nonce MUST be retained by the replay cache: the FULL verifier
|
|
35
|
+
* acceptance window, PLUS one second of rounding headroom. A proof is accepted while
|
|
36
|
+
* `created - skew ≤ now ≤ expires + skew` (with `expires = created + ttl`) — a window `ttl + 2·skew`
|
|
37
|
+
* wide. But the verifier compares at SECOND granularity and is inclusive at the top, so the last
|
|
38
|
+
* accepting second is honoured in full (up to +999 ms), while a nonce first consumed at the very
|
|
39
|
+
* start of the `created - skew` second is retained from there. Retaining for exactly `ttl + 2·skew`
|
|
40
|
+
* therefore leaves a sub-second tail in which an evicted nonce lets a still-valid proof replay; the
|
|
41
|
+
* `+ 1` closes it. Retention is measured from FIRST use. If a verifier widens `skewSec` beyond
|
|
42
|
+
* {@link DEFAULT_SKEW_SEC}, widen the cache TTL to match.
|
|
43
|
+
*/
|
|
44
|
+
export declare const NONCE_RETENTION_SEC: number;
|
|
45
|
+
/** RFC 7638 confirmation key thumbprint (`cnf.jkt`) — the sender-constraint fusion anchor. */
|
|
46
|
+
export declare const CardProofCnfSchema: z.ZodObject<{
|
|
47
|
+
jkt: z.ZodString;
|
|
48
|
+
}, z.core.$strip>;
|
|
49
|
+
/**
|
|
50
|
+
* The `org.kya-os/proof@1` payload. Every field except the two signatures (`jws`, `httpSig`) is a
|
|
51
|
+
* COVERED claim: the detached EdDSA `jws` signs the RFC 8785 (JCS) canonicalization of the claims,
|
|
52
|
+
* so tampering any of them fails the signature. `cnf.jkt` is OPTIONAL — present it degrades to
|
|
53
|
+
* L3-minus rather than blocking when the authorization server does not emit an RFC 9449 `cnf`.
|
|
54
|
+
*
|
|
55
|
+
* `httpSig` is the OPTIONAL second signature of the DUAL carrier: a RAW EdDSA signature (base64url,
|
|
56
|
+
* NOT JWS-framed) made by the SAME DID key over the RFC 9421 signature base the HTTP Message
|
|
57
|
+
* Signature sibling exposes. Because it is a raw signature over the exact base a stock RFC 9421
|
|
58
|
+
* verifier reconstructs, that sibling is genuinely cross-verifiable against the resolved DID key
|
|
59
|
+
* (the `jws` framing prepends a protected header, so its bytes could never satisfy a 9421 verifier).
|
|
60
|
+
* It degrades gracefully: a signer without a `signRaw` seam mints a JWS-only proof (no sibling).
|
|
61
|
+
*/
|
|
62
|
+
export declare const CardProofMetaSchema: z.ZodObject<{
|
|
63
|
+
prf: z.ZodLiteral<"org.kya-os/proof@1">;
|
|
64
|
+
alg: z.ZodEnum<{
|
|
65
|
+
EdDSA: "EdDSA";
|
|
66
|
+
ES256: "ES256";
|
|
67
|
+
}>;
|
|
68
|
+
did: z.ZodString;
|
|
69
|
+
kid: z.ZodString;
|
|
70
|
+
audience: z.ZodString;
|
|
71
|
+
nonce: z.ZodString;
|
|
72
|
+
created: z.ZodNumber;
|
|
73
|
+
expires: z.ZodNumber;
|
|
74
|
+
requestHash: z.ZodString;
|
|
75
|
+
cnf: z.ZodOptional<z.ZodObject<{
|
|
76
|
+
jkt: z.ZodString;
|
|
77
|
+
}, z.core.$strip>>;
|
|
78
|
+
jws: z.ZodString;
|
|
79
|
+
httpSig: z.ZodOptional<z.ZodString>;
|
|
80
|
+
}, z.core.$strict>;
|
|
81
|
+
export type CardProofCnf = z.infer<typeof CardProofCnfSchema>;
|
|
82
|
+
export type CardProofMeta = z.infer<typeof CardProofMetaSchema>;
|
|
83
|
+
/** An Ed25519 private JWK (OKP, carries `d`) — the signer's key material, never serialized out. */
|
|
84
|
+
export interface Ed25519PrivateJwk {
|
|
85
|
+
kty: 'OKP';
|
|
86
|
+
crv: 'Ed25519';
|
|
87
|
+
x: string;
|
|
88
|
+
d: string;
|
|
89
|
+
kid?: string;
|
|
90
|
+
}
|
|
91
|
+
/** A P-256 private JWK (EC, carries `d`) — the ES256 signer's key material. */
|
|
92
|
+
export interface P256PrivateJwk {
|
|
93
|
+
kty: 'EC';
|
|
94
|
+
crv: 'P-256';
|
|
95
|
+
x: string;
|
|
96
|
+
y: string;
|
|
97
|
+
d: string;
|
|
98
|
+
kid?: string;
|
|
99
|
+
}
|
|
100
|
+
/** A proof-signing private JWK — Ed25519 (EdDSA) or P-256 (ES256). */
|
|
101
|
+
export type ProofPrivateJwk = Ed25519PrivateJwk | P256PrivateJwk;
|
|
102
|
+
/**
|
|
103
|
+
* The minting seam. Holds the entity's identity coordinates + an opaque detached-JWS signer;
|
|
104
|
+
* the module never touches raw key material. `jkt` is the RFC 7638 thumbprint of the signing
|
|
105
|
+
* key, embedded as `cnf.jkt` unless the build context overrides it.
|
|
106
|
+
*/
|
|
107
|
+
export interface ProofSigner {
|
|
108
|
+
readonly did: string;
|
|
109
|
+
readonly kid: string;
|
|
110
|
+
readonly jkt?: string;
|
|
111
|
+
/** The signing algorithm this signer produces — `EdDSA` (Ed25519) or `ES256` (P-256). Default `EdDSA`. */
|
|
112
|
+
readonly alg?: 'EdDSA' | 'ES256';
|
|
113
|
+
/** Produce a DETACHED JWS (`protectedHeader..signature`) over `payload`, signed with {@link alg}. */
|
|
114
|
+
sign(payload: Uint8Array): Promise<string>;
|
|
115
|
+
/**
|
|
116
|
+
* OPTIONAL: produce a RAW EdDSA signature (base64url, NOT JWS-framed) over `payload` with the
|
|
117
|
+
* SAME key as {@link sign}. Enables the dual-carrier RFC 9421 sibling — the raw signature over
|
|
118
|
+
* the 9421 base is what a stock 9421 verifier reconstructs and checks against the DID key. A
|
|
119
|
+
* signer that omits this mints a JWS-only proof (the sibling degrades away, never breaks).
|
|
120
|
+
*/
|
|
121
|
+
signRaw?(payload: Uint8Array): Promise<string>;
|
|
122
|
+
}
|
|
123
|
+
/** Per-request minting context: who the proof is for, its nonce, lifetime, and cnf override. */
|
|
124
|
+
export interface BuildProofContext {
|
|
125
|
+
/** Recipient DID (anti-confused-deputy / anti-relay binding). */
|
|
126
|
+
audience: string;
|
|
127
|
+
/** 128-bit nonce (client-random or server-issued). */
|
|
128
|
+
nonce: string;
|
|
129
|
+
/** Proof lifetime in seconds (default {@link DEFAULT_TTL_SEC}). */
|
|
130
|
+
ttlSec?: number;
|
|
131
|
+
/** Explicit `cnf.jkt` (e.g. the token's RFC 9449 thumbprint); default: the signer's `jkt`. */
|
|
132
|
+
cnfJkt?: string;
|
|
133
|
+
/** Injectable clock returning epoch MILLISECONDS (deterministic tests). */
|
|
134
|
+
now?: () => number;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Resolve the Ed25519 public key registered for a `kid`.
|
|
138
|
+
*
|
|
139
|
+
* CONTRACT (this seam is a SECURITY BOUNDARY): the resolver MUST resolve the EXACT `did#fragment`
|
|
140
|
+
* from the AUTHORITATIVE DID document and return ONLY the key genuinely published at that
|
|
141
|
+
* verificationMethod — never a key that merely shares the DID prefix, and never a caller-supplied
|
|
142
|
+
* key taken on trust. A secure verifier supplies {@link ResolveDidKeys} for an independent RFC 7638
|
|
143
|
+
* membership proof; without it the verifier FAILS CLOSED unless you attest THIS resolver is
|
|
144
|
+
* authoritative via `trustResolveKeyAuthority` (in which case this contract is the sole binding).
|
|
145
|
+
*
|
|
146
|
+
* Fail-closed: throw when the `kid` is unresolvable (the verifier records `key_unresolvable`).
|
|
147
|
+
*/
|
|
148
|
+
export type ResolveKey = (kid: string) => ProofPublicJwk | Promise<ProofPublicJwk>;
|
|
149
|
+
/** List the Ed25519 verification keys published by a DID document — the DID-membership seam. */
|
|
150
|
+
export type ResolveDidKeys = (did: string) => ProofPublicJwk[] | Promise<ProofPublicJwk[]>;
|
|
151
|
+
/**
|
|
152
|
+
* Replay seam — the ATOMIC test-AND-set (SPEC §12.2). It MUST atomically RECORD `nonce` for `did`
|
|
153
|
+
* and return `true` iff the nonce was NOT already recorded (still unexpired); on a replay it MUST
|
|
154
|
+
* return `false` and leave the prior record intact. The record-AND-check MUST be one atomic step:
|
|
155
|
+
* the verifier treats a `true` return as proof the nonce is single-use, so a pure read that never
|
|
156
|
+
* persists the nonce (e.g. `(n) => !seen.has(n)` where `seen` is never written) is a replay HOLE —
|
|
157
|
+
* it compiles and provides ZERO protection. Scope the record by `did` to prevent cross-DID replay.
|
|
158
|
+
* Reach for the batteries-included {@link InMemoryNonceCache} (race-free) or
|
|
159
|
+
* {@link consumeFromNonceCacheProvider} rather than hand-rolling this.
|
|
160
|
+
*/
|
|
161
|
+
export type ConsumeNonceIfFresh = (nonce: string, did: string) => boolean | Promise<boolean>;
|
|
162
|
+
/**
|
|
163
|
+
* The verification seams. `resolveKey` resolves the signing key by `kid`. `resolveDidKeys` is the
|
|
164
|
+
* INDEPENDENT RFC 7638 DID-membership proof (the signing key MUST be a verificationMethod the proof's
|
|
165
|
+
* `did` publishes) — it closes the forgeable-principal gap and is what a secure verifier binds on.
|
|
166
|
+
* `tokenCnfJkt` is the OAuth token's RFC 9449 sender-constraint for the cnf fusion; omit for L3-minus.
|
|
167
|
+
*/
|
|
168
|
+
export interface VerifyProofDeps {
|
|
169
|
+
resolveKey: ResolveKey;
|
|
170
|
+
/**
|
|
171
|
+
* The DID-membership seam: returns every Ed25519 verificationMethod the proof's `did` publishes,
|
|
172
|
+
* so the verifier can PROVE (RFC 7638 thumbprint) the signing key really belongs to that principal.
|
|
173
|
+
* SUPPLY THIS for any production verifier — it is the only independent binding of key → principal.
|
|
174
|
+
*/
|
|
175
|
+
resolveDidKeys?: ResolveDidKeys;
|
|
176
|
+
/**
|
|
177
|
+
* INSECURE escape hatch — default `false` (secure). With no {@link ResolveDidKeys} seam there is no
|
|
178
|
+
* independent membership proof, so the verifier FAILS CLOSED (`did_membership_unverifiable`) by
|
|
179
|
+
* default rather than trust an unbound key. Set `true` ONLY when you attest that your
|
|
180
|
+
* {@link ResolveKey} is itself AUTHORITATIVE — it resolves the exact `did#fragment` from the DID
|
|
181
|
+
* document and returns ONLY that published key (dev/test, or a trusted internal resolver). In that
|
|
182
|
+
* mode binding rests on the `kid`-prefix check plus your resolveKey contract. Prefer `resolveDidKeys`.
|
|
183
|
+
*/
|
|
184
|
+
trustResolveKeyAuthority?: boolean;
|
|
185
|
+
/** The verifier's own DID — the proof's `audience` MUST equal this (anti-relay). */
|
|
186
|
+
expectedAudience: string;
|
|
187
|
+
/** The access token's RFC 9449 `cnf.jkt` (enables L3 fusion); omit for L3-minus. */
|
|
188
|
+
tokenCnfJkt?: string;
|
|
189
|
+
/**
|
|
190
|
+
* Replay defense — the ATOMIC test-AND-set that records the nonce and returns `false` on a replay
|
|
191
|
+
* (SPEC §12.2). Wire {@link InMemoryNonceCache}'s `consume` (single-process, race-free) or
|
|
192
|
+
* {@link consumeFromNonceCacheProvider} (over a shared store). When it is omitted the verifier
|
|
193
|
+
* FAILS CLOSED (`nonce_seam_missing`) rather than skipping replay defense.
|
|
194
|
+
*/
|
|
195
|
+
consumeNonceIfFresh?: ConsumeNonceIfFresh;
|
|
196
|
+
/** Injectable clock returning epoch MILLISECONDS (deterministic tests). */
|
|
197
|
+
now?: () => number;
|
|
198
|
+
/** Accepted clock skew in seconds (default {@link DEFAULT_SKEW_SEC}). */
|
|
199
|
+
skewSec?: number;
|
|
200
|
+
}
|
|
201
|
+
/** Assurance a valid proof carries: L3 on full cnf fusion, L3-minus without an AS `cnf`. */
|
|
202
|
+
export type ProofAssurance = 'L3' | 'L3-minus';
|
|
203
|
+
/** The result of {@link verifyCardProof} — `ok` iff there are no `reasons` (fail-closed). */
|
|
204
|
+
export interface ProofVerifyResult {
|
|
205
|
+
ok: boolean;
|
|
206
|
+
reasons: string[];
|
|
207
|
+
/** Present only when `ok`: the derived assurance and the accountable principal DID. */
|
|
208
|
+
level?: ProofAssurance;
|
|
209
|
+
did?: string;
|
|
210
|
+
/**
|
|
211
|
+
* Non-fatal diagnostics. Unlike `reasons`, these do NOT affect `ok` — the proof is valid — but
|
|
212
|
+
* flag a configuration state a caller should be able to observe. Currently:
|
|
213
|
+
* `cnf_present_but_token_unfused` — the proof carried a sender-constraint (`cnf`) that could not be
|
|
214
|
+
* fused because the verifier was given no token `cnf.jkt` (`tokenCnfJkt`), so assurance is L3-minus,
|
|
215
|
+
* not L3. Surfaced so an integrator who intended L3 sees the downgrade instead of it passing silently.
|
|
216
|
+
*/
|
|
217
|
+
warnings?: string[];
|
|
218
|
+
}
|
|
219
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/card/proof/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KYA-OS Entity Card — stateless per-request holder-of-key proof: shapes + seams.
|
|
3
|
+
*
|
|
4
|
+
* `org.kya-os/proof@1` is the STATELESS, sender-constrained proof profile. It rides its OWN
|
|
5
|
+
* `_meta` key ({@link KYA_OS_CARD_PROOF_META_KEY} = `org.kya-os/proof@1`), DISTINCT from the legacy
|
|
6
|
+
* session-bound `ProofMeta` (which carries `sessionId` + a handshake nonce under
|
|
7
|
+
* `org.kya-os/proof`). Separate keys let the two regimes coexist on one server without either guard
|
|
8
|
+
* seeing — or rejecting — the other's proof. Every request self-proves; there is no session state.
|
|
9
|
+
*
|
|
10
|
+
* All crypto is INJECTED via seams ({@link ProofSigner} for minting, {@link VerifyProofDeps}
|
|
11
|
+
* for verifying) so no runtime (`mcp-i-core`) dependency leaks into `@kya-os/mcp`; the module
|
|
12
|
+
* uses only `jose` + `json-canonicalize`, already direct dependencies.
|
|
13
|
+
*/
|
|
14
|
+
import { z } from 'zod';
|
|
15
|
+
import { Did, PROOF_PROFILE_ID } from '../schema.js';
|
|
16
|
+
/** The stateless per-request proof profile tag (the `prf` discriminator). */
|
|
17
|
+
export const PROOF_PROFILE_V1 = PROOF_PROFILE_ID;
|
|
18
|
+
/**
|
|
19
|
+
* The `_meta` key the STATELESS card proof rides under — DISTINCT from the legacy session proof's
|
|
20
|
+
* `org.kya-os/proof` (`KYA_OS_PROOF_META_KEY`). Sharing one key made the two regimes mutually
|
|
21
|
+
* exclusive on a server (a legacy proof failed the card schema and was 401'd; a card proof failed
|
|
22
|
+
* the legacy structure check). With separate keys each guard reads its OWN key and simply does not
|
|
23
|
+
* see the other's proof, so both can run on one server — genuinely additive, no legacy coupling. The
|
|
24
|
+
* key equals the `prf` profile id, so it is self-describing and versioned.
|
|
25
|
+
*/
|
|
26
|
+
export const KYA_OS_CARD_PROOF_META_KEY = PROOF_PROFILE_V1;
|
|
27
|
+
/** Default proof lifetime in seconds (SPEC §8: short-lived, ≤ 60s). */
|
|
28
|
+
export const DEFAULT_TTL_SEC = 60;
|
|
29
|
+
/** Maximum accepted proof lifetime in seconds — a longer window fails closed. */
|
|
30
|
+
export const MAX_TTL_SEC = 60;
|
|
31
|
+
/** Default accepted clock skew in seconds (±) for the created/expires window. */
|
|
32
|
+
export const DEFAULT_SKEW_SEC = 5;
|
|
33
|
+
/**
|
|
34
|
+
* Minimum time a consumed nonce MUST be retained by the replay cache: the FULL verifier
|
|
35
|
+
* acceptance window, PLUS one second of rounding headroom. A proof is accepted while
|
|
36
|
+
* `created - skew ≤ now ≤ expires + skew` (with `expires = created + ttl`) — a window `ttl + 2·skew`
|
|
37
|
+
* wide. But the verifier compares at SECOND granularity and is inclusive at the top, so the last
|
|
38
|
+
* accepting second is honoured in full (up to +999 ms), while a nonce first consumed at the very
|
|
39
|
+
* start of the `created - skew` second is retained from there. Retaining for exactly `ttl + 2·skew`
|
|
40
|
+
* therefore leaves a sub-second tail in which an evicted nonce lets a still-valid proof replay; the
|
|
41
|
+
* `+ 1` closes it. Retention is measured from FIRST use. If a verifier widens `skewSec` beyond
|
|
42
|
+
* {@link DEFAULT_SKEW_SEC}, widen the cache TTL to match.
|
|
43
|
+
*/
|
|
44
|
+
export const NONCE_RETENTION_SEC = MAX_TTL_SEC + 2 * DEFAULT_SKEW_SEC + 1;
|
|
45
|
+
/**
|
|
46
|
+
* base64url charset (RFC 4648 §5, no padding). `nonce` and `cnf.jkt` are embedded VERBATIM into the
|
|
47
|
+
* line-oriented RFC 9421 signature base (see `http-sig.ts`: `"kya-nonce": ${nonce}` / `"kya-cnf":
|
|
48
|
+
* ${jkt}`), so a newline — or any non-base64url byte — would corrupt that base. RFC 7638 thumbprints
|
|
49
|
+
* are base64url by definition, and a 128-bit nonce is CSPRNG base64url/hex, so we reject anything
|
|
50
|
+
* else EARLY at build/parse rather than leaning on the downstream verifier's base reconstruction to
|
|
51
|
+
* fail closed. (`did`/`audience` are DIDs, guarded by {@link Did}; `kid` is guarded below.)
|
|
52
|
+
*/
|
|
53
|
+
const BASE64URL = /^[A-Za-z0-9_-]+$/;
|
|
54
|
+
/** RFC 7638 confirmation key thumbprint (`cnf.jkt`) — the sender-constraint fusion anchor. */
|
|
55
|
+
export const CardProofCnfSchema = z.object({
|
|
56
|
+
jkt: z.string().min(1).regex(BASE64URL, 'cnf.jkt must be a base64url RFC 7638 thumbprint'),
|
|
57
|
+
});
|
|
58
|
+
/**
|
|
59
|
+
* The `org.kya-os/proof@1` payload. Every field except the two signatures (`jws`, `httpSig`) is a
|
|
60
|
+
* COVERED claim: the detached EdDSA `jws` signs the RFC 8785 (JCS) canonicalization of the claims,
|
|
61
|
+
* so tampering any of them fails the signature. `cnf.jkt` is OPTIONAL — present it degrades to
|
|
62
|
+
* L3-minus rather than blocking when the authorization server does not emit an RFC 9449 `cnf`.
|
|
63
|
+
*
|
|
64
|
+
* `httpSig` is the OPTIONAL second signature of the DUAL carrier: a RAW EdDSA signature (base64url,
|
|
65
|
+
* NOT JWS-framed) made by the SAME DID key over the RFC 9421 signature base the HTTP Message
|
|
66
|
+
* Signature sibling exposes. Because it is a raw signature over the exact base a stock RFC 9421
|
|
67
|
+
* verifier reconstructs, that sibling is genuinely cross-verifiable against the resolved DID key
|
|
68
|
+
* (the `jws` framing prepends a protected header, so its bytes could never satisfy a 9421 verifier).
|
|
69
|
+
* It degrades gracefully: a signer without a `signRaw` seam mints a JWS-only proof (no sibling).
|
|
70
|
+
*/
|
|
71
|
+
export const CardProofMetaSchema = z.object({
|
|
72
|
+
prf: z.literal(PROOF_PROFILE_V1),
|
|
73
|
+
alg: z.enum(['EdDSA', 'ES256']),
|
|
74
|
+
did: Did,
|
|
75
|
+
// The signing key reference MUST carry a `#fragment` (a verificationMethod id); the runtime also
|
|
76
|
+
// binds `kid.split('#')[0] === did`. did:key is base58btc, so the fragment is case-SENSITIVE.
|
|
77
|
+
kid: z.string().regex(/^did:(key|web):.+#.+$/, 'kid must be a DID with a #fragment (e.g. did:web:host#key-1)'),
|
|
78
|
+
audience: Did,
|
|
79
|
+
nonce: z.string().min(1).regex(BASE64URL, 'nonce must be base64url-safe (it is embedded verbatim in the RFC 9421 signature base)'),
|
|
80
|
+
created: z.number().int().nonnegative(),
|
|
81
|
+
expires: z.number().int().nonnegative(),
|
|
82
|
+
requestHash: z.string().min(1),
|
|
83
|
+
cnf: CardProofCnfSchema.optional(),
|
|
84
|
+
jws: z.string().min(1),
|
|
85
|
+
httpSig: z.string().min(1).optional(),
|
|
86
|
+
}).strict(); // no unknown fields: the covered-claims set IS the signed contract (matches schema.ts)
|
|
87
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/card/proof/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,GAAG,EAAE,gBAAgB,EAAuB,MAAM,cAAc,CAAC;AAE1E,6EAA6E;AAC7E,MAAM,CAAC,MAAM,gBAAgB,GAAG,gBAAgB,CAAC;AAEjD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,gBAAgB,CAAC;AAE3D,uEAAuE;AACvE,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAC;AAElC,iFAAiF;AACjF,MAAM,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAE9B,iFAAiF;AACjF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAElC;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,WAAW,GAAG,CAAC,GAAG,gBAAgB,GAAG,CAAC,CAAC;AAE1E;;;;;;;GAOG;AACH,MAAM,SAAS,GAAG,kBAAkB,CAAC;AAErC,8FAA8F;AAC9F,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,iDAAiD,CAAC;CAC3F,CAAC,CAAC;AAEH;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC;IAChC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC/B,GAAG,EAAE,GAAG;IACR,iGAAiG;IACjG,8FAA8F;IAC9F,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,uBAAuB,EAAE,8DAA8D,CAAC;IAC9G,QAAQ,EAAE,GAAG;IACb,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,uFAAuF,CAAC;IAClI,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IACvC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IACvC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,GAAG,EAAE,kBAAkB,CAAC,QAAQ,EAAE;IAClC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACtB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CACtC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,uFAAuF"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KYA-OS Entity Card proof — VERIFY (`verifyCardProof`), fail-closed.
|
|
3
|
+
*
|
|
4
|
+
* Recompute EVERY binding a stateless `org.kya-os/proof@1` asserts and reject on the first thing
|
|
5
|
+
* that does not hold. The signature only proves the proof is AUTHENTIC (signed by the holder of
|
|
6
|
+
* `kid`); accountability requires binding that key to the accountable principal `did`:
|
|
7
|
+
*
|
|
8
|
+
* 1. `kid`'s DID part MUST equal `proof.did` (`kid.split('#')[0] === did`) — closes the
|
|
9
|
+
* forgeable-principal gap where a proof claims a victim `did` while `kid` points elsewhere;
|
|
10
|
+
* 2. the resolved signing key MUST be a verificationMethod of `proof.did`, via the injected
|
|
11
|
+
* `resolveDidKeys` seam (RFC 7638 thumbprint membership) — closes a key that merely shares
|
|
12
|
+
* the DID's `kid` prefix but is not actually published by that DID.
|
|
13
|
+
*
|
|
14
|
+
* Plus: `audience` → the verifier, `requestHash` → THIS body, `nonce` → unseen, `created`/`expires`
|
|
15
|
+
* → NOW (±skew), the detached JWS → the covered claims, and the `cnf.jkt` fusion
|
|
16
|
+
* (`token.cnf.jkt === proof.cnf.jkt === thumbprint(resolve(kid))`). Any failure appends a reason;
|
|
17
|
+
* `ok` is true iff there are none.
|
|
18
|
+
*/
|
|
19
|
+
import type { ToolRequest } from '../../proof/generator.js';
|
|
20
|
+
import { type ProofVerifyResult, type VerifyProofDeps } from './types.js';
|
|
21
|
+
/**
|
|
22
|
+
* Verify an `org.kya-os/proof@1` against the request it should bind and the injected seams.
|
|
23
|
+
* Fail-closed: returns `{ ok:false, reasons }` on any broken binding; on success returns the
|
|
24
|
+
* derived assurance (`L3` on full cnf fusion, `L3-minus` without an AS `cnf`) and the principal.
|
|
25
|
+
*/
|
|
26
|
+
export declare function verifyCardProof(proof: unknown, req: ToolRequest, deps: VerifyProofDeps): Promise<ProofVerifyResult>;
|
|
27
|
+
//# sourceMappingURL=verify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../../src/card/proof/verify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAG5D,OAAO,EAML,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACrB,MAAM,YAAY,CAAC;AAEpB;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,OAAO,EACd,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC,iBAAiB,CAAC,CAmC5B"}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KYA-OS Entity Card proof — VERIFY (`verifyCardProof`), fail-closed.
|
|
3
|
+
*
|
|
4
|
+
* Recompute EVERY binding a stateless `org.kya-os/proof@1` asserts and reject on the first thing
|
|
5
|
+
* that does not hold. The signature only proves the proof is AUTHENTIC (signed by the holder of
|
|
6
|
+
* `kid`); accountability requires binding that key to the accountable principal `did`:
|
|
7
|
+
*
|
|
8
|
+
* 1. `kid`'s DID part MUST equal `proof.did` (`kid.split('#')[0] === did`) — closes the
|
|
9
|
+
* forgeable-principal gap where a proof claims a victim `did` while `kid` points elsewhere;
|
|
10
|
+
* 2. the resolved signing key MUST be a verificationMethod of `proof.did`, via the injected
|
|
11
|
+
* `resolveDidKeys` seam (RFC 7638 thumbprint membership) — closes a key that merely shares
|
|
12
|
+
* the DID's `kid` prefix but is not actually published by that DID.
|
|
13
|
+
*
|
|
14
|
+
* Plus: `audience` → the verifier, `requestHash` → THIS body, `nonce` → unseen, `created`/`expires`
|
|
15
|
+
* → NOW (±skew), the detached JWS → the covered claims, and the `cnf.jkt` fusion
|
|
16
|
+
* (`token.cnf.jkt === proof.cnf.jkt === thumbprint(resolve(kid))`). Any failure appends a reason;
|
|
17
|
+
* `ok` is true iff there are none.
|
|
18
|
+
*/
|
|
19
|
+
import { calculateJwkThumbprint, flattenedVerify, importJWK } from 'jose';
|
|
20
|
+
import { base64urlDecodeToString, base64urlEncodeFromBytes } from '../../utils/base64.js';
|
|
21
|
+
import { canonicalPayloadBytes, computeRequestHash } from './canonical.js';
|
|
22
|
+
import { CardProofMetaSchema, DEFAULT_SKEW_SEC, MAX_TTL_SEC, } from './types.js';
|
|
23
|
+
/**
|
|
24
|
+
* Verify an `org.kya-os/proof@1` against the request it should bind and the injected seams.
|
|
25
|
+
* Fail-closed: returns `{ ok:false, reasons }` on any broken binding; on success returns the
|
|
26
|
+
* derived assurance (`L3` on full cnf fusion, `L3-minus` without an AS `cnf`) and the principal.
|
|
27
|
+
*/
|
|
28
|
+
export async function verifyCardProof(proof, req, deps) {
|
|
29
|
+
const reasons = [];
|
|
30
|
+
const parsed = CardProofMetaSchema.safeParse(proof);
|
|
31
|
+
if (!parsed.success)
|
|
32
|
+
return { ok: false, reasons: ['malformed_proof'] };
|
|
33
|
+
const meta = parsed.data;
|
|
34
|
+
if (meta.kid.split('#')[0] !== meta.did)
|
|
35
|
+
reasons.push('kid_did_mismatch');
|
|
36
|
+
// `resolveKey` (DID-key resolution, possibly a network fetch) and `computeRequestHash` (local JCS +
|
|
37
|
+
// SHA-256) are INDEPENDENT — run them concurrently. Fail-closed semantics are unchanged: each still
|
|
38
|
+
// appends its own reason. Caching the resolved key belongs at the injected `resolveKey` seam (the
|
|
39
|
+
// consumer owns it); verifyCardProof stays a pure, stateless function — no cross-tenant global cache.
|
|
40
|
+
const [key, computedHash] = await Promise.all([resolveKey(meta.kid, deps, reasons), computeRequestHash(req)]);
|
|
41
|
+
if (key)
|
|
42
|
+
await assertDidMembership(key, meta.did, deps, reasons);
|
|
43
|
+
// Bind the declared alg to the resolved key type: an ES256 claim MUST carry a P-256 key, an EdDSA
|
|
44
|
+
// claim an Ed25519 key. `alg` is a signed covered claim, but the KEY type is authoritative here —
|
|
45
|
+
// this closes alg/key confusion. Gate the signature check on it so import always uses a matching alg.
|
|
46
|
+
const algOk = key !== undefined && keyMatchesAlg(key, meta.alg);
|
|
47
|
+
if (key && !algOk)
|
|
48
|
+
reasons.push('alg_key_mismatch');
|
|
49
|
+
if (meta.audience !== deps.expectedAudience)
|
|
50
|
+
reasons.push('audience_mismatch');
|
|
51
|
+
if (meta.requestHash !== computedHash)
|
|
52
|
+
reasons.push('request_hash_mismatch');
|
|
53
|
+
checkWindow(meta, deps, reasons);
|
|
54
|
+
await consumeNonce(meta, deps, reasons);
|
|
55
|
+
if (key && algOk && !(await verifyDetachedJws(meta, key)))
|
|
56
|
+
reasons.push('invalid_signature');
|
|
57
|
+
const warnings = [];
|
|
58
|
+
let level = 'L3-minus';
|
|
59
|
+
if (key)
|
|
60
|
+
level = await checkCnfFusion(meta, key, deps, reasons, warnings);
|
|
61
|
+
const ok = reasons.length === 0;
|
|
62
|
+
const withWarnings = warnings.length > 0 ? { warnings } : {};
|
|
63
|
+
return ok
|
|
64
|
+
? { ok, reasons, level, did: meta.did, ...withWarnings }
|
|
65
|
+
: { ok, reasons, ...withWarnings };
|
|
66
|
+
}
|
|
67
|
+
/** Resolve the signing key for `kid`; fail-closed (records `key_unresolvable`) on throw. */
|
|
68
|
+
async function resolveKey(kid, deps, reasons) {
|
|
69
|
+
try {
|
|
70
|
+
return await deps.resolveKey(kid);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
reasons.push('key_unresolvable');
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Cryptographically bind the signing key to `did`: it MUST be one of the DID document's
|
|
79
|
+
* verification keys (RFC 7638 thumbprint membership), via the injected `resolveDidKeys` seam.
|
|
80
|
+
* SECURE BY DEFAULT:
|
|
81
|
+
* - `resolveDidKeys` PRESENT → run the independent membership proof (always);
|
|
82
|
+
* - `resolveDidKeys` ABSENT → there is NO independent proof, so FAIL CLOSED
|
|
83
|
+
* (`did_membership_unverifiable`) unless the caller explicitly attests its `resolveKey` is
|
|
84
|
+
* authoritative via `trustResolveKeyAuthority` (dev/test or a trusted internal resolver).
|
|
85
|
+
* Fail-closed on an unresolvable document.
|
|
86
|
+
*/
|
|
87
|
+
async function assertDidMembership(key, did, deps, reasons) {
|
|
88
|
+
if (!deps.resolveDidKeys) {
|
|
89
|
+
// No membership seam: a minimal verifier must not silently trust an unbound key.
|
|
90
|
+
if (!deps.trustResolveKeyAuthority)
|
|
91
|
+
reasons.push('did_membership_unverifiable');
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
let didKeys;
|
|
95
|
+
try {
|
|
96
|
+
didKeys = await deps.resolveDidKeys(did);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
reasons.push('did_keys_unresolvable');
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
let keyJkt;
|
|
103
|
+
let published;
|
|
104
|
+
try {
|
|
105
|
+
keyJkt = await thumbprint(key);
|
|
106
|
+
published = await Promise.all(didKeys.map(thumbprint));
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
// A structurally-typed but invalid JWK from the seam (jose throws) must fail CLOSED with a
|
|
110
|
+
// reason, never as an unhandled rejection out of verifyCardProof — matches the seam-catch above.
|
|
111
|
+
reasons.push('thumbprint_computation_failed');
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (!published.includes(keyJkt))
|
|
115
|
+
reasons.push('kid_not_in_did_document');
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Atomically CONSUME the nonce via the injected `consumeNonceIfFresh` replay seam (test-AND-set —
|
|
119
|
+
* SPEC §12.2). A `false` return is a replay (`nonce_replayed`). When the seam is not supplied there
|
|
120
|
+
* is no replay defense to run, so we FAIL CLOSED (`nonce_seam_missing`) rather than skip the check.
|
|
121
|
+
*/
|
|
122
|
+
async function consumeNonce(meta, deps, reasons) {
|
|
123
|
+
const consume = deps.consumeNonceIfFresh;
|
|
124
|
+
if (!consume) {
|
|
125
|
+
reasons.push('nonce_seam_missing');
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
if (!(await consume(meta.nonce, meta.did)))
|
|
129
|
+
reasons.push('nonce_replayed');
|
|
130
|
+
}
|
|
131
|
+
/** Enforce the created/expires window: sane bounds, capped TTL, and ±skew freshness. */
|
|
132
|
+
function checkWindow(meta, deps, reasons) {
|
|
133
|
+
const skew = deps.skewSec ?? DEFAULT_SKEW_SEC;
|
|
134
|
+
const now = Math.floor((deps.now?.() ?? Date.now()) / 1000);
|
|
135
|
+
if (meta.expires <= meta.created)
|
|
136
|
+
reasons.push('invalid_window');
|
|
137
|
+
if (meta.expires - meta.created > MAX_TTL_SEC)
|
|
138
|
+
reasons.push('ttl_too_long');
|
|
139
|
+
if (meta.created > now + skew)
|
|
140
|
+
reasons.push('created_in_future');
|
|
141
|
+
if (meta.expires < now - skew)
|
|
142
|
+
reasons.push('expired');
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Verify the DETACHED JWS over the reconstructed covered claims. The header is NOT trusted: its `alg`
|
|
146
|
+
* MUST equal the (schema-allow-listed `EdDSA`|`ES256`, and signed) `meta.alg`, and its `kid` MUST equal
|
|
147
|
+
* `meta.kid`. Verification is PINNED to that single alg — never negotiated. The payload is recomputed
|
|
148
|
+
* from the meta (JCS), so any tampered covered field (including `alg`) yields a different signing input.
|
|
149
|
+
*/
|
|
150
|
+
async function verifyDetachedJws(meta, key) {
|
|
151
|
+
const parts = meta.jws.split('.');
|
|
152
|
+
if (parts.length !== 3 || parts[1] !== '')
|
|
153
|
+
return false;
|
|
154
|
+
const [protectedB64, , signatureB64] = parts;
|
|
155
|
+
const header = decodeHeader(protectedB64);
|
|
156
|
+
if (!header || header.alg !== meta.alg || header.kid !== meta.kid)
|
|
157
|
+
return false;
|
|
158
|
+
try {
|
|
159
|
+
const pub = await importJWK(toJwk(key), meta.alg);
|
|
160
|
+
await flattenedVerify({
|
|
161
|
+
protected: protectedB64,
|
|
162
|
+
payload: base64urlEncodeFromBytes(canonicalPayloadBytes(meta)),
|
|
163
|
+
signature: signatureB64,
|
|
164
|
+
}, pub, { algorithms: [meta.alg] });
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/** True iff the resolved key's type is the one the declared `alg` requires (anti-confusion). */
|
|
172
|
+
function keyMatchesAlg(key, alg) {
|
|
173
|
+
return alg === 'ES256'
|
|
174
|
+
? key.kty === 'EC' && key.crv === 'P-256'
|
|
175
|
+
: key.kty === 'OKP' && key.crv === 'Ed25519';
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* The `cnf.jkt` fusion (SPEC §8): a present `cnf.jkt` MUST equal the signing key's thumbprint,
|
|
179
|
+
* and when the AS supplies a token `cnf.jkt` the three MUST fuse
|
|
180
|
+
* (`token.cnf.jkt === proof.cnf.jkt === thumbprint(resolve(kid))`) for L3. No token `cnf` degrades
|
|
181
|
+
* to L3-minus; a token `cnf` with no proof `cnf` is a downgrade attack and fails closed.
|
|
182
|
+
*/
|
|
183
|
+
async function checkCnfFusion(meta, key, deps, reasons, warnings) {
|
|
184
|
+
let keyJkt;
|
|
185
|
+
try {
|
|
186
|
+
keyJkt = await thumbprint(key);
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
// Same fail-closed contract as assertDidMembership: an invalid JWK denies with a reason.
|
|
190
|
+
reasons.push('thumbprint_computation_failed');
|
|
191
|
+
return 'L3-minus';
|
|
192
|
+
}
|
|
193
|
+
if (meta.cnf && meta.cnf.jkt !== keyJkt)
|
|
194
|
+
reasons.push('cnf_key_mismatch');
|
|
195
|
+
if (deps.tokenCnfJkt === undefined) {
|
|
196
|
+
// No token cnf.jkt was supplied, so there is nothing to fuse against and assurance is L3-minus.
|
|
197
|
+
// If the client nonetheless PRESENTED a sender-constraint (`cnf`), the proof was capable of L3 —
|
|
198
|
+
// it degraded only because `tokenCnfJkt` was not wired. That is a valid L3-minus proof, not a
|
|
199
|
+
// failure, so it is a warning (not a reason): it lets an integrator who intended L3 notice the
|
|
200
|
+
// silent downgrade rather than assume token-theft resistance they are not actually getting.
|
|
201
|
+
if (meta.cnf)
|
|
202
|
+
warnings.push('cnf_present_but_token_unfused');
|
|
203
|
+
return 'L3-minus';
|
|
204
|
+
}
|
|
205
|
+
if (!meta.cnf) {
|
|
206
|
+
reasons.push('cnf_required_by_token');
|
|
207
|
+
return 'L3-minus';
|
|
208
|
+
}
|
|
209
|
+
if (meta.cnf.jkt !== deps.tokenCnfJkt) {
|
|
210
|
+
reasons.push('cnf_token_mismatch');
|
|
211
|
+
return 'L3-minus';
|
|
212
|
+
}
|
|
213
|
+
return meta.cnf.jkt === keyJkt ? 'L3' : 'L3-minus';
|
|
214
|
+
}
|
|
215
|
+
/** Decode a base64url JWS protected header to `{ alg, kid }`, or null on malformed input. */
|
|
216
|
+
function decodeHeader(b64) {
|
|
217
|
+
if (!b64)
|
|
218
|
+
return null;
|
|
219
|
+
try {
|
|
220
|
+
return JSON.parse(base64urlDecodeToString(b64));
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
return null;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
/** The RFC 7638 thumbprint of an Ed25519 public JWK (canonical `{crv,kty,x}` only). */
|
|
227
|
+
function thumbprint(key) {
|
|
228
|
+
return calculateJwkThumbprint(toJwk(key), 'sha256');
|
|
229
|
+
}
|
|
230
|
+
/** Project a proof public JWK to the canonical `jose` JWK (drop `kid`/`use`; EC carries `x`+`y`). */
|
|
231
|
+
function toJwk(key) {
|
|
232
|
+
return key.kty === 'EC'
|
|
233
|
+
? { kty: 'EC', crv: 'P-256', x: key.x, y: key.y }
|
|
234
|
+
: { kty: 'OKP', crv: 'Ed25519', x: key.x };
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../../src/card/proof/verify.ts"],"names":[],"mappings":"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"}
|