@xemahq/biome-supply-chain 0.1.3 → 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/README.md +28 -6
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/cosign-exec.d.ts +4 -2
- package/dist/lib/cosign-exec.d.ts.map +1 -1
- package/dist/lib/cosign-exec.js +28 -15
- package/dist/lib/cosign-exec.js.map +1 -1
- package/dist/lib/trust-anchors.d.ts +27 -0
- package/dist/lib/trust-anchors.d.ts.map +1 -0
- package/dist/lib/trust-anchors.js +55 -0
- package/dist/lib/trust-anchors.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
ensureCosignAvailable,
|
|
23
23
|
verifyCosignSignature,
|
|
24
24
|
verifyCosignBlob,
|
|
25
|
+
CosignTrustAnchorKind,
|
|
25
26
|
SignatureVerdict,
|
|
26
27
|
CosignVerifyOutcome,
|
|
27
28
|
} from '@xemahq/biome-supply-chain';
|
|
@@ -35,20 +36,41 @@ await verifyCosignSignature({
|
|
|
35
36
|
oidcIssuer: 'https://token.actions.githubusercontent.com',
|
|
36
37
|
});
|
|
37
38
|
|
|
38
|
-
// Detached blob (caller owns artifact/bundle files on disk)
|
|
39
|
-
|
|
39
|
+
// Detached blob (caller owns artifact/bundle/public-key files on disk).
|
|
40
|
+
// A trust anchor is EITHER a keyless certificate-identity pattern OR a NAMED
|
|
41
|
+
// public key; both kinds share one list and one result shape, and the anchors
|
|
42
|
+
// are tried in order until one verifies.
|
|
43
|
+
const { outcome, matchedAnchor } = await verifyCosignBlob({
|
|
40
44
|
artifactPath: '/tmp/remoteEntry.js',
|
|
41
45
|
bundlePath: '/tmp/remoteEntry.js.bundle',
|
|
42
|
-
|
|
46
|
+
anchors: [
|
|
47
|
+
{
|
|
48
|
+
kind: CosignTrustAnchorKind.KeylessIdentity,
|
|
49
|
+
name: '^https://github.com/xema-dev/.*$', // the name IS the regexp
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
kind: CosignTrustAnchorKind.PublicKey,
|
|
53
|
+
name: 'release-2026',
|
|
54
|
+
publicKeyPath: '/etc/cosign/release.pub',
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
// Optional: pin the Sigstore trusted root so KEYLESS anchors verify with
|
|
58
|
+
// `--offline --trusted-root` (air-gap capable). A missing, unreadable or
|
|
59
|
+
// digest-mismatched root THROWS `CosignTrustedRootError` before cosign is
|
|
60
|
+
// spawned — it never falls back to cosign's online default.
|
|
61
|
+
trustedRoot: { path: '/etc/sigstore/trusted-root.json', sha256: '<64 hex>' },
|
|
43
62
|
});
|
|
44
63
|
if (outcome === CosignVerifyOutcome.Verified) {
|
|
45
|
-
//
|
|
64
|
+
// matchedAnchor is { kind, name } — WHICH anchor vouched for the bytes
|
|
46
65
|
}
|
|
47
66
|
```
|
|
48
67
|
|
|
68
|
+
An empty `anchors` list resolves to `Failed` without spawning cosign, and a
|
|
69
|
+
failed verification is a neutral outcome rather than a throw.
|
|
70
|
+
|
|
49
71
|
Artifact resolution (resolving an OCI ref, or fetching + writing a blob to a
|
|
50
|
-
temp file) stays with each consumer; this package owns only the cosign exec
|
|
51
|
-
the verdict enums.
|
|
72
|
+
temp file) stays with each consumer; this package owns only the cosign exec,
|
|
73
|
+
the trust-anchor vocabulary and the verdict enums.
|
|
52
74
|
|
|
53
75
|
## License
|
|
54
76
|
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -15,5 +15,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./lib/verdicts"), exports);
|
|
18
|
+
__exportStar(require("./lib/trust-anchors"), exports);
|
|
18
19
|
__exportStar(require("./lib/cosign-exec"), exports);
|
|
19
20
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iDAA+B;AAC/B,oDAAkC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iDAA+B;AAC/B,sDAAoC;AACpC,oDAAkC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type CosignBlobTrustAnchor, type CosignMatchedAnchor, type CosignPinnedTrustedRoot } from './trust-anchors';
|
|
1
2
|
import { CosignVerifyOutcome } from './verdicts';
|
|
2
3
|
export declare function ensureCosignAvailable(bin?: string): Promise<void>;
|
|
3
4
|
export interface VerifyCosignSignatureInput {
|
|
@@ -20,13 +21,14 @@ export declare function verifyCosignAttestation(input: VerifyCosignAttestationIn
|
|
|
20
21
|
export interface VerifyCosignBlobInput {
|
|
21
22
|
readonly artifactPath: string;
|
|
22
23
|
readonly bundlePath: string;
|
|
23
|
-
readonly
|
|
24
|
+
readonly anchors: readonly CosignBlobTrustAnchor[];
|
|
24
25
|
readonly oidcIssuer?: string | undefined;
|
|
26
|
+
readonly trustedRoot?: CosignPinnedTrustedRoot | undefined;
|
|
25
27
|
readonly bin?: string | undefined;
|
|
26
28
|
}
|
|
27
29
|
export interface VerifyCosignBlobResult {
|
|
28
30
|
readonly outcome: CosignVerifyOutcome;
|
|
29
|
-
readonly
|
|
31
|
+
readonly matchedAnchor?: CosignMatchedAnchor | undefined;
|
|
30
32
|
}
|
|
31
33
|
export declare function verifyCosignBlob(input: VerifyCosignBlobInput): Promise<VerifyCosignBlobResult>;
|
|
32
34
|
//# sourceMappingURL=cosign-exec.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cosign-exec.d.ts","sourceRoot":"","sources":["../../src/lib/cosign-exec.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAoCjD,wBAAsB,qBAAqB,CACzC,GAAG,GAAE,MAA2B,GAC/B,OAAO,CAAC,IAAI,CAAC,CAYf;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,QAAQ,CAAC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAEzC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AAOD,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,0BAA0B,GAChC,OAAO,CAAC,IAAI,CAAC,CAuBf;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AAMD,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,4BAA4B,GAClC,OAAO,CAAC,IAAI,CAAC,CAyBf;AAED,MAAM,WAAW,qBAAqB;IAEpC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAE9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"cosign-exec.d.ts","sourceRoot":"","sources":["../../src/lib/cosign-exec.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC7B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAoCjD,wBAAsB,qBAAqB,CACzC,GAAG,GAAE,MAA2B,GAC/B,OAAO,CAAC,IAAI,CAAC,CAYf;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,QAAQ,CAAC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAEzC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AAOD,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,0BAA0B,GAChC,OAAO,CAAC,IAAI,CAAC,CAuBf;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AAMD,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,4BAA4B,GAClC,OAAO,CAAC,IAAI,CAAC,CAyBf;AAED,MAAM,WAAW,qBAAqB;IAEpC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAE9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAO5B,QAAQ,CAAC,OAAO,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAKnD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAWzC,QAAQ,CAAC,WAAW,CAAC,EAAE,uBAAuB,GAAG,SAAS,CAAC;IAC3D,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC;IAOtC,QAAQ,CAAC,aAAa,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAC;CAC1D;AA8DD,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC,sBAAsB,CAAC,CAoBjC"}
|
package/dist/lib/cosign-exec.js
CHANGED
|
@@ -5,6 +5,7 @@ exports.verifyCosignSignature = verifyCosignSignature;
|
|
|
5
5
|
exports.verifyCosignAttestation = verifyCosignAttestation;
|
|
6
6
|
exports.verifyCosignBlob = verifyCosignBlob;
|
|
7
7
|
const node_child_process_1 = require("node:child_process");
|
|
8
|
+
const trust_anchors_1 = require("./trust-anchors");
|
|
8
9
|
const verdicts_1 = require("./verdicts");
|
|
9
10
|
const DEFAULT_COSIGN_BIN = 'cosign';
|
|
10
11
|
function runCosign(bin, args) {
|
|
@@ -80,26 +81,38 @@ async function verifyCosignAttestation(input) {
|
|
|
80
81
|
throw new Error(`${bin} verify-attestation failed (code=${code}): ${stderr.slice(-200)}`);
|
|
81
82
|
}
|
|
82
83
|
}
|
|
84
|
+
function buildBlobVerifyArgs(anchor, input) {
|
|
85
|
+
const args = ['verify-blob'];
|
|
86
|
+
if (anchor.kind === trust_anchors_1.CosignTrustAnchorKind.PublicKey) {
|
|
87
|
+
args.push('--key', anchor.publicKeyPath, '--bundle', input.bundlePath, '--insecure-ignore-tlog');
|
|
88
|
+
args.push(input.artifactPath);
|
|
89
|
+
return args;
|
|
90
|
+
}
|
|
91
|
+
args.push('--bundle', input.bundlePath, '--certificate-identity-regexp', anchor.name);
|
|
92
|
+
if (input.oidcIssuer) {
|
|
93
|
+
args.push('--certificate-oidc-issuer', input.oidcIssuer);
|
|
94
|
+
}
|
|
95
|
+
if (input.trustedRoot) {
|
|
96
|
+
args.push('--offline', '--trusted-root', input.trustedRoot.path);
|
|
97
|
+
}
|
|
98
|
+
args.push(input.artifactPath);
|
|
99
|
+
return args;
|
|
100
|
+
}
|
|
83
101
|
async function verifyCosignBlob(input) {
|
|
84
102
|
const bin = input.bin ?? DEFAULT_COSIGN_BIN;
|
|
85
|
-
if (input.
|
|
103
|
+
if (input.anchors.length === 0) {
|
|
86
104
|
return { outcome: verdicts_1.CosignVerifyOutcome.Failed };
|
|
87
105
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
'--certificate-identity-regexp',
|
|
94
|
-
identity,
|
|
95
|
-
];
|
|
96
|
-
if (input.oidcIssuer) {
|
|
97
|
-
args.push('--certificate-oidc-issuer', input.oidcIssuer);
|
|
98
|
-
}
|
|
99
|
-
args.push(input.artifactPath);
|
|
100
|
-
const { code } = await runCosign(bin, args);
|
|
106
|
+
if (input.trustedRoot) {
|
|
107
|
+
(0, trust_anchors_1.assertPinnedTrustedRoot)(input.trustedRoot);
|
|
108
|
+
}
|
|
109
|
+
for (const anchor of input.anchors) {
|
|
110
|
+
const { code } = await runCosign(bin, buildBlobVerifyArgs(anchor, input));
|
|
101
111
|
if (code === 0) {
|
|
102
|
-
return {
|
|
112
|
+
return {
|
|
113
|
+
outcome: verdicts_1.CosignVerifyOutcome.Verified,
|
|
114
|
+
matchedAnchor: { kind: anchor.kind, name: anchor.name },
|
|
115
|
+
};
|
|
103
116
|
}
|
|
104
117
|
}
|
|
105
118
|
return { outcome: verdicts_1.CosignVerifyOutcome.Failed };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cosign-exec.js","sourceRoot":"","sources":["../../src/lib/cosign-exec.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"cosign-exec.js","sourceRoot":"","sources":["../../src/lib/cosign-exec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export declare enum CosignTrustAnchorKind {
|
|
2
|
+
KeylessIdentity = "keyless-identity",
|
|
3
|
+
PublicKey = "public-key"
|
|
4
|
+
}
|
|
5
|
+
export interface CosignKeylessIdentityAnchor {
|
|
6
|
+
readonly kind: CosignTrustAnchorKind.KeylessIdentity;
|
|
7
|
+
readonly name: string;
|
|
8
|
+
}
|
|
9
|
+
export interface CosignPublicKeyAnchor {
|
|
10
|
+
readonly kind: CosignTrustAnchorKind.PublicKey;
|
|
11
|
+
readonly name: string;
|
|
12
|
+
readonly publicKeyPath: string;
|
|
13
|
+
}
|
|
14
|
+
export type CosignBlobTrustAnchor = CosignKeylessIdentityAnchor | CosignPublicKeyAnchor;
|
|
15
|
+
export interface CosignMatchedAnchor {
|
|
16
|
+
readonly kind: CosignTrustAnchorKind;
|
|
17
|
+
readonly name: string;
|
|
18
|
+
}
|
|
19
|
+
export interface CosignPinnedTrustedRoot {
|
|
20
|
+
readonly path: string;
|
|
21
|
+
readonly sha256: string;
|
|
22
|
+
}
|
|
23
|
+
export declare class CosignTrustedRootError extends Error {
|
|
24
|
+
constructor(message: string);
|
|
25
|
+
}
|
|
26
|
+
export declare function assertPinnedTrustedRoot(root: CosignPinnedTrustedRoot): void;
|
|
27
|
+
//# sourceMappingURL=trust-anchors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trust-anchors.d.ts","sourceRoot":"","sources":["../../src/lib/trust-anchors.ts"],"names":[],"mappings":"AAiBA,oBAAY,qBAAqB;IAC/B,eAAe,qBAAqB;IACpC,SAAS,eAAe;CACzB;AAQD,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC,eAAe,CAAC;IACrD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAQD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC,SAAS,CAAC;IAC/C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAGD,MAAM,MAAM,qBAAqB,GAC7B,2BAA2B,GAC3B,qBAAqB,CAAC;AAQ1B,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAcD,MAAM,WAAW,uBAAuB;IAEtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAUD,qBAAa,sBAAuB,SAAQ,KAAK;gBACnC,OAAO,EAAE,MAAM;CAI5B;AAuBD,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,uBAAuB,GAAG,IAAI,CA0C3E"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CosignTrustedRootError = exports.CosignTrustAnchorKind = void 0;
|
|
4
|
+
exports.assertPinnedTrustedRoot = assertPinnedTrustedRoot;
|
|
5
|
+
const node_crypto_1 = require("node:crypto");
|
|
6
|
+
const node_fs_1 = require("node:fs");
|
|
7
|
+
var CosignTrustAnchorKind;
|
|
8
|
+
(function (CosignTrustAnchorKind) {
|
|
9
|
+
CosignTrustAnchorKind["KeylessIdentity"] = "keyless-identity";
|
|
10
|
+
CosignTrustAnchorKind["PublicKey"] = "public-key";
|
|
11
|
+
})(CosignTrustAnchorKind || (exports.CosignTrustAnchorKind = CosignTrustAnchorKind = {}));
|
|
12
|
+
class CosignTrustedRootError extends Error {
|
|
13
|
+
constructor(message) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.name = 'CosignTrustedRootError';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.CosignTrustedRootError = CosignTrustedRootError;
|
|
19
|
+
const SHA256_HEX = /^[a-f0-9]{64}$/u;
|
|
20
|
+
const SIGSTORE_TRUSTED_ROOT_MEDIA_TYPE = 'application/vnd.dev.sigstore.trustedroot+json;version=0.1';
|
|
21
|
+
const MAX_TRUSTED_ROOT_BYTES = 8 * 1024 * 1024;
|
|
22
|
+
function assertPinnedTrustedRoot(root) {
|
|
23
|
+
if (!SHA256_HEX.test(root.sha256)) {
|
|
24
|
+
throw new CosignTrustedRootError(`pinned Sigstore trusted-root digest '${root.sha256}' is not a lowercase-hex sha256`);
|
|
25
|
+
}
|
|
26
|
+
let bytes;
|
|
27
|
+
try {
|
|
28
|
+
bytes = (0, node_fs_1.readFileSync)(root.path);
|
|
29
|
+
}
|
|
30
|
+
catch (cause) {
|
|
31
|
+
throw new CosignTrustedRootError(`pinned Sigstore trusted root '${root.path}' could not be read: ` +
|
|
32
|
+
`${cause instanceof Error ? cause.message : String(cause)}`);
|
|
33
|
+
}
|
|
34
|
+
if (bytes.byteLength > MAX_TRUSTED_ROOT_BYTES) {
|
|
35
|
+
throw new CosignTrustedRootError(`pinned Sigstore trusted root '${root.path}' is ${bytes.byteLength} bytes, over the ${MAX_TRUSTED_ROOT_BYTES}-byte ceiling`);
|
|
36
|
+
}
|
|
37
|
+
const actual = (0, node_crypto_1.createHash)('sha256').update(bytes).digest('hex');
|
|
38
|
+
if (actual !== root.sha256) {
|
|
39
|
+
throw new CosignTrustedRootError(`pinned Sigstore trusted-root digest mismatch for '${root.path}': expected ${root.sha256}, got ${actual}`);
|
|
40
|
+
}
|
|
41
|
+
let document;
|
|
42
|
+
try {
|
|
43
|
+
document = JSON.parse(bytes.toString('utf8'));
|
|
44
|
+
}
|
|
45
|
+
catch (cause) {
|
|
46
|
+
throw new CosignTrustedRootError(`pinned Sigstore trusted root '${root.path}' is not valid JSON: ` +
|
|
47
|
+
`${cause instanceof Error ? cause.message : String(cause)}`);
|
|
48
|
+
}
|
|
49
|
+
const mediaType = document?.mediaType;
|
|
50
|
+
if (mediaType !== SIGSTORE_TRUSTED_ROOT_MEDIA_TYPE) {
|
|
51
|
+
throw new CosignTrustedRootError(`pinned Sigstore trusted root '${root.path}' declares mediaType ` +
|
|
52
|
+
`'${String(mediaType)}' — expected '${SIGSTORE_TRUSTED_ROOT_MEDIA_TYPE}'`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=trust-anchors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trust-anchors.js","sourceRoot":"","sources":["../../src/lib/trust-anchors.ts"],"names":[],"mappings":";;;AAoHA,0DA0CC;AA9JD,6CAAyC;AACzC,qCAAuC;AAgBvC,IAAY,qBAGX;AAHD,WAAY,qBAAqB;IAC/B,6DAAoC,CAAA;IACpC,iDAAwB,CAAA;AAC1B,CAAC,EAHW,qBAAqB,qCAArB,qBAAqB,QAGhC;AAoED,MAAa,sBAAuB,SAAQ,KAAK;IAC/C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AALD,wDAKC;AAGD,MAAM,UAAU,GAAG,iBAAiB,CAAC;AAOrC,MAAM,gCAAgC,GACpC,2DAA2D,CAAC;AAG9D,MAAM,sBAAsB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAS/C,SAAgB,uBAAuB,CAAC,IAA6B;IACnE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,sBAAsB,CAC9B,wCAAwC,IAAI,CAAC,MAAM,iCAAiC,CACrF,CAAC;IACJ,CAAC;IACD,IAAI,KAAa,CAAC;IAClB,IAAI,CAAC;QACH,KAAK,GAAG,IAAA,sBAAY,EAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,sBAAsB,CAC9B,iCAAiC,IAAI,CAAC,IAAI,uBAAuB;YAC/D,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC9D,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,CAAC,UAAU,GAAG,sBAAsB,EAAE,CAAC;QAC9C,MAAM,IAAI,sBAAsB,CAC9B,iCAAiC,IAAI,CAAC,IAAI,QAAQ,KAAK,CAAC,UAAU,oBAAoB,sBAAsB,eAAe,CAC5H,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,IAAA,wBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAChE,IAAI,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;QAC3B,MAAM,IAAI,sBAAsB,CAC9B,qDAAqD,IAAI,CAAC,IAAI,eAAe,IAAI,CAAC,MAAM,SAAS,MAAM,EAAE,CAC1G,CAAC;IACJ,CAAC;IACD,IAAI,QAAiB,CAAC;IACtB,IAAI,CAAC;QACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAChD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,sBAAsB,CAC9B,iCAAiC,IAAI,CAAC,IAAI,uBAAuB;YAC/D,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC9D,CAAC;IACJ,CAAC;IACD,MAAM,SAAS,GAAI,QAA2C,EAAE,SAAS,CAAC;IAC1E,IAAI,SAAS,KAAK,gCAAgC,EAAE,CAAC;QACnD,MAAM,IAAI,sBAAsB,CAC9B,iCAAiC,IAAI,CAAC,IAAI,uBAAuB;YAC/D,IAAI,MAAM,CAAC,SAAS,CAAC,iBAAiB,gCAAgC,GAAG,CAC5E,CAAC;IACJ,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xemahq/biome-supply-chain",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Shared cosign supply-chain verification for Xema biomes: the single cosign CLI exec + the signature/provenance verdict enums used by biome-fetcher-api (OCI bundle verification) and xema-store-api. Node-builtins only.",
|
|
5
5
|
"license": "LicenseRef-Xema-BSL-1.1",
|
|
6
6
|
"author": "Neuralchowder Inc. <developer@xema.dev> (https://xema.dev)",
|