@passportsign/core 0.1.0 → 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.
- package/dist/badge.d.ts +5 -0
- package/dist/badge.d.ts.map +1 -1
- package/dist/badge.js +8 -2
- package/dist/badge.js.map +1 -1
- package/dist/bind.d.ts.map +1 -1
- package/dist/bind.js +2 -8
- package/dist/bind.js.map +1 -1
- package/dist/bundle-fs.d.ts +16 -0
- package/dist/bundle-fs.d.ts.map +1 -0
- package/dist/bundle-fs.js +31 -0
- package/dist/bundle-fs.js.map +1 -0
- package/dist/bundle.d.ts +13 -5
- package/dist/bundle.d.ts.map +1 -1
- package/dist/bundle.js +18 -20
- package/dist/bundle.js.map +1 -1
- package/dist/canonical.d.ts.map +1 -1
- package/dist/canonical.js +3 -4
- package/dist/canonical.js.map +1 -1
- package/dist/classify.d.ts +68 -0
- package/dist/classify.d.ts.map +1 -0
- package/dist/classify.js +117 -0
- package/dist/classify.js.map +1 -0
- package/dist/dsse-common.d.ts +32 -0
- package/dist/dsse-common.d.ts.map +1 -0
- package/dist/dsse-common.js +26 -0
- package/dist/dsse-common.js.map +1 -0
- package/dist/dsse-web.d.ts +28 -0
- package/dist/dsse-web.d.ts.map +1 -0
- package/dist/dsse-web.js +81 -0
- package/dist/dsse-web.js.map +1 -0
- package/dist/dsse.d.ts +2 -26
- package/dist/dsse.d.ts.map +1 -1
- package/dist/dsse.js +2 -19
- package/dist/dsse.js.map +1 -1
- package/dist/encoding.d.ts +20 -0
- package/dist/encoding.d.ts.map +1 -0
- package/dist/encoding.js +88 -0
- package/dist/encoding.js.map +1 -0
- package/dist/github.js +2 -2
- package/dist/github.js.map +1 -1
- package/dist/index.d.ts +9 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/dist/log/rekor.d.ts +1 -1
- package/dist/log/rekor.d.ts.map +1 -1
- package/dist/log/rekor.js +7 -10
- package/dist/log/rekor.js.map +1 -1
- package/dist/lookup.d.ts +46 -0
- package/dist/lookup.d.ts.map +1 -0
- package/dist/lookup.js +101 -0
- package/dist/lookup.js.map +1 -0
- package/dist/merkle.js +3 -3
- package/dist/merkle.js.map +1 -1
- package/dist/nonce.js +1 -1
- package/dist/nonce.js.map +1 -1
- package/dist/profile-index.d.ts +64 -0
- package/dist/profile-index.d.ts.map +1 -0
- package/dist/profile-index.js +161 -0
- package/dist/profile-index.js.map +1 -0
- package/dist/revoke.d.ts +30 -0
- package/dist/revoke.d.ts.map +1 -0
- package/dist/revoke.js +42 -0
- package/dist/revoke.js.map +1 -0
- package/dist/sdk-payload.d.ts.map +1 -1
- package/dist/sdk-payload.js +4 -6
- package/dist/sdk-payload.js.map +1 -1
- package/dist/statement.d.ts +41 -0
- package/dist/statement.d.ts.map +1 -1
- package/dist/statement.js +43 -0
- package/dist/statement.js.map +1 -1
- package/dist/submit.d.ts +3 -3
- package/dist/submit.d.ts.map +1 -1
- package/dist/submit.js +3 -14
- package/dist/submit.js.map +1 -1
- package/dist/verifier.d.ts.map +1 -1
- package/dist/verifier.js +4 -14
- package/dist/verifier.js.map +1 -1
- package/dist/web.d.ts +35 -0
- package/dist/web.d.ts.map +1 -0
- package/dist/web.js +35 -0
- package/dist/web.js.map +1 -0
- package/package.json +6 -2
- package/src/badge.ts +124 -113
- package/src/bind.ts +128 -137
- package/src/bundle-fs.ts +40 -0
- package/src/bundle.ts +138 -127
- package/src/canonical.ts +33 -33
- package/src/classify.ts +165 -0
- package/src/dsse-common.ts +45 -0
- package/src/dsse-web.ts +97 -0
- package/src/dsse.ts +63 -91
- package/src/encoding.ts +96 -0
- package/src/github.ts +196 -196
- package/src/index.ts +59 -2
- package/src/log/rekor.ts +330 -334
- package/src/lookup.ts +175 -0
- package/src/merkle.ts +187 -187
- package/src/nonce.ts +53 -53
- package/src/profile-index.ts +222 -0
- package/src/revoke.ts +67 -0
- package/src/sdk-payload.ts +60 -62
- package/src/statement.ts +203 -119
- package/src/submit.ts +38 -54
- package/src/verifier.ts +304 -317
- package/src/web.ts +175 -0
package/dist/statement.js
CHANGED
|
@@ -7,14 +7,22 @@
|
|
|
7
7
|
* `test/fixtures/canonical-vectors.json` pin the canonicalization
|
|
8
8
|
* output for representative statements built here.
|
|
9
9
|
*/
|
|
10
|
+
import { sha256Hex, utf8ToBytes } from './encoding.js';
|
|
10
11
|
export const IN_TOTO_STATEMENT_TYPE = 'https://in-toto.io/Statement/v1';
|
|
11
12
|
export const PASSPORTSIGN_PREDICATE_TYPE = 'https://passportsign.dev/personhood/v1';
|
|
13
|
+
export const PASSPORTSIGN_REVOCATION_PREDICATE_TYPE = 'https://passportsign.dev/personhood/v1#revocation';
|
|
12
14
|
const SHA256_HEX = /^[0-9a-f]{64}$/;
|
|
15
|
+
const REKOR_UUID = /^[0-9a-f]{80}$/;
|
|
13
16
|
function assertSha256Hex(value, field) {
|
|
14
17
|
if (!SHA256_HEX.test(value)) {
|
|
15
18
|
throw new TypeError(`${field}: expected lowercase 64-char hex SHA-256, got ${JSON.stringify(value)}`);
|
|
16
19
|
}
|
|
17
20
|
}
|
|
21
|
+
function assertRekorUuid(value, field) {
|
|
22
|
+
if (!REKOR_UUID.test(value)) {
|
|
23
|
+
throw new TypeError(`${field}: expected 80-char lowercase hex Rekor entry UUID, got ${JSON.stringify(value)}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
18
26
|
function assertNonEmpty(value, field) {
|
|
19
27
|
if (value.length === 0) {
|
|
20
28
|
throw new TypeError(`${field}: must be non-empty`);
|
|
@@ -64,4 +72,39 @@ export function buildStatement(input) {
|
|
|
64
72
|
},
|
|
65
73
|
};
|
|
66
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Build a passportsign revocation statement (spec §7, roadmap v0.5.2).
|
|
77
|
+
*
|
|
78
|
+
* Revocation requires only a fresh proof from the same passport — there
|
|
79
|
+
* are deliberately no gist fields (no GitHub control needed; that's the
|
|
80
|
+
* recovery property). The revocation always targets one concrete
|
|
81
|
+
* binding entry; the subject digest is the sha256 of that entry's UUID
|
|
82
|
+
* string, tying the statement to the artifact it acts on.
|
|
83
|
+
*/
|
|
84
|
+
export function buildRevocationStatement(input) {
|
|
85
|
+
assertRekorUuid(input.revokes_rekor_entry_hash, 'revokes_rekor_entry_hash');
|
|
86
|
+
assertSha256Hex(input.proof_blob_sha256, 'proof_blob_sha256');
|
|
87
|
+
assertNonEmpty(input.github_username, 'github_username');
|
|
88
|
+
assertNonEmpty(input.unique_identifier, 'unique_identifier');
|
|
89
|
+
assertNonEmpty(input.scope, 'scope');
|
|
90
|
+
assertNonEmpty(input.zkpassport_sdk_version, 'zkpassport_sdk_version');
|
|
91
|
+
const subjectDigest = sha256Hex(utf8ToBytes(input.revokes_rekor_entry_hash));
|
|
92
|
+
return {
|
|
93
|
+
_type: IN_TOTO_STATEMENT_TYPE,
|
|
94
|
+
subject: [
|
|
95
|
+
{
|
|
96
|
+
name: `github.com/${input.github_username}`,
|
|
97
|
+
digest: { sha256: subjectDigest },
|
|
98
|
+
},
|
|
99
|
+
],
|
|
100
|
+
predicateType: PASSPORTSIGN_REVOCATION_PREDICATE_TYPE,
|
|
101
|
+
predicate: {
|
|
102
|
+
unique_identifier: input.unique_identifier,
|
|
103
|
+
revokes_rekor_entry_hash: input.revokes_rekor_entry_hash,
|
|
104
|
+
proof_blob_sha256: input.proof_blob_sha256,
|
|
105
|
+
scope: input.scope,
|
|
106
|
+
zkpassport_sdk_version: input.zkpassport_sdk_version,
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
}
|
|
67
110
|
//# sourceMappingURL=statement.js.map
|
package/dist/statement.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"statement.js","sourceRoot":"","sources":["../src/statement.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,CAAC,MAAM,sBAAsB,GAAG,iCAA0C,CAAC;AACjF,MAAM,CAAC,MAAM,2BAA2B,GACtC,wCAAiD,CAAC;
|
|
1
|
+
{"version":3,"file":"statement.js","sourceRoot":"","sources":["../src/statement.ts"],"names":[],"mappings":"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"}
|
package/dist/submit.d.ts
CHANGED
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
* with a {@link RekorClient}. Day 7 calls this to turn a real-passport
|
|
7
7
|
* bind into a public-log entry plus a portable bundle.
|
|
8
8
|
*/
|
|
9
|
-
import { type
|
|
10
|
-
import { type PassportsignBundle } from './bundle.js';
|
|
9
|
+
import { type PassportsignBundle, type SubmittableStatement } from './bundle.js';
|
|
11
10
|
import { type RekorClient, type RekorEntryResponse } from './log/rekor.js';
|
|
11
|
+
export { type SubmittableStatement } from './bundle.js';
|
|
12
12
|
export interface SubmitBindingDeps {
|
|
13
13
|
rekor: RekorClient;
|
|
14
14
|
}
|
|
@@ -22,5 +22,5 @@ export interface SubmitBindingResult {
|
|
|
22
22
|
* `PassportsignError('log_submission_failed', …)` (from the client) on
|
|
23
23
|
* any Rekor failure.
|
|
24
24
|
*/
|
|
25
|
-
export declare function submitBinding(prepared:
|
|
25
|
+
export declare function submitBinding(prepared: SubmittableStatement, deps: SubmitBindingDeps): Promise<SubmitBindingResult>;
|
|
26
26
|
//# sourceMappingURL=submit.d.ts.map
|
package/dist/submit.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"submit.d.ts","sourceRoot":"","sources":["../src/submit.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"submit.d.ts","sourceRoot":"","sources":["../src/submit.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAkB,KAAK,kBAAkB,EAAE,KAAK,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEjG,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAE3E,OAAO,EAAE,KAAK,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAExD,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,WAAW,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,UAAU,EAAE,kBAAkB,CAAC;CAChC;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,oBAAoB,EAC9B,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,mBAAmB,CAAC,CAI9B"}
|
package/dist/submit.js
CHANGED
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
* with a {@link RekorClient}. Day 7 calls this to turn a real-passport
|
|
7
7
|
* bind into a public-log entry plus a portable bundle.
|
|
8
8
|
*/
|
|
9
|
-
import {} from './
|
|
10
|
-
import { BUNDLE_FORMAT_VERSION, validateBundle, } from './bundle.js';
|
|
9
|
+
import { assembleBundle } from './bundle.js';
|
|
11
10
|
import { IN_TOTO_PAYLOAD_TYPE, signEnvelope } from './dsse.js';
|
|
12
11
|
import {} from './log/rekor.js';
|
|
12
|
+
export {} from './bundle.js';
|
|
13
13
|
/**
|
|
14
14
|
* Sign the canonical statement bytes with an ephemeral ECDSA P-256 key,
|
|
15
15
|
* submit the in-toto entry to Rekor, and assemble the bundle. Throws
|
|
@@ -19,17 +19,6 @@ import {} from './log/rekor.js';
|
|
|
19
19
|
export async function submitBinding(prepared, deps) {
|
|
20
20
|
const { envelope } = signEnvelope(prepared.statement_canonical, IN_TOTO_PAYLOAD_TYPE);
|
|
21
21
|
const rekorEntry = await deps.rekor.submitIntoto(envelope);
|
|
22
|
-
|
|
23
|
-
bundle_format_version: BUNDLE_FORMAT_VERSION,
|
|
24
|
-
statement: Buffer.from(prepared.statement_canonical).toString('hex'),
|
|
25
|
-
proof_blob: prepared.proof_blob_b64,
|
|
26
|
-
rekor: {
|
|
27
|
-
log_entry_hash: rekorEntry.uuid,
|
|
28
|
-
inclusion_proof: rekorEntry.verification.inclusionProof,
|
|
29
|
-
log_root_at_submission: rekorEntry.verification.inclusionProof.rootHash,
|
|
30
|
-
},
|
|
31
|
-
};
|
|
32
|
-
validateBundle(bundle);
|
|
33
|
-
return { bundle, rekorEntry };
|
|
22
|
+
return { bundle: assembleBundle(prepared, rekorEntry), rekorEntry };
|
|
34
23
|
}
|
|
35
24
|
//# sourceMappingURL=submit.js.map
|
package/dist/submit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"submit.js","sourceRoot":"","sources":["../src/submit.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"submit.js","sourceRoot":"","sources":["../src/submit.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,cAAc,EAAsD,MAAM,aAAa,CAAC;AACjG,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EAA6C,MAAM,gBAAgB,CAAC;AAE3E,OAAO,EAA6B,MAAM,aAAa,CAAC;AAWxD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,QAA8B,EAC9B,IAAuB;IAEvB,MAAM,EAAE,QAAQ,EAAE,GAAG,YAAY,CAAC,QAAQ,CAAC,mBAAmB,EAAE,oBAAoB,CAAC,CAAC;IACtF,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC3D,OAAO,EAAE,MAAM,EAAE,cAAc,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,UAAU,EAAE,CAAC;AACtE,CAAC"}
|
package/dist/verifier.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verifier.d.ts","sourceRoot":"","sources":["../src/verifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;
|
|
1
|
+
{"version":3,"file":"verifier.d.ts","sourceRoot":"","sources":["../src/verifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,KAAK,kBAAkB,EAAkB,MAAM,aAAa,CAAC;AAEtE,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAIlD,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;AAEtD,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,UAAU,EAAE,WAAW,CAAC;IACxB;;;OAGG;IACH,eAAe,EAAE,WAAW,CAAC;IAC7B;;;;OAIG;IACH,gBAAgB,EAAE,WAAW,CAAC;IAC9B;;;;OAIG;IACH,SAAS,EAAE,WAAW,CAAC;IACvB;;;OAGG;IACH,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACrC,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,OAAO,EAAE,CAAC;IAClB,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,OAAO,CAAC;IAClB,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CACzD;AAED,MAAM,WAAW,gBAAgB;IAC/B,mFAAmF;IACnF,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,sEAAsE;IACtE,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAmBD;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,kBAAkB,EAC1B,IAAI,GAAE,gBAAqB,GAC1B,OAAO,CAAC,kBAAkB,CAAC,CAoI7B"}
|
package/dist/verifier.js
CHANGED
|
@@ -11,23 +11,13 @@
|
|
|
11
11
|
* originalQuery, queryResult). For now `sdk_proof` reports
|
|
12
12
|
* `'pending_day_7'`.
|
|
13
13
|
*/
|
|
14
|
-
import { createHash } from 'node:crypto';
|
|
15
14
|
import { validateBundle } from './bundle.js';
|
|
15
|
+
import { base64ToBytes, bytesToUtf8, hexToBytes, sha256Hex } from './encoding.js';
|
|
16
16
|
import {} from './log/rekor.js';
|
|
17
17
|
import { hashLeaf, verifyConsistency, verifyInclusion } from './merkle.js';
|
|
18
18
|
import { unpackSdkPayload } from './sdk-payload.js';
|
|
19
|
-
function hexToBytes(hex) {
|
|
20
|
-
const out = new Uint8Array(hex.length / 2);
|
|
21
|
-
for (let i = 0; i < out.length; i++) {
|
|
22
|
-
out[i] = parseInt(hex.substr(i * 2, 2), 16);
|
|
23
|
-
}
|
|
24
|
-
return out;
|
|
25
|
-
}
|
|
26
|
-
function sha256Hex(bytes) {
|
|
27
|
-
return createHash('sha256').update(bytes).digest('hex');
|
|
28
|
-
}
|
|
29
19
|
function parseEntryBody(bodyBase64) {
|
|
30
|
-
const bytes =
|
|
20
|
+
const bytes = bytesToUtf8(base64ToBytes(bodyBase64));
|
|
31
21
|
const body = JSON.parse(bytes);
|
|
32
22
|
const spec = body['spec'];
|
|
33
23
|
const content = spec?.['content'];
|
|
@@ -96,7 +86,7 @@ export async function verifyBundle(bundle, deps = {}) {
|
|
|
96
86
|
result.errors.push(`payloadHash mismatch: bundle says ${expectedPayloadHash}, Rekor entry has ${entryPayloadHash}`);
|
|
97
87
|
}
|
|
98
88
|
// 3. inclusion_proof: leaf hash = sha256(0x00 || decoded-body-bytes); verify against captured root.
|
|
99
|
-
const bodyBytes =
|
|
89
|
+
const bodyBytes = base64ToBytes(entry.body);
|
|
100
90
|
const leaf = hashLeaf(bodyBytes);
|
|
101
91
|
const captured = bundle.rekor.inclusion_proof;
|
|
102
92
|
const proofHashes = captured.hashes.map(hexToBytes);
|
|
@@ -169,7 +159,7 @@ async function runSdkVerification(bundle, sdkVerifier, errors) {
|
|
|
169
159
|
// The returned uniqueIdentifier must match the statement's predicate.
|
|
170
160
|
let statementUniqueId;
|
|
171
161
|
try {
|
|
172
|
-
const statementBytes =
|
|
162
|
+
const statementBytes = bytesToUtf8(hexToBytes(bundle.statement));
|
|
173
163
|
const parsed = JSON.parse(statementBytes);
|
|
174
164
|
statementUniqueId = parsed.predicate?.unique_identifier;
|
|
175
165
|
}
|
package/dist/verifier.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verifier.js","sourceRoot":"","sources":["../src/verifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"verifier.js","sourceRoot":"","sources":["../src/verifier.ts"],"names":[],"mappings":"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"}
|
package/dist/web.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@passportsign/core/web` — the runtime-neutral surface.
|
|
3
|
+
*
|
|
4
|
+
* Everything exported here runs on Node, Cloudflare Workers, and
|
|
5
|
+
* browsers: no `node:fs`, no `node:crypto`, no `node:sqlite`, no
|
|
6
|
+
* `Buffer`. The Worker badge service and the browser bind flow import
|
|
7
|
+
* from this subpath; if something node-only sneaks in, their bundlers
|
|
8
|
+
* fail loudly at build time — that's the contract this file enforces.
|
|
9
|
+
*
|
|
10
|
+
* Node-only counterparts stay on the main entry: `readBundle` /
|
|
11
|
+
* `writeBundle` (fs), `signEnvelope` (node crypto; use
|
|
12
|
+
* `signEnvelopeWeb` here), `submitBinding` (composes the node signer;
|
|
13
|
+
* compose `signEnvelopeWeb` + `RekorClient.submitIntoto` +
|
|
14
|
+
* `assembleBundle` instead), and the SQLite cache.
|
|
15
|
+
*/
|
|
16
|
+
export { canonicalize, canonicalSha256Hex } from './canonical.js';
|
|
17
|
+
export { base64ToBytes, bytesToBase64, bytesToHex, bytesToUtf8, hexToBytes, randomBytes, sha256Bytes, sha256Hex, utf8ToBytes, } from './encoding.js';
|
|
18
|
+
export { IN_TOTO_STATEMENT_TYPE, PASSPORTSIGN_PREDICATE_TYPE, PASSPORTSIGN_REVOCATION_PREDICATE_TYPE, buildRevocationStatement, buildStatement, type BuildRevocationStatementInput, type BuildStatementInput, type DisclosureLevel, type PassportsignPredicate, type PassportsignRevocationPredicate, type PassportsignRevocationStatement, type PassportsignStatement, } from './statement.js';
|
|
19
|
+
export { BUNDLE_FORMAT_VERSION, BundleValidationError, assembleBundle, validateBundle, type PassportsignBundle, type RekorBundleFields, type SubmittableStatement, } from './bundle.js';
|
|
20
|
+
export { ERROR_CODES, PassportsignError, type ErrorCode } from './errors.js';
|
|
21
|
+
export { NONCE_BYTES, NONCE_BASE32_LENGTH, base32Encode, generateNonce, } from './nonce.js';
|
|
22
|
+
export { checkGistControl, type CheckGistOptions, type GistEvidence, } from './github.js';
|
|
23
|
+
export { prepareBinding, type PrepareBindingDeps, type PrepareBindingInit, type PrepareBindingInput, type PreparedBinding, } from './bind.js';
|
|
24
|
+
export { prepareRevocation, type PrepareRevocationInput, type PreparedRevocation, } from './revoke.js';
|
|
25
|
+
export { DSSE_VERSION, IN_TOTO_PAYLOAD_TYPE, pae, type DsseEnvelope, type DsseSignature, } from './dsse-common.js';
|
|
26
|
+
export { p1363ToDer, signEnvelopeWeb, type SignEnvelopeWebResult, } from './dsse-web.js';
|
|
27
|
+
export { DEFAULT_REKOR_BASE_URL, PublicSigstoreRekorClient, buildIntotoEntryBody, type InclusionProof, type PublicSigstoreRekorClientOptions, type RekorClient, type RekorEntryResponse, } from './log/rekor.js';
|
|
28
|
+
export { hashLeaf, hashPair, verifyConsistency, verifyInclusion, } from './merkle.js';
|
|
29
|
+
export { packSdkPayload, unpackSdkPayload, type PackedSdkPayload, type SdkPayload, } from './sdk-payload.js';
|
|
30
|
+
export { renderBadgeMarkdown, renderBadgeSvg, type BadgeInput, } from './badge.js';
|
|
31
|
+
export { PROFILE_INDEX_FILENAME, PROFILE_INDEX_VERSION, ProfileIndexValidationError, addBinding, addRevocation, createProfileIndex, fetchProfileIndex, mergeProfileIndexes, profileIndexUrl, validateProfileIndex, type FetchProfileIndexOptions, type ProfileIndex, type ProfileIndexBinding, type ProfileIndexRevocation, } from './profile-index.js';
|
|
32
|
+
export { EntryParseError, STALENESS_WINDOW_MS, classifyBindings, parseIntotoEntry, type BindingState, type ClassifiedBinding, type ClassifyBindingsInput, type InTotoStatement, type ParsedIntotoEntry, } from './classify.js';
|
|
33
|
+
export { lookupBindings, lookupFromIndex, type LookupBindingsDeps, type LookupDeps, type LookupEntryProblem, type LookupResult, } from './lookup.js';
|
|
34
|
+
export { verifyBundle, type BundleVerifyResult, type CheckResult, type SdkVerifier, type SdkVerifyInput, type SdkVerifyResult, type VerifyBundleDeps, } from './verifier.js';
|
|
35
|
+
//# sourceMappingURL=web.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../src/web.ts"],"names":[],"mappings":"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"}
|
package/dist/web.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@passportsign/core/web` — the runtime-neutral surface.
|
|
3
|
+
*
|
|
4
|
+
* Everything exported here runs on Node, Cloudflare Workers, and
|
|
5
|
+
* browsers: no `node:fs`, no `node:crypto`, no `node:sqlite`, no
|
|
6
|
+
* `Buffer`. The Worker badge service and the browser bind flow import
|
|
7
|
+
* from this subpath; if something node-only sneaks in, their bundlers
|
|
8
|
+
* fail loudly at build time — that's the contract this file enforces.
|
|
9
|
+
*
|
|
10
|
+
* Node-only counterparts stay on the main entry: `readBundle` /
|
|
11
|
+
* `writeBundle` (fs), `signEnvelope` (node crypto; use
|
|
12
|
+
* `signEnvelopeWeb` here), `submitBinding` (composes the node signer;
|
|
13
|
+
* compose `signEnvelopeWeb` + `RekorClient.submitIntoto` +
|
|
14
|
+
* `assembleBundle` instead), and the SQLite cache.
|
|
15
|
+
*/
|
|
16
|
+
export { canonicalize, canonicalSha256Hex } from './canonical.js';
|
|
17
|
+
export { base64ToBytes, bytesToBase64, bytesToHex, bytesToUtf8, hexToBytes, randomBytes, sha256Bytes, sha256Hex, utf8ToBytes, } from './encoding.js';
|
|
18
|
+
export { IN_TOTO_STATEMENT_TYPE, PASSPORTSIGN_PREDICATE_TYPE, PASSPORTSIGN_REVOCATION_PREDICATE_TYPE, buildRevocationStatement, buildStatement, } from './statement.js';
|
|
19
|
+
export { BUNDLE_FORMAT_VERSION, BundleValidationError, assembleBundle, validateBundle, } from './bundle.js';
|
|
20
|
+
export { ERROR_CODES, PassportsignError } from './errors.js';
|
|
21
|
+
export { NONCE_BYTES, NONCE_BASE32_LENGTH, base32Encode, generateNonce, } from './nonce.js';
|
|
22
|
+
export { checkGistControl, } from './github.js';
|
|
23
|
+
export { prepareBinding, } from './bind.js';
|
|
24
|
+
export { prepareRevocation, } from './revoke.js';
|
|
25
|
+
export { DSSE_VERSION, IN_TOTO_PAYLOAD_TYPE, pae, } from './dsse-common.js';
|
|
26
|
+
export { p1363ToDer, signEnvelopeWeb, } from './dsse-web.js';
|
|
27
|
+
export { DEFAULT_REKOR_BASE_URL, PublicSigstoreRekorClient, buildIntotoEntryBody, } from './log/rekor.js';
|
|
28
|
+
export { hashLeaf, hashPair, verifyConsistency, verifyInclusion, } from './merkle.js';
|
|
29
|
+
export { packSdkPayload, unpackSdkPayload, } from './sdk-payload.js';
|
|
30
|
+
export { renderBadgeMarkdown, renderBadgeSvg, } from './badge.js';
|
|
31
|
+
export { PROFILE_INDEX_FILENAME, PROFILE_INDEX_VERSION, ProfileIndexValidationError, addBinding, addRevocation, createProfileIndex, fetchProfileIndex, mergeProfileIndexes, profileIndexUrl, validateProfileIndex, } from './profile-index.js';
|
|
32
|
+
export { EntryParseError, STALENESS_WINDOW_MS, classifyBindings, parseIntotoEntry, } from './classify.js';
|
|
33
|
+
export { lookupBindings, lookupFromIndex, } from './lookup.js';
|
|
34
|
+
export { verifyBundle, } from './verifier.js';
|
|
35
|
+
//# sourceMappingURL=web.js.map
|
package/dist/web.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web.js","sourceRoot":"","sources":["../src/web.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAElE,OAAO,EACL,aAAa,EACb,aAAa,EACb,UAAU,EACV,WAAW,EACX,UAAU,EACV,WAAW,EACX,WAAW,EACX,SAAS,EACT,WAAW,GACZ,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,sBAAsB,EACtB,2BAA2B,EAC3B,sCAAsC,EACtC,wBAAwB,EACxB,cAAc,GAQf,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,cAAc,EACd,cAAc,GAIf,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAkB,MAAM,aAAa,CAAC;AAE7E,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,YAAY,EACZ,aAAa,GACd,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,gBAAgB,GAGjB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,cAAc,GAKf,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,iBAAiB,GAGlB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,YAAY,EACZ,oBAAoB,EACpB,GAAG,GAGJ,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,UAAU,EACV,eAAe,GAEhB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,oBAAoB,GAKrB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,iBAAiB,EACjB,eAAe,GAChB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,cAAc,EACd,gBAAgB,GAGjB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,mBAAmB,EACnB,cAAc,GAEf,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,2BAA2B,EAC3B,UAAU,EACV,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EACf,oBAAoB,GAKrB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,GAMjB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,cAAc,EACd,eAAe,GAKhB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,YAAY,GAOb,MAAM,eAAe,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@passportsign/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Core primitives for passportsign: canonical serialization, in-toto Statement v1 builder, binding bundle format, GitHub gist check, Rekor client, RFC 6962 Merkle, DSSE envelope, bundle verifier. Apache-2.0.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"passportsign",
|
|
@@ -31,6 +31,10 @@
|
|
|
31
31
|
"types": "./dist/index.d.ts",
|
|
32
32
|
"default": "./dist/index.js"
|
|
33
33
|
},
|
|
34
|
+
"./web": {
|
|
35
|
+
"types": "./dist/web.d.ts",
|
|
36
|
+
"default": "./dist/web.js"
|
|
37
|
+
},
|
|
34
38
|
"./storage/sqlite": {
|
|
35
39
|
"types": "./dist/storage/sqlite.d.ts",
|
|
36
40
|
"default": "./dist/storage/sqlite.js"
|
|
@@ -49,9 +53,9 @@
|
|
|
49
53
|
"node": ">=22.5"
|
|
50
54
|
},
|
|
51
55
|
"dependencies": {
|
|
56
|
+
"@noble/hashes": "^1.8.0",
|
|
52
57
|
"@truestamp/canonify": "1.0.3"
|
|
53
58
|
},
|
|
54
|
-
"devDependencies": {},
|
|
55
59
|
"scripts": {
|
|
56
60
|
"build": "tsc -p tsconfig.json",
|
|
57
61
|
"test": "vitest run",
|
package/src/badge.ts
CHANGED
|
@@ -1,113 +1,124 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Self-contained inline SVG badge generator for passportsign.
|
|
3
|
-
*
|
|
4
|
-
* v0 ships without a hosted badge service. Maintainers commit the
|
|
5
|
-
* generated `passportsign-badge.svg` to a public repo (typically the
|
|
6
|
-
* `username/username` profile repo) and reference it from their
|
|
7
|
-
* README. GitHub's image proxy renders the SVG; the badge wraps a
|
|
8
|
-
* link to the Rekor entry for click-through verification.
|
|
9
|
-
*
|
|
10
|
-
* Visual: shields.io-style pill, two segments, ~190-280px wide
|
|
11
|
-
* depending on text. Renders with the 10x scale + transform=scale(.1)
|
|
12
|
-
* trick used by shields.io for crisper text rendering.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
export interface BadgeInput {
|
|
16
|
-
github_username: string;
|
|
17
|
-
issuing_country: string | null;
|
|
18
|
-
bound_at: string; // ISO 8601 timestamp
|
|
19
|
-
/** Rekor entry UUID for the `<title>` tooltip. */
|
|
20
|
-
log_entry_hash?: string;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
`<
|
|
90
|
-
`<
|
|
91
|
-
`<
|
|
92
|
-
`<
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Self-contained inline SVG badge generator for passportsign.
|
|
3
|
+
*
|
|
4
|
+
* v0 ships without a hosted badge service. Maintainers commit the
|
|
5
|
+
* generated `passportsign-badge.svg` to a public repo (typically the
|
|
6
|
+
* `username/username` profile repo) and reference it from their
|
|
7
|
+
* README. GitHub's image proxy renders the SVG; the badge wraps a
|
|
8
|
+
* link to the Rekor entry for click-through verification.
|
|
9
|
+
*
|
|
10
|
+
* Visual: shields.io-style pill, two segments, ~190-280px wide
|
|
11
|
+
* depending on text. Renders with the 10x scale + transform=scale(.1)
|
|
12
|
+
* trick used by shields.io for crisper text rendering.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
export interface BadgeInput {
|
|
16
|
+
github_username: string;
|
|
17
|
+
issuing_country: string | null;
|
|
18
|
+
bound_at: string; // ISO 8601 timestamp
|
|
19
|
+
/** Rekor entry UUID for the `<title>` tooltip. */
|
|
20
|
+
log_entry_hash?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Binding state (spec §4 color logic). Defaults to `'active'` so
|
|
23
|
+
* v0-era callers (static badges) are unchanged.
|
|
24
|
+
*/
|
|
25
|
+
state?: 'active' | 'stale' | 'revoked';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const LABEL = 'passportsign';
|
|
29
|
+
const STATE_COLORS = {
|
|
30
|
+
active: '#4c1',
|
|
31
|
+
stale: '#dfb317',
|
|
32
|
+
revoked: '#e05d44',
|
|
33
|
+
} as const;
|
|
34
|
+
const CHAR_WIDTH_PX = 7; // Approx Verdana 11pt character width
|
|
35
|
+
const SIDE_PADDING_PX = 8;
|
|
36
|
+
|
|
37
|
+
function escapeXml(s: string): string {
|
|
38
|
+
return s.replace(/[<>&"']/g, (c) => {
|
|
39
|
+
switch (c) {
|
|
40
|
+
case '<': return '<';
|
|
41
|
+
case '>': return '>';
|
|
42
|
+
case '&': return '&';
|
|
43
|
+
case '"': return '"';
|
|
44
|
+
case "'": return ''';
|
|
45
|
+
default: return c;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function dateStringFor(isoTimestamp: string): string {
|
|
51
|
+
// Render as YYYY-MM-DD for the badge.
|
|
52
|
+
const d = new Date(isoTimestamp);
|
|
53
|
+
if (Number.isNaN(d.getTime())) return isoTimestamp.slice(0, 10);
|
|
54
|
+
const y = d.getUTCFullYear();
|
|
55
|
+
const m = String(d.getUTCMonth() + 1).padStart(2, '0');
|
|
56
|
+
const day = String(d.getUTCDate()).padStart(2, '0');
|
|
57
|
+
return `${y}-${m}-${day}`;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Render the badge SVG. The output is intentionally a string (not a
|
|
62
|
+
* DOM tree or stream) so callers can write it to disk directly with
|
|
63
|
+
* `writeFileSync`.
|
|
64
|
+
*/
|
|
65
|
+
export function renderBadgeSvg(input: BadgeInput): string {
|
|
66
|
+
const state = input.state ?? 'active';
|
|
67
|
+
const date = dateStringFor(input.bound_at);
|
|
68
|
+
const valueParts = [state === 'revoked' ? 'revoked' : 'verified human'];
|
|
69
|
+
if (input.issuing_country) valueParts.push(input.issuing_country);
|
|
70
|
+
valueParts.push(date);
|
|
71
|
+
const valueText = valueParts.join(' · '); // middle dot ·
|
|
72
|
+
|
|
73
|
+
const labelEsc = escapeXml(LABEL);
|
|
74
|
+
const valueEsc = escapeXml(valueText);
|
|
75
|
+
|
|
76
|
+
const labelW = LABEL.length * CHAR_WIDTH_PX + 2 * SIDE_PADDING_PX;
|
|
77
|
+
const valueW = valueText.length * CHAR_WIDTH_PX + 2 * SIDE_PADDING_PX;
|
|
78
|
+
const totalW = labelW + valueW;
|
|
79
|
+
|
|
80
|
+
const labelCx10 = labelW * 5; // centre of label segment, scaled x10
|
|
81
|
+
const valueCx10 = (labelW + valueW / 2) * 10;
|
|
82
|
+
const ariaLabel = `${labelEsc}: ${valueEsc}`;
|
|
83
|
+
const tooltipExtra = input.log_entry_hash
|
|
84
|
+
? ` (rekor entry ${escapeXml(input.log_entry_hash.slice(0, 16))}…)`
|
|
85
|
+
: '';
|
|
86
|
+
|
|
87
|
+
return [
|
|
88
|
+
`<svg xmlns="http://www.w3.org/2000/svg" width="${totalW}" height="20" role="img" aria-label="${ariaLabel}">`,
|
|
89
|
+
`<title>${ariaLabel}${tooltipExtra}</title>`,
|
|
90
|
+
`<linearGradient id="s" x2="0" y2="100%">`,
|
|
91
|
+
`<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>`,
|
|
92
|
+
`<stop offset="1" stop-opacity=".1"/>`,
|
|
93
|
+
`</linearGradient>`,
|
|
94
|
+
`<clipPath id="r"><rect width="${totalW}" height="20" rx="3" fill="#fff"/></clipPath>`,
|
|
95
|
+
`<g clip-path="url(#r)">`,
|
|
96
|
+
`<rect width="${labelW}" height="20" fill="#555"/>`,
|
|
97
|
+
`<rect x="${labelW}" width="${valueW}" height="20" fill="${STATE_COLORS[state]}"/>`,
|
|
98
|
+
`<rect width="${totalW}" height="20" fill="url(#s)"/>`,
|
|
99
|
+
`</g>`,
|
|
100
|
+
`<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110">`,
|
|
101
|
+
`<text x="${labelCx10}" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)">${labelEsc}</text>`,
|
|
102
|
+
`<text x="${labelCx10}" y="140" transform="scale(.1)">${labelEsc}</text>`,
|
|
103
|
+
`<text x="${valueCx10}" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)">${valueEsc}</text>`,
|
|
104
|
+
`<text x="${valueCx10}" y="140" transform="scale(.1)">${valueEsc}</text>`,
|
|
105
|
+
`</g>`,
|
|
106
|
+
`</svg>`,
|
|
107
|
+
].join('');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Render the Markdown snippet that wraps the badge in a click-through
|
|
112
|
+
* link to the Rekor entry. Suitable for pasting into a README.
|
|
113
|
+
*/
|
|
114
|
+
export function renderBadgeMarkdown(input: {
|
|
115
|
+
badge_path: string; // relative path the user will commit
|
|
116
|
+
log_entry_hash: string; // Rekor entry UUID
|
|
117
|
+
rekor_base_url?: string; // default: https://rekor.sigstore.dev
|
|
118
|
+
alt_text?: string;
|
|
119
|
+
}): string {
|
|
120
|
+
const base = input.rekor_base_url ?? 'https://rekor.sigstore.dev';
|
|
121
|
+
const url = `${base}/api/v1/log/entries/${input.log_entry_hash}`;
|
|
122
|
+
const alt = input.alt_text ?? 'passportsign verified';
|
|
123
|
+
return `[](${url})`;
|
|
124
|
+
}
|