@antseed/antseed-verifier 0.1.0 → 0.1.1
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 +5 -3
- package/dist/antseed-node-types.d.ts +6 -0
- package/dist/antseed-node-types.d.ts.map +1 -1
- package/dist/approved-node-measurements.d.ts +33 -0
- package/dist/approved-node-measurements.d.ts.map +1 -0
- package/dist/approved-node-measurements.js +42 -0
- package/dist/approved-node-measurements.js.map +1 -0
- package/dist/approved-seller-images.d.ts +14 -0
- package/dist/approved-seller-images.d.ts.map +1 -0
- package/dist/approved-seller-images.js +7 -0
- package/dist/approved-seller-images.js.map +1 -0
- package/dist/capability.d.ts +5 -0
- package/dist/capability.d.ts.map +1 -1
- package/dist/capability.js.map +1 -1
- package/dist/caps/tee-tdx.d.ts +43 -17
- package/dist/caps/tee-tdx.d.ts.map +1 -1
- package/dist/caps/tee-tdx.js +158 -35
- package/dist/caps/tee-tdx.js.map +1 -1
- package/dist/collect/confidential-space.d.ts +12 -0
- package/dist/collect/confidential-space.d.ts.map +1 -0
- package/dist/collect/confidential-space.js +22 -0
- package/dist/collect/confidential-space.js.map +1 -0
- package/dist/collect/dstack.d.ts +10 -0
- package/dist/collect/dstack.d.ts.map +1 -1
- package/dist/collect/dstack.js +31 -26
- package/dist/collect/dstack.js.map +1 -1
- package/dist/collect/unix-http.d.ts +9 -0
- package/dist/collect/unix-http.d.ts.map +1 -0
- package/dist/collect/unix-http.js +21 -0
- package/dist/collect/unix-http.js.map +1 -0
- package/dist/confidential-space.d.ts +49 -0
- package/dist/confidential-space.d.ts.map +1 -0
- package/dist/confidential-space.js +93 -0
- package/dist/confidential-space.js.map +1 -0
- package/dist/dstack-app-compose.d.ts +36 -0
- package/dist/dstack-app-compose.d.ts.map +1 -0
- package/dist/dstack-app-compose.js +113 -0
- package/dist/dstack-app-compose.js.map +1 -0
- package/dist/dstack-event-log.d.ts +42 -0
- package/dist/dstack-event-log.d.ts.map +1 -0
- package/dist/dstack-event-log.js +87 -0
- package/dist/dstack-event-log.js.map +1 -0
- package/dist/prover.d.ts.map +1 -1
- package/dist/prover.js +17 -4
- package/dist/prover.js.map +1 -1
- package/dist/report-data.d.ts +3 -1
- package/dist/report-data.d.ts.map +1 -1
- package/dist/report-data.js +1 -0
- package/dist/report-data.js.map +1 -1
- package/dist/seller-config-rules.d.ts +43 -0
- package/dist/seller-config-rules.d.ts.map +1 -0
- package/dist/seller-config-rules.js +130 -0
- package/dist/seller-config-rules.js.map +1 -0
- package/dist/shared.d.ts +16 -2
- package/dist/shared.d.ts.map +1 -1
- package/dist/shared.js +21 -5
- package/dist/shared.js.map +1 -1
- package/dist/tcb-policy.d.ts +8 -0
- package/dist/tcb-policy.d.ts.map +1 -0
- package/dist/tcb-policy.js +14 -0
- package/dist/tcb-policy.js.map +1 -0
- package/dist/tee-provider-plugins.json +7 -0
- package/dist/verifier.d.ts +2 -1
- package/dist/verifier.d.ts.map +1 -1
- package/dist/verifier.js +10 -7
- package/dist/verifier.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { JWTPayload } from 'jose';
|
|
2
|
+
import type { ApprovedSellerImage } from './approved-seller-images.js';
|
|
3
|
+
import { type SellerUpstream } from './seller-config-rules.js';
|
|
4
|
+
/**
|
|
5
|
+
* Google Confidential Space runs one container on a TDX VM under a Google-built OS with no
|
|
6
|
+
* operator access, and Google's attestation service signs a token describing it: the hardware,
|
|
7
|
+
* the OS image, whether debugging is on, the container's image digest and every environment
|
|
8
|
+
* variable the operator overrode. The seller asks for a token carrying our binding as its nonce,
|
|
9
|
+
* and the buyer checks Google's signature and these claims instead of a raw TDX quote.
|
|
10
|
+
*
|
|
11
|
+
* A conforming workload runs an approved Antseed TEE seller image on a production (non-debug)
|
|
12
|
+
* Confidential Space image on Intel TDX. Its only overrides are the settings LITERAL_ENV allows,
|
|
13
|
+
* the seller config (ANTSEED_SELLER_CONFIG_JSON, checked by the seller config rules), where
|
|
14
|
+
* its secrets come from (ANTSEED_GCP_SECRETS) and where it keeps its state across restarts
|
|
15
|
+
* (ANTSEED_GCP_STATE). Secrets themselves are fetched from Secret Manager inside the attested
|
|
16
|
+
* container, since the token would show any env value to every buyer. The state the image keeps
|
|
17
|
+
* there is its payment and metering databases, encrypted, without prompts or responses.
|
|
18
|
+
*/
|
|
19
|
+
export declare const CS_ISSUER = "https://confidentialcomputing.googleapis.com";
|
|
20
|
+
/** The audience the seller requests its token for, so a token minted for another purpose fails. */
|
|
21
|
+
export declare const CS_AUDIENCE = "antseed-verifier";
|
|
22
|
+
/** Google's Confidential Space token signing keys (the issuer's jwks_uri). */
|
|
23
|
+
export declare const CS_JWKS_URL = "https://www.googleapis.com/service_accounts/v1/metadata/jwk/signer@confidentialspace-sign.iam.gserviceaccount.com";
|
|
24
|
+
/** The seller config, as JSON, in an env override (the image writes it to its config file). */
|
|
25
|
+
export declare const CS_SELLER_CONFIG_ENV = "ANTSEED_SELLER_CONFIG_JSON";
|
|
26
|
+
/** `{ "audience": <workload identity provider>, "secrets": { NAME: <Secret Manager version> } }` */
|
|
27
|
+
export declare const CS_SECRETS_ENV = "ANTSEED_GCP_SECRETS";
|
|
28
|
+
/** `gs://<bucket>/<prefix>`: where in Cloud Storage the seller keeps its encrypted state snapshots. */
|
|
29
|
+
export declare const CS_STATE_ENV = "ANTSEED_GCP_STATE";
|
|
30
|
+
/** The bucket and prefix of a CS_STATE_ENV value, or null if it isn't a `gs://<bucket>/<prefix>` URL. */
|
|
31
|
+
export declare function parseStateLocation(value: string): {
|
|
32
|
+
bucket: string;
|
|
33
|
+
prefix: string;
|
|
34
|
+
} | null;
|
|
35
|
+
/** Verify a Confidential Space token's signature, issuer, audience and expiry; returns its claims. */
|
|
36
|
+
export type VerifyConfidentialSpaceTokenFn = (token: string) => Promise<JWTPayload>;
|
|
37
|
+
/** Checks the token against Google's published keys (ANTSEED_VERIFIER_CS_JWKS_URL overrides the URL). The seller half never loads jose. */
|
|
38
|
+
export declare const defaultVerifyConfidentialSpaceToken: VerifyConfidentialSpaceTokenFn;
|
|
39
|
+
/** The nonce a seller requests: SHA-256 (hex) of its antseed-rd-v1 report data for this round. */
|
|
40
|
+
export declare function confidentialSpaceNonce(reportData: Uint8Array): string;
|
|
41
|
+
export interface CheckedConfidentialSpace {
|
|
42
|
+
image: ApprovedSellerImage;
|
|
43
|
+
upstreams: SellerUpstream[];
|
|
44
|
+
}
|
|
45
|
+
/** Check a verified token's claims for this round's nonce. Returns the image and upstreams, or why it fails. */
|
|
46
|
+
export declare function checkConfidentialSpaceClaims(claims: JWTPayload, expectedNonce: string, images: readonly ApprovedSellerImage[]): CheckedConfidentialSpace | {
|
|
47
|
+
error: string;
|
|
48
|
+
};
|
|
49
|
+
//# sourceMappingURL=confidential-space.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confidential-space.d.ts","sourceRoot":"","sources":["../src/confidential-space.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAmB,MAAM,MAAM,CAAA;AACvD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AAEtE,OAAO,EAA0F,KAAK,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAEtJ;;;;;;;;;;;;;;GAcG;AAEH,eAAO,MAAM,SAAS,iDAAiD,CAAA;AACvE,mGAAmG;AACnG,eAAO,MAAM,WAAW,qBAAqB,CAAA;AAC7C,8EAA8E;AAC9E,eAAO,MAAM,WAAW,sHAAsH,CAAA;AAC9I,+FAA+F;AAC/F,eAAO,MAAM,oBAAoB,+BAA+B,CAAA;AAChE,oGAAoG;AACpG,eAAO,MAAM,cAAc,wBAAwB,CAAA;AACnD,uGAAuG;AACvG,eAAO,MAAM,YAAY,sBAAsB,CAAA;AAI/C,yGAAyG;AACzG,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAG3F;AAED,sGAAsG;AACtG,MAAM,MAAM,8BAA8B,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAA;AAGnF,2IAA2I;AAC3I,eAAO,MAAM,mCAAmC,EAAE,8BAIjD,CAAA;AAID,kGAAkG;AAClG,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAErE;AAED,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,mBAAmB,CAAA;IAC1B,SAAS,EAAE,cAAc,EAAE,CAAA;CAC5B;AAED,gHAAgH;AAChH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,UAAU,EAClB,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,SAAS,mBAAmB,EAAE,GACrC,wBAAwB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CA4C9C"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { isTcbAcceptable } from './tcb-policy.js';
|
|
3
|
+
import { LITERAL_ENV, RuleError, check, checkHiddenSecrets, checkSellerConfig, isObj, parseJson } from './seller-config-rules.js';
|
|
4
|
+
/**
|
|
5
|
+
* Google Confidential Space runs one container on a TDX VM under a Google-built OS with no
|
|
6
|
+
* operator access, and Google's attestation service signs a token describing it: the hardware,
|
|
7
|
+
* the OS image, whether debugging is on, the container's image digest and every environment
|
|
8
|
+
* variable the operator overrode. The seller asks for a token carrying our binding as its nonce,
|
|
9
|
+
* and the buyer checks Google's signature and these claims instead of a raw TDX quote.
|
|
10
|
+
*
|
|
11
|
+
* A conforming workload runs an approved Antseed TEE seller image on a production (non-debug)
|
|
12
|
+
* Confidential Space image on Intel TDX. Its only overrides are the settings LITERAL_ENV allows,
|
|
13
|
+
* the seller config (ANTSEED_SELLER_CONFIG_JSON, checked by the seller config rules), where
|
|
14
|
+
* its secrets come from (ANTSEED_GCP_SECRETS) and where it keeps its state across restarts
|
|
15
|
+
* (ANTSEED_GCP_STATE). Secrets themselves are fetched from Secret Manager inside the attested
|
|
16
|
+
* container, since the token would show any env value to every buyer. The state the image keeps
|
|
17
|
+
* there is its payment and metering databases, encrypted, without prompts or responses.
|
|
18
|
+
*/
|
|
19
|
+
export const CS_ISSUER = 'https://confidentialcomputing.googleapis.com';
|
|
20
|
+
/** The audience the seller requests its token for, so a token minted for another purpose fails. */
|
|
21
|
+
export const CS_AUDIENCE = 'antseed-verifier';
|
|
22
|
+
/** Google's Confidential Space token signing keys (the issuer's jwks_uri). */
|
|
23
|
+
export const CS_JWKS_URL = 'https://www.googleapis.com/service_accounts/v1/metadata/jwk/signer@confidentialspace-sign.iam.gserviceaccount.com';
|
|
24
|
+
/** The seller config, as JSON, in an env override (the image writes it to its config file). */
|
|
25
|
+
export const CS_SELLER_CONFIG_ENV = 'ANTSEED_SELLER_CONFIG_JSON';
|
|
26
|
+
/** `{ "audience": <workload identity provider>, "secrets": { NAME: <Secret Manager version> } }` */
|
|
27
|
+
export const CS_SECRETS_ENV = 'ANTSEED_GCP_SECRETS';
|
|
28
|
+
/** `gs://<bucket>/<prefix>`: where in Cloud Storage the seller keeps its encrypted state snapshots. */
|
|
29
|
+
export const CS_STATE_ENV = 'ANTSEED_GCP_STATE';
|
|
30
|
+
const STATE_LOCATION = /^gs:\/\/([a-z0-9][a-z0-9._-]{1,61}[a-z0-9])\/((?!.*\/\/)(?!.*\.\.)[A-Za-z0-9._-][A-Za-z0-9._/-]{0,1023})$/;
|
|
31
|
+
/** The bucket and prefix of a CS_STATE_ENV value, or null if it isn't a `gs://<bucket>/<prefix>` URL. */
|
|
32
|
+
export function parseStateLocation(value) {
|
|
33
|
+
const match = STATE_LOCATION.exec(value);
|
|
34
|
+
return match && !match[2].endsWith('/') ? { bucket: match[1], prefix: match[2] } : null;
|
|
35
|
+
}
|
|
36
|
+
let googleKeys;
|
|
37
|
+
/** Checks the token against Google's published keys (ANTSEED_VERIFIER_CS_JWKS_URL overrides the URL). The seller half never loads jose. */
|
|
38
|
+
export const defaultVerifyConfidentialSpaceToken = async (token) => {
|
|
39
|
+
const jose = await import('jose');
|
|
40
|
+
googleKeys ??= jose.createRemoteJWKSet(new URL(process.env['ANTSEED_VERIFIER_CS_JWKS_URL'] || CS_JWKS_URL));
|
|
41
|
+
return (await jose.jwtVerify(token, googleKeys, { issuer: CS_ISSUER, audience: CS_AUDIENCE })).payload;
|
|
42
|
+
};
|
|
43
|
+
const SECRET_VERSION = /^projects\/[^/]+\/secrets\/[^/]+\/versions\/[^/]+$/;
|
|
44
|
+
/** The nonce a seller requests: SHA-256 (hex) of its antseed-rd-v1 report data for this round. */
|
|
45
|
+
export function confidentialSpaceNonce(reportData) {
|
|
46
|
+
return createHash('sha256').update(reportData).digest('hex');
|
|
47
|
+
}
|
|
48
|
+
/** Check a verified token's claims for this round's nonce. Returns the image and upstreams, or why it fails. */
|
|
49
|
+
export function checkConfidentialSpaceClaims(claims, expectedNonce, images) {
|
|
50
|
+
try {
|
|
51
|
+
const nonces = claims['eat_nonce'];
|
|
52
|
+
check(nonces === expectedNonce || (Array.isArray(nonces) && nonces.includes(expectedNonce)), 'Confidential Space token is not bound to this round and connection');
|
|
53
|
+
check(claims['hwmodel'] === 'GCP_INTEL_TDX', `Confidential Space hardware is ${String(claims['hwmodel'])}, not Intel TDX`);
|
|
54
|
+
check(claims['swname'] === 'CONFIDENTIAL_SPACE', 'token is not from a Confidential Space image');
|
|
55
|
+
check(claims['dbgstat'] === 'disabled-since-boot', 'Confidential Space debug image (debugging enabled)');
|
|
56
|
+
check(claims['secboot'] === true, 'Confidential Space VM did not boot with Secure Boot');
|
|
57
|
+
// Google's verdict on the TDX platform's TCB, held to the same acceptance as a raw quote's.
|
|
58
|
+
const tcb = isObj(claims['tdx']) ? claims['tdx']['gcp_attester_tcb_status'] : undefined;
|
|
59
|
+
check(typeof tcb === 'string' && isTcbAcceptable(tcb), `TCB status not acceptable: ${String(tcb ?? 'unknown')}`);
|
|
60
|
+
const submods = isObj(claims['submods']) ? claims['submods'] : {};
|
|
61
|
+
const space = isObj(submods['confidential_space']) ? submods['confidential_space'] : {};
|
|
62
|
+
const support = space['support_attributes'];
|
|
63
|
+
check(Array.isArray(support) && support.includes('STABLE'), 'Confidential Space image is not a supported production release');
|
|
64
|
+
const container = isObj(submods['container']) ? submods['container'] : {};
|
|
65
|
+
const digest = container['image_digest'];
|
|
66
|
+
const image = typeof digest === 'string' ? images.find((i) => i.digest === digest) : undefined;
|
|
67
|
+
check(image, `image ${String(digest).slice(0, 19)}… is not an approved Antseed TEE seller image`);
|
|
68
|
+
const env = container['env_override'] ?? {};
|
|
69
|
+
check(isObj(env), 'container env_override must be a map');
|
|
70
|
+
for (const [key, value] of Object.entries(env)) {
|
|
71
|
+
check(typeof value === 'string', `environment ${key} must be a string`);
|
|
72
|
+
check(LITERAL_ENV.test(key) || key === CS_SELLER_CONFIG_ENV || key === CS_SECRETS_ENV || key === CS_STATE_ENV, `environment ${key} is not allowed`);
|
|
73
|
+
}
|
|
74
|
+
const state = env[CS_STATE_ENV];
|
|
75
|
+
check(state === undefined || parseStateLocation(state), `${CS_STATE_ENV} must be a gs://<bucket>/<prefix> URL`);
|
|
76
|
+
const config = env[CS_SELLER_CONFIG_ENV];
|
|
77
|
+
check(typeof config === 'string', `the seller config must be set in ${CS_SELLER_CONFIG_ENV}`);
|
|
78
|
+
const { upstreams, apiKeyEnvs } = checkSellerConfig(parseJson(config, 'seller config'));
|
|
79
|
+
const secrets = env[CS_SECRETS_ENV] === undefined ? { secrets: {} } : parseJson(env[CS_SECRETS_ENV], CS_SECRETS_ENV);
|
|
80
|
+
check(isObj(secrets) && isObj(secrets['secrets']), `${CS_SECRETS_ENV} must name its secrets`);
|
|
81
|
+
for (const [name, version] of Object.entries(secrets['secrets'])) {
|
|
82
|
+
check(typeof version === 'string' && SECRET_VERSION.test(version), `${CS_SECRETS_ENV} ${name} must be a Secret Manager version`);
|
|
83
|
+
}
|
|
84
|
+
checkHiddenSecrets(Object.keys(secrets['secrets']), apiKeyEnvs);
|
|
85
|
+
return { image, upstreams };
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
if (err instanceof RuleError)
|
|
89
|
+
return { error: err.message };
|
|
90
|
+
throw err;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=confidential-space.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confidential-space.js","sourceRoot":"","sources":["../src/confidential-space.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ApprovedSellerImage } from './approved-seller-images.js';
|
|
2
|
+
import { type SellerUpstream } from './seller-config-rules.js';
|
|
3
|
+
export type { SellerUpstream } from './seller-config-rules.js';
|
|
4
|
+
/**
|
|
5
|
+
* A dstack app is measured as the SHA-256 of its app-compose.json, which embeds the docker
|
|
6
|
+
* compose file. The seller sends that document with its quote. The buyer hashes it against the
|
|
7
|
+
* compose hash replayed from the quote's RTMR3, then checks it with the rules below. A
|
|
8
|
+
* conforming compose runs one approved Antseed TEE seller image, and every setting that decides
|
|
9
|
+
* where prompts go is written in it literally, so the buyer reads it directly. Only secrets come
|
|
10
|
+
* in hidden, as encrypted environment variables, and no secret can redirect prompts.
|
|
11
|
+
*
|
|
12
|
+
* The rules (anything not listed is rejected):
|
|
13
|
+
* - app-compose: runner docker-compose; no pre-launch or bash script; the allowed encrypted
|
|
14
|
+
* variables are only the secrets the compose file uses. Logs may be public: the image runs
|
|
15
|
+
* the seller in content-free mode, so they hold no prompts or answers, nor upstream error text about a request.
|
|
16
|
+
* - compose file: written as JSON; one service; image pinned by an approved digest; no command,
|
|
17
|
+
* entrypoint, user or other service options; the only volumes are the seller data volume and
|
|
18
|
+
* the dstack socket; the seller config is one inline config at /etc/antseed/config.json.
|
|
19
|
+
* - environment: the literal settings LITERAL_ENV allows; secrets only as `NAME: ${NAME}` for
|
|
20
|
+
* the names checkHiddenSecrets allows, plus `ANTSEED_VERIFIER_SIGNING_KEY: ${ANTSEED_IDENTITY_HEX}`.
|
|
21
|
+
* No `$` anywhere else, because compose substitutes variables in every value, the inline
|
|
22
|
+
* config included.
|
|
23
|
+
* - seller config: the rules in seller-config-rules.ts.
|
|
24
|
+
*/
|
|
25
|
+
export interface CheckedAppCompose {
|
|
26
|
+
image: ApprovedSellerImage;
|
|
27
|
+
upstreams: SellerUpstream[];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Check a seller's app-compose.json against the compose hash its quote measured, then against
|
|
31
|
+
* the rules above. Returns the approved image and the seller's upstreams, or why it fails.
|
|
32
|
+
*/
|
|
33
|
+
export declare function checkAppCompose(appCompose: string, composeHash: string, images: readonly ApprovedSellerImage[]): CheckedAppCompose | {
|
|
34
|
+
error: string;
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=dstack-app-compose.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dstack-app-compose.d.ts","sourceRoot":"","sources":["../src/dstack-app-compose.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AACtE,OAAO,EAAsG,KAAK,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAElK,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAE9D;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,mBAAmB,CAAA;IAC1B,SAAS,EAAE,cAAc,EAAE,CAAA;CAC5B;AAyFD;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,SAAS,mBAAmB,EAAE,GACrC,iBAAiB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAmBvC"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { LITERAL_ENV, SECRET_ENV, check, checkHiddenSecrets, checkSellerConfig, isObj, parseJson, RuleError } from './seller-config-rules.js';
|
|
3
|
+
const APP_COMPOSE_KEYS = new Set([
|
|
4
|
+
'manifest_version', 'name', 'features', 'runner', 'docker_compose_file', 'docker_config',
|
|
5
|
+
'public_logs', 'public_sysinfo', 'public_tcbinfo', 'kms_enabled', 'gateway_enabled', 'tproxy_enabled',
|
|
6
|
+
'local_key_provider_enabled', 'key_provider', 'key_provider_id', 'allowed_envs', 'no_instance_id',
|
|
7
|
+
'secure_time', 'pre_launch_script', 'storage_fs', 'swap_size',
|
|
8
|
+
]);
|
|
9
|
+
const SERVICE_KEYS = new Set(['image', 'restart', 'ports', 'environment', 'volumes', 'configs', 'container_name']);
|
|
10
|
+
const CONFIG_PATH = '/etc/antseed/config.json';
|
|
11
|
+
const DATA_DIR = '/var/lib/antseed';
|
|
12
|
+
const DSTACK_SOCKET = '/var/run/dstack.sock';
|
|
13
|
+
const IMAGE = /^[a-z0-9][a-z0-9._/:-]*@(sha256:[0-9a-f]{64})$/;
|
|
14
|
+
/** Whether any key or string anywhere in a value contains "$". */
|
|
15
|
+
function hasVariableReference(value) {
|
|
16
|
+
if (typeof value === 'string')
|
|
17
|
+
return value.includes('$');
|
|
18
|
+
if (Array.isArray(value))
|
|
19
|
+
return value.some(hasVariableReference);
|
|
20
|
+
if (isObj(value))
|
|
21
|
+
return Object.entries(value).some(([key, entry]) => key.includes('$') || hasVariableReference(entry));
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
/** The secrets the environment hides, after checking every entry. */
|
|
25
|
+
function checkEnvironment(env) {
|
|
26
|
+
check(env === undefined || isObj(env), 'environment must be a map');
|
|
27
|
+
const secrets = new Set();
|
|
28
|
+
for (const [key, value] of Object.entries(env ?? {})) {
|
|
29
|
+
check(typeof value === 'string', `environment ${key} must be a string`);
|
|
30
|
+
const ref = /^\$\{([A-Z][A-Z0-9_]*)\}$/.exec(value)?.[1];
|
|
31
|
+
if (ref) {
|
|
32
|
+
const signingKey = key === 'ANTSEED_VERIFIER_SIGNING_KEY' && ref === 'ANTSEED_IDENTITY_HEX';
|
|
33
|
+
check(SECRET_ENV.test(ref) && (ref === key || signingKey), `environment ${key} may not come from a hidden variable`);
|
|
34
|
+
secrets.add(ref);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
check(LITERAL_ENV.test(key), `environment ${key} is not allowed`);
|
|
38
|
+
check(!value.includes('$'), `environment ${key} may not reference variables`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return secrets;
|
|
42
|
+
}
|
|
43
|
+
function checkComposeFile(compose, images) {
|
|
44
|
+
check(isObj(compose), 'compose file must be an object');
|
|
45
|
+
check(Object.keys(compose).every((k) => ['name', 'services', 'volumes', 'configs'].includes(k)), 'compose file has unsupported top-level keys');
|
|
46
|
+
const services = compose['services'];
|
|
47
|
+
check(isObj(services) && Object.keys(services).length === 1, 'compose file must have exactly one service');
|
|
48
|
+
const service = Object.values(services)[0];
|
|
49
|
+
check(isObj(service), 'service must be an object');
|
|
50
|
+
const extra = Object.keys(service).filter((k) => !SERVICE_KEYS.has(k));
|
|
51
|
+
check(extra.length === 0, `service option ${extra[0]} is not allowed`);
|
|
52
|
+
const digest = typeof service['image'] === 'string' ? IMAGE.exec(service['image'])?.[1] : undefined;
|
|
53
|
+
check(digest, 'service image must be pinned by digest');
|
|
54
|
+
const image = images.find((i) => i.digest === digest);
|
|
55
|
+
check(image, `image ${digest.slice(0, 19)}… is not an approved Antseed TEE seller image`);
|
|
56
|
+
const secrets = checkEnvironment(service['environment']);
|
|
57
|
+
// Compose substitutes ${...} in every value; only the environment entries checked above may use it.
|
|
58
|
+
const { environment: _env, ...rest } = service;
|
|
59
|
+
check(!hasVariableReference({ ...compose, services: { s: rest } }), 'compose file may not reference variables outside the environment');
|
|
60
|
+
check(service['ports'] === undefined || (Array.isArray(service['ports']) && service['ports'].every((p) => typeof p === 'string' && /^[0-9.:]+(?:\/(?:tcp|udp))?$/.test(p))), 'ports must be plain port mappings');
|
|
61
|
+
const volumes = service['volumes'] ?? [];
|
|
62
|
+
check(Array.isArray(volumes), 'volumes must be a list');
|
|
63
|
+
const named = new Set();
|
|
64
|
+
for (const v of volumes) {
|
|
65
|
+
check(typeof v === 'string', 'volumes must use the short syntax');
|
|
66
|
+
const [source, target, ...more] = v.split(':');
|
|
67
|
+
check(more.length === 0 && source && target, `volume ${v} is not allowed`);
|
|
68
|
+
if (target === DSTACK_SOCKET && source === DSTACK_SOCKET)
|
|
69
|
+
continue;
|
|
70
|
+
check(target === DATA_DIR && /^[a-z0-9][a-z0-9_-]*$/.test(source), `volume ${v} is not allowed`);
|
|
71
|
+
named.add(source);
|
|
72
|
+
}
|
|
73
|
+
const topVolumes = compose['volumes'] ?? {};
|
|
74
|
+
check(isObj(topVolumes) && Object.entries(topVolumes).every(([k, v]) => named.has(k) && (v === null || (isObj(v) && Object.keys(v).length === 0))), 'volumes must be plain named volumes');
|
|
75
|
+
const configs = service['configs'];
|
|
76
|
+
check(Array.isArray(configs) && configs.length === 1 && isObj(configs[0]), 'the seller config must be one inline config');
|
|
77
|
+
const ref = configs[0];
|
|
78
|
+
check(Object.keys(ref).every((k) => k === 'source' || k === 'target') && ref['target'] === CONFIG_PATH, `the seller config must be mounted at ${CONFIG_PATH}`);
|
|
79
|
+
const top = compose['configs'];
|
|
80
|
+
check(isObj(top) && Object.keys(top).length === 1 && typeof ref['source'] === 'string', 'the seller config must be one inline config');
|
|
81
|
+
const content = top[ref['source']];
|
|
82
|
+
check(isObj(content) && Object.keys(content).length === 1 && typeof content['content'] === 'string', 'the seller config must be inline content');
|
|
83
|
+
const { upstreams, apiKeyEnvs } = checkSellerConfig(parseJson(content['content'], 'seller config'));
|
|
84
|
+
checkHiddenSecrets(secrets, apiKeyEnvs);
|
|
85
|
+
return { image, upstreams, secrets };
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Check a seller's app-compose.json against the compose hash its quote measured, then against
|
|
89
|
+
* the rules above. Returns the approved image and the seller's upstreams, or why it fails.
|
|
90
|
+
*/
|
|
91
|
+
export function checkAppCompose(appCompose, composeHash, images) {
|
|
92
|
+
if (createHash('sha256').update(appCompose, 'utf8').digest('hex') !== composeHash.toLowerCase()) {
|
|
93
|
+
return { error: 'app compose does not match the measured compose hash' };
|
|
94
|
+
}
|
|
95
|
+
try {
|
|
96
|
+
const app = parseJson(appCompose, 'app compose');
|
|
97
|
+
check(isObj(app), 'app compose must be an object');
|
|
98
|
+
const extra = Object.keys(app).filter((k) => !APP_COMPOSE_KEYS.has(k));
|
|
99
|
+
check(extra.length === 0, `app compose option ${extra[0]} is not allowed`);
|
|
100
|
+
check(app['runner'] === 'docker-compose' && typeof app['docker_compose_file'] === 'string', 'app must run a docker compose file');
|
|
101
|
+
check(!app['pre_launch_script'], 'app may not run a pre-launch script');
|
|
102
|
+
const { image, upstreams, secrets } = checkComposeFile(parseJson(app['docker_compose_file'], 'compose file (write it as JSON)'), images);
|
|
103
|
+
const allowed = app['allowed_envs'] ?? [];
|
|
104
|
+
check(Array.isArray(allowed) && allowed.every((n) => typeof n === 'string' && secrets.has(n)), 'app may only accept the encrypted variables its compose file uses as secrets');
|
|
105
|
+
return { image, upstreams };
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
if (err instanceof RuleError)
|
|
109
|
+
return { error: err.message };
|
|
110
|
+
throw err;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=dstack-app-compose.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dstack-app-compose.js","sourceRoot":"","sources":["../src/dstack-app-compose.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAuB,MAAM,0BAA0B,CAAA;AA+BlK,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC;IAC/B,kBAAkB,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,qBAAqB,EAAE,eAAe;IACxF,aAAa,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,aAAa,EAAE,iBAAiB,EAAE,gBAAgB;IACrG,4BAA4B,EAAE,cAAc,EAAE,iBAAiB,EAAE,cAAc,EAAE,gBAAgB;IACjG,aAAa,EAAE,mBAAmB,EAAE,YAAY,EAAE,WAAW;CAC9D,CAAC,CAAA;AACF,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,gBAAgB,CAAC,CAAC,CAAA;AAClH,MAAM,WAAW,GAAG,0BAA0B,CAAA;AAC9C,MAAM,QAAQ,GAAG,kBAAkB,CAAA;AACnC,MAAM,aAAa,GAAG,sBAAsB,CAAA;AAC5C,MAAM,KAAK,GAAG,gDAAgD,CAAA;AAE9D,kEAAkE;AAClE,SAAS,oBAAoB,CAAC,KAAc;IAC1C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;IACzD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAA;IACjE,IAAI,KAAK,CAAC,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAA;IACvH,OAAO,KAAK,CAAA;AACd,CAAC;AAED,qEAAqE;AACrE,SAAS,gBAAgB,CAAC,GAAY;IACpC,KAAK,CAAC,GAAG,KAAK,SAAS,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,2BAA2B,CAAC,CAAA;IACnE,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAA;IACjC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,CAAC;QACrD,KAAK,CAAC,OAAO,KAAK,KAAK,QAAQ,EAAE,eAAe,GAAG,mBAAmB,CAAC,CAAA;QACvE,MAAM,GAAG,GAAG,2BAA2B,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACxD,IAAI,GAAG,EAAE,CAAC;YACR,MAAM,UAAU,GAAG,GAAG,KAAK,8BAA8B,IAAI,GAAG,KAAK,sBAAsB,CAAA;YAC3F,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,GAAG,IAAI,UAAU,CAAC,EAAE,eAAe,GAAG,sCAAsC,CAAC,CAAA;YACpH,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAClB,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,eAAe,GAAG,iBAAiB,CAAC,CAAA;YACjE,KAAK,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,eAAe,GAAG,8BAA8B,CAAC,CAAA;QAC/E,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,SAAS,gBAAgB,CAAC,OAAgB,EAAE,MAAsC;IAChF,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,gCAAgC,CAAC,CAAA;IACvD,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,6CAA6C,CAAC,CAAA;IAC/I,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;IACpC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,4CAA4C,CAAC,CAAA;IAC1G,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;IAC1C,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,2BAA2B,CAAC,CAAA;IAClD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;IACtE,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,kBAAkB,KAAK,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAA;IAEtE,MAAM,MAAM,GAAG,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IACnG,KAAK,CAAC,MAAM,EAAE,wCAAwC,CAAC,CAAA;IACvD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAA;IACrD,KAAK,CAAC,KAAK,EAAE,SAAS,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,+CAA+C,CAAC,CAAA;IAEzF,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAA;IACxD,oGAAoG;IACpG,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,CAAA;IAC9C,KAAK,CAAC,CAAC,oBAAoB,CAAC,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,EAAE,kEAAkE,CAAC,CAAA;IAEvI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,8BAA8B,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,mCAAmC,CAAC,CAAA;IACjN,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,CAAA;IACxC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,wBAAwB,CAAC,CAAA;IACvD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAA;IAC/B,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,KAAK,CAAC,OAAO,CAAC,KAAK,QAAQ,EAAE,mCAAmC,CAAC,CAAA;QACjE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QAC9C,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,IAAI,MAAM,EAAE,UAAU,CAAC,iBAAiB,CAAC,CAAA;QAC1E,IAAI,MAAM,KAAK,aAAa,IAAI,MAAM,KAAK,aAAa;YAAE,SAAQ;QAClE,KAAK,CAAC,MAAM,KAAK,QAAQ,IAAI,uBAAuB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,CAAA;QAChG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IACnB,CAAC;IACD,MAAM,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,CAAA;IAC3C,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,qCAAqC,CAAC,CAAA;IAE1L,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAAA;IAClC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,6CAA6C,CAAC,CAAA;IACzH,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;IACtB,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,WAAW,EAAE,wCAAwC,WAAW,EAAE,CAAC,CAAA;IAC9J,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,CAAA;IAC9B,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,GAAG,CAAC,QAAQ,CAAC,KAAK,QAAQ,EAAE,6CAA6C,CAAC,CAAA;IACtI,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAA;IAClC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,OAAO,CAAC,SAAS,CAAC,KAAK,QAAQ,EAAE,0CAA0C,CAAC,CAAA;IAChJ,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,iBAAiB,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,eAAe,CAAC,CAAC,CAAA;IACnG,kBAAkB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAA;IACvC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,CAAA;AACtC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,UAAkB,EAClB,WAAmB,EACnB,MAAsC;IAEtC,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,WAAW,CAAC,WAAW,EAAE,EAAE,CAAC;QAChG,OAAO,EAAE,KAAK,EAAE,sDAAsD,EAAE,CAAA;IAC1E,CAAC;IACD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,SAAS,CAAC,UAAU,EAAE,aAAa,CAAC,CAAA;QAChD,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,+BAA+B,CAAC,CAAA;QAClD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;QACtE,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,sBAAsB,KAAK,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAA;QAC1E,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,gBAAgB,IAAI,OAAO,GAAG,CAAC,qBAAqB,CAAC,KAAK,QAAQ,EAAE,oCAAoC,CAAC,CAAA;QACjI,KAAK,CAAC,CAAC,GAAG,CAAC,mBAAmB,CAAC,EAAE,qCAAqC,CAAC,CAAA;QACvE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAAC,SAAS,CAAC,GAAG,CAAC,qBAAqB,CAAC,EAAE,iCAAiC,CAAC,EAAE,MAAM,CAAC,CAAA;QACxI,MAAM,OAAO,GAAG,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAA;QACzC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,8EAA8E,CAAC,CAAA;QAC9K,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAA;IAC7B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,SAAS;YAAE,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,CAAA;QAC3D,MAAM,GAAG,CAAA;IACX,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dstack (Phala) CVMs measure the app into RTMR3 at boot as runtime events: app-id, compose-hash
|
|
3
|
+
* (SHA-256 of app-compose.json, which pins the container images and their config), init scripts,
|
|
4
|
+
* instance-id, then boot-mr-done. RTMR3 differs per instance, so a buyer replays the event log to
|
|
5
|
+
* RTMR3 and reads the compose hash from it instead of pinning RTMR3.
|
|
6
|
+
*/
|
|
7
|
+
/** dstack's runtime event type (not a TCG type). */
|
|
8
|
+
export declare const DSTACK_RUNTIME_EVENT_TYPE = 134217729;
|
|
9
|
+
/** One event-log entry as the dstack guest agent returns it (bytes hex-encoded). */
|
|
10
|
+
export interface DstackEvent {
|
|
11
|
+
imr: number;
|
|
12
|
+
event_type: number;
|
|
13
|
+
digest: string;
|
|
14
|
+
event: string;
|
|
15
|
+
event_payload: string;
|
|
16
|
+
/** Digest format: absent or 1 = binary preimage, 2 = canonical JSON. */
|
|
17
|
+
version?: number;
|
|
18
|
+
}
|
|
19
|
+
/** The SHA-384 digest dstack extends RTMR3 with for a runtime event (v1 binary or v2 canonical JSON preimage). */
|
|
20
|
+
export declare function runtimeEventDigest(name: string, payload: Buffer, version: number): Buffer;
|
|
21
|
+
/**
|
|
22
|
+
* Parse a dstack event log (the JSON string or its decoded array) and check each entry's shape;
|
|
23
|
+
* replay checks the contents. Throws on anything else.
|
|
24
|
+
*/
|
|
25
|
+
export declare function parseDstackEventLog(eventLog: unknown): DstackEvent[];
|
|
26
|
+
/** The RTMR3 events from a dstack event log (the JSON string or its parsed array). */
|
|
27
|
+
export declare function rtmr3Events(eventLog: unknown): DstackEvent[];
|
|
28
|
+
/**
|
|
29
|
+
* Replay a dstack RTMR3 event log against the quote's (DCAP-verified) RTMR3 and return the app's
|
|
30
|
+
* compose hash. Every digest is recomputed from the event's name and payload, so a matching RTMR3
|
|
31
|
+
* authenticates each event as dstack measured it. It fails when:
|
|
32
|
+
* - the replay does not reproduce RTMR3;
|
|
33
|
+
* - boot did not finish (no boot-mr-done), or there is not exactly one compose-hash before it;
|
|
34
|
+
* - any init script ran: init scripts are measured outside the compose file, so an approved
|
|
35
|
+
* compose hash would not cover them.
|
|
36
|
+
*/
|
|
37
|
+
export declare function composeHashFromEventLog(events: readonly DstackEvent[], rtmr3: Uint8Array): {
|
|
38
|
+
composeHash: string;
|
|
39
|
+
} | {
|
|
40
|
+
error: string;
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=dstack-event-log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dstack-event-log.d.ts","sourceRoot":"","sources":["../src/dstack-event-log.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,oDAAoD;AACpD,eAAO,MAAM,yBAAyB,YAAa,CAAA;AAKnD,oFAAoF;AACpF,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAA;IACX,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,MAAM,CAAA;IACrB,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,kHAAkH;AAClH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CASzF;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,OAAO,GAAG,WAAW,EAAE,CAUpE;AAED,sFAAsF;AACtF,wBAAgB,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,WAAW,EAAE,CAE5D;AAWD;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,EAAE,KAAK,EAAE,UAAU,GAAG;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAqBtI"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
/**
|
|
3
|
+
* dstack (Phala) CVMs measure the app into RTMR3 at boot as runtime events: app-id, compose-hash
|
|
4
|
+
* (SHA-256 of app-compose.json, which pins the container images and their config), init scripts,
|
|
5
|
+
* instance-id, then boot-mr-done. RTMR3 differs per instance, so a buyer replays the event log to
|
|
6
|
+
* RTMR3 and reads the compose hash from it instead of pinning RTMR3.
|
|
7
|
+
*/
|
|
8
|
+
/** dstack's runtime event type (not a TCG type). */
|
|
9
|
+
export const DSTACK_RUNTIME_EVENT_TYPE = 0x08000001;
|
|
10
|
+
/** Generous bound on the RTMR3 events a seller may send; dstack emits under ten at boot. */
|
|
11
|
+
const MAX_RTMR3_EVENTS = 64;
|
|
12
|
+
/** The SHA-384 digest dstack extends RTMR3 with for a runtime event (v1 binary or v2 canonical JSON preimage). */
|
|
13
|
+
export function runtimeEventDigest(name, payload, version) {
|
|
14
|
+
if (version === 2) {
|
|
15
|
+
// JCS (RFC 8785): keys sorted, no whitespace. JSON.stringify serializes the string values the same way.
|
|
16
|
+
const canonical = `{"name":${JSON.stringify(name)},"payload":${JSON.stringify(payload.toString('hex'))},"type":${DSTACK_RUNTIME_EVENT_TYPE}}`;
|
|
17
|
+
return createHash('sha384').update(canonical, 'utf8').digest();
|
|
18
|
+
}
|
|
19
|
+
const type = Buffer.alloc(4);
|
|
20
|
+
type.writeUInt32LE(DSTACK_RUNTIME_EVENT_TYPE, 0);
|
|
21
|
+
return createHash('sha384').update(Buffer.concat([type, Buffer.from(':'), Buffer.from(name, 'utf8'), Buffer.from(':'), payload])).digest();
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Parse a dstack event log (the JSON string or its decoded array) and check each entry's shape;
|
|
25
|
+
* replay checks the contents. Throws on anything else.
|
|
26
|
+
*/
|
|
27
|
+
export function parseDstackEventLog(eventLog) {
|
|
28
|
+
const parsed = typeof eventLog === 'string' ? JSON.parse(eventLog) : eventLog;
|
|
29
|
+
if (!Array.isArray(parsed))
|
|
30
|
+
throw new Error('event log is not an array');
|
|
31
|
+
for (const e of parsed) {
|
|
32
|
+
if (!e || typeof e !== 'object' || typeof e.imr !== 'number' || typeof e.event_type !== 'number'
|
|
33
|
+
|| typeof e.event !== 'string' || typeof e.event_payload !== 'string') {
|
|
34
|
+
throw new Error('event log entry is not a dstack event');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return parsed;
|
|
38
|
+
}
|
|
39
|
+
/** The RTMR3 events from a dstack event log (the JSON string or its parsed array). */
|
|
40
|
+
export function rtmr3Events(eventLog) {
|
|
41
|
+
return parseDstackEventLog(eventLog).filter((e) => e.imr === 3);
|
|
42
|
+
}
|
|
43
|
+
const HEX = /^(?:[0-9a-fA-F]{2})*$/;
|
|
44
|
+
/**
|
|
45
|
+
* dstack event names are kebab-case. The v1 digest preimage is `type ‖ ":" ‖ name ‖ ":" ‖ payload`
|
|
46
|
+
* with no lengths, so a name holding ":" could move bytes between name and payload without
|
|
47
|
+
* changing the digest (e.g. "init-script-hash:" with the payload's leading ":" removed). Only
|
|
48
|
+
* names without delimiters are accepted, which makes every preimage split one way.
|
|
49
|
+
*/
|
|
50
|
+
const EVENT_NAME = /^[a-z0-9][a-z0-9-]*$/;
|
|
51
|
+
/**
|
|
52
|
+
* Replay a dstack RTMR3 event log against the quote's (DCAP-verified) RTMR3 and return the app's
|
|
53
|
+
* compose hash. Every digest is recomputed from the event's name and payload, so a matching RTMR3
|
|
54
|
+
* authenticates each event as dstack measured it. It fails when:
|
|
55
|
+
* - the replay does not reproduce RTMR3;
|
|
56
|
+
* - boot did not finish (no boot-mr-done), or there is not exactly one compose-hash before it;
|
|
57
|
+
* - any init script ran: init scripts are measured outside the compose file, so an approved
|
|
58
|
+
* compose hash would not cover them.
|
|
59
|
+
*/
|
|
60
|
+
export function composeHashFromEventLog(events, rtmr3) {
|
|
61
|
+
if (events.length > MAX_RTMR3_EVENTS)
|
|
62
|
+
return { error: 'malformed dstack event log' };
|
|
63
|
+
let mr = Buffer.alloc(48);
|
|
64
|
+
for (const e of events) {
|
|
65
|
+
if (e.event_type !== DSTACK_RUNTIME_EVENT_TYPE || !EVENT_NAME.test(e.event) || !HEX.test(e.event_payload)) {
|
|
66
|
+
return { error: 'malformed dstack event log' };
|
|
67
|
+
}
|
|
68
|
+
if (e.version !== undefined && e.version !== 1 && e.version !== 2)
|
|
69
|
+
return { error: `unknown dstack event log version ${String(e.version)}` };
|
|
70
|
+
const digest = runtimeEventDigest(e.event, Buffer.from(e.event_payload, 'hex'), e.version ?? 1);
|
|
71
|
+
mr = createHash('sha384').update(Buffer.concat([mr, digest])).digest();
|
|
72
|
+
}
|
|
73
|
+
if (!mr.equals(Buffer.from(rtmr3)))
|
|
74
|
+
return { error: 'dstack event log does not replay to the quote\'s RTMR3' };
|
|
75
|
+
const boot = events;
|
|
76
|
+
const done = boot.findIndex((e) => e.event === 'boot-mr-done');
|
|
77
|
+
if (done < 0)
|
|
78
|
+
return { error: 'dstack boot did not complete (no boot-mr-done event)' };
|
|
79
|
+
const measured = boot.slice(0, done);
|
|
80
|
+
if (measured.some((e) => e.event === 'init-script-hash'))
|
|
81
|
+
return { error: 'the CVM ran init scripts outside the approved compose file' };
|
|
82
|
+
const compose = measured.filter((e) => e.event === 'compose-hash');
|
|
83
|
+
if (compose.length !== 1 || compose[0].event_payload.length !== 64)
|
|
84
|
+
return { error: 'dstack event log has no single compose-hash event' };
|
|
85
|
+
return { composeHash: compose[0].event_payload.toLowerCase() };
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=dstack-event-log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dstack-event-log.js","sourceRoot":"","sources":["../src/dstack-event-log.ts"],"names":[],"mappings":"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"}
|
package/dist/prover.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prover.d.ts","sourceRoot":"","sources":["../src/prover.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAiC,MAAM,yBAAyB,CAAA;AACpF,OAAO,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"prover.d.ts","sourceRoot":"","sources":["../src/prover.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAiC,MAAM,yBAAyB,CAAA;AACpF,OAAO,iBAAiB,CAAA;AA8JxB,QAAA,MAAM,MAAM,EAAE,MAwEb,CAAA;AAED,eAAe,MAAM,CAAA"}
|
package/dist/prover.js
CHANGED
|
@@ -5,7 +5,7 @@ import { NODE_TEE_CAP_ID, PROVIDER_TEE_CAP_ID, encodeTeeTdxEvidence, tdxConfigKe
|
|
|
5
5
|
import { GPU_CAP_ID, gpuConfigKey } from './caps/gpu-nvidia.js';
|
|
6
6
|
import { claimsConfigKey } from './caps/provider-claims.js';
|
|
7
7
|
import { loadAdapter } from './adapters/index.js';
|
|
8
|
-
import { VERIFIER_ID, decodeAttestRequest, encodeAttestResponse, evidenceConfigKey, normalizePeerId, } from './shared.js';
|
|
8
|
+
import { CHANNEL_BINDING_HEADER, VERIFIER_ID, decodeAttestRequest, encodeAttestResponse, evidenceConfigKey, normalizeChannelBinding, normalizePeerId, } from './shared.js';
|
|
9
9
|
/**
|
|
10
10
|
* Seller half — embedded prover (type:'prover'). For each requested capability the seller
|
|
11
11
|
* supports (has a collector for, and whose collection succeeds), it produces evidence and
|
|
@@ -15,7 +15,7 @@ import { VERIFIER_ID, decodeAttestRequest, encodeAttestResponse, evidenceConfigK
|
|
|
15
15
|
* Env config (the seller offers each provider cap only when the evidence URL and its field are
|
|
16
16
|
* set, all off the same route):
|
|
17
17
|
* ANTSEED_TEE_PEER_ID this node's peer id (EVM address, no 0x) — required
|
|
18
|
-
* ANTSEED_VERIFIER_NODE_TEE seller-node-tee-genuine source: "configfs" (default), "dstack", or "http"
|
|
18
|
+
* ANTSEED_VERIFIER_NODE_TEE seller-node-tee-genuine source: "configfs" (default), "dstack", "confidential-space", or "http"
|
|
19
19
|
* ANTSEED_VERIFIER_DSTACK_SOCKET override the dstack guest-agent socket path (default /var/run/dstack.sock)
|
|
20
20
|
* ANTSEED_VERIFIER_PROVIDER_ADAPTER in-process provider adapter id (e.g. "chutes", "aci"); fetches provider evidence directly, no separate shim
|
|
21
21
|
* ANTSEED_VERIFIER_PROVIDER_EVIDENCE_URL provider evidence route ({nonce} hex placeholder); offers seller-provider-tee-genuine via http (alternative to an adapter)
|
|
@@ -145,7 +145,7 @@ const prover = {
|
|
|
145
145
|
type: 'prover',
|
|
146
146
|
name: VERIFIER_ID,
|
|
147
147
|
displayName: 'TEE attestation prover (capability-based)',
|
|
148
|
-
version: '0.1.
|
|
148
|
+
version: '0.1.1',
|
|
149
149
|
description: 'Produces per-capability seller attestation evidence (Intel TDX quote, seller-identity signature) for buyers to verify.',
|
|
150
150
|
async prove(req) {
|
|
151
151
|
const rawPeer = process.env[PEER_ID_KEY]?.trim();
|
|
@@ -163,14 +163,27 @@ const prover = {
|
|
|
163
163
|
}
|
|
164
164
|
let nonce;
|
|
165
165
|
let caps;
|
|
166
|
+
let bindChannel;
|
|
166
167
|
try {
|
|
167
168
|
;
|
|
168
|
-
({ nonce, caps } = decodeAttestRequest(req.body ?? new Uint8Array()));
|
|
169
|
+
({ nonce, caps, bindChannel } = decodeAttestRequest(req.body ?? new Uint8Array()));
|
|
169
170
|
}
|
|
170
171
|
catch (err) {
|
|
171
172
|
return json(400, { error: { message: msg(err), type: 'invalid_request_error' } });
|
|
172
173
|
}
|
|
173
174
|
const config = baseConfig();
|
|
175
|
+
// A buyer that asks for it gets the node quote bound to its connection. The seller node sets
|
|
176
|
+
// the header from the connection the request arrived on; without it the node cap is omitted
|
|
177
|
+
// rather than minted unbound.
|
|
178
|
+
if (bindChannel) {
|
|
179
|
+
const header = Object.entries(req.headers ?? {}).find(([name]) => name.toLowerCase() === CHANNEL_BINDING_HEADER)?.[1];
|
|
180
|
+
try {
|
|
181
|
+
config[tdxConfigKey(NODE_TEE_CAP_ID, 'channelBinding')] = normalizeChannelBinding(header ?? '');
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
config[tdxConfigKey(NODE_TEE_CAP_ID, 'source')] = 'unavailable';
|
|
185
|
+
}
|
|
186
|
+
}
|
|
174
187
|
const sign = buildSigner(peerId);
|
|
175
188
|
const evidence = {};
|
|
176
189
|
// A selected provider adapter pre-fills the provider caps in-process, before the collect loop.
|
package/dist/prover.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prover.js","sourceRoot":"","sources":["../src/prover.ts"],"names":[],"mappings":"AACA,OAAO,iBAAiB,CAAA,CAAC,4CAA4C;AACrE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AACjE,OAAO,EAAE,wBAAwB,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AACvF,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAC5G,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACjD,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,eAAe,GAChB,MAAM,aAAa,CAAA;AAEpB;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,WAAW,GAAG,qBAAqB,CAAA;AACzC,MAAM,WAAW,GAAG,8BAA8B,CAAA;AAClD,MAAM,gBAAgB,GAAG,mCAAmC,CAAA;AAC5D,MAAM,eAAe,GAAG,2BAA2B,CAAA;AACnD,MAAM,aAAa,GAAG,gCAAgC,CAAA;AACtD,MAAM,qBAAqB,GAAG,wCAAwC,CAAA;AACtE,MAAM,kBAAkB,GAAG,qCAAqC,CAAA;AAChE,MAAM,kBAAkB,GAAG,qCAAqC,CAAA;AAChE,MAAM,qBAAqB,GAAG,wCAAwC,CAAA;AACtE,MAAM,uBAAuB,GAAG,0CAA0C,CAAA;AAC1E,MAAM,6BAA6B,GAAG,gDAAgD,CAAA;AAEtF,SAAS,GAAG,CAAC,GAAY;IACvB,OAAO,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;AACzD,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,iBAAiB,CAC9B,KAAiB,EACjB,IAAc,EACd,QAAoC,EACpC,MAA8B;IAE9B,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,CAAA;IAChD,IAAI,CAAC,EAAE;QAAE,OAAM;IACf,MAAM,GAAG,GAAG,CAAC,KAAa,EAAE,KAAiB,EAAQ,EAAE;QACrD,QAAQ,CAAC,KAAK,CAAC,GAAG,KAAK,CAAA;QACvB,MAAM,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;IAC1E,CAAC,CAAA;IACD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,EAAE,CAAC,CAAA;QACrC,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,CAAA;QAC1D,IAAI,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;YACvC,MAAM,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,aAAa,EAAE,WAAW,EAAE,EAAE,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAA;YAC9G,GAAG,CAAC,mBAAmB,EAAE,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAA;QAC9E,CAAC;QACD,IAAI,EAAE,CAAC,WAAW,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAChD,GAAG,CAAC,UAAU,EAAE,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;QAC3E,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,WAAW,uBAAuB,EAAE,kBAAkB,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAC9F,CAAC;AACH,CAAC;AAED,SAAS,IAAI,CAAC,UAAkB,EAAE,IAAa;IAC7C,OAAO;QACL,UAAU;QACV,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;KACrD,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,UAAU;IACjB,MAAM,GAAG,GAA2B,EAAE,CAAA;IACtC,mFAAmF;IACnF,GAAG,CAAC,YAAY,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,IAAI,EAAE,IAAI,UAAU,CAAA;IACjG,mGAAmG;IACnG,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,CAAA;IACvD,IAAI,YAAY;QAAE,GAAG,CAAC,YAAY,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC,GAAG,YAAY,CAAA;IACpF,0FAA0F;IAC1F,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,EAAE,IAAI,EAAE,CAAA;IAC1D,IAAI,OAAO,EAAE,CAAC;QACZ,GAAG,CAAC,YAAY,CAAC,mBAAmB,EAAE,QAAQ,CAAC,CAAC,GAAG,MAAM,CAAA;QACzD,GAAG,CAAC,YAAY,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC,GAAG,OAAO,CAAA;QACvD,GAAG,CAAC,YAAY,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,IAAI,OAAO,CAAA;QACpG,uFAAuF;QACvF,4FAA4F;QAC5F,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,EAAE,IAAI,EAAE,CAAA;QAClE,IAAI,aAAa,EAAE,CAAC;YAClB,GAAG,CAAC,YAAY,CAAC,mBAAmB,EAAE,gBAAgB,CAAC,CAAC,GAAG,aAAa,CAAA;YACxE,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,EAAE,IAAI,EAAE,CAAA;YACtE,IAAI,WAAW;gBAAE,GAAG,CAAC,YAAY,CAAC,mBAAmB,EAAE,qBAAqB,CAAC,CAAC,GAAG,WAAW,CAAA;QAC9F,CAAC;QACD,uFAAuF;QACvF,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,CAAA;QACxD,IAAI,QAAQ,EAAE,CAAC;YACb,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,GAAG,OAAO,CAAA;YAClC,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,GAAG,QAAQ,CAAA;QACvC,CAAC;QACD,0FAA0F;QAC1F,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,EAAE,IAAI,EAAE,CAAA;QAC9D,IAAI,WAAW,EAAE,CAAC;YAChB,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,GAAG,OAAO,CAAA;YACrC,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,GAAG,WAAW,CAAA;QAC7C,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED;;;;GAIG;AACH,SAAS,WAAW,CAAC,MAAc;IACjC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,CAAA;IAC5C,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAA;IAC1B,IAAI,CAAC;QACH,IAAI,wBAAwB,CAAC,GAAG,CAAC,KAAK,MAAM,EAAE,CAAC;YAC7C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,WAAW,KAAK,WAAW,eAAe,WAAW,2BAA2B,CAAC,CAAA;YAC1G,OAAO,SAAS,CAAA;QAClB,CAAC;QACD,OAAO,oBAAoB,CAAC,GAAG,CAAC,CAAA;IAClC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,WAAW,aAAa,WAAW,4BAA4B,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACrG,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED,MAAM,MAAM,GAAW;IACrB,IAAI,EAAE,QAAQ;IACd,IAAI,EAAE,WAAW;IACjB,WAAW,EAAE,2CAA2C;IACxD,OAAO,EAAE,OAAO;IAChB,WAAW,EAAE,wHAAwH;IAErI,KAAK,CAAC,KAAK,CAAC,GAAkB;QAC5B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,CAAA;QAChD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,GAAG,EAAE;gBACf,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,WAAW,qEAAqE,EAAE,IAAI,EAAE,WAAW,EAAE;aAC3H,CAAC,CAAA;QACJ,CAAC;QACD,IAAI,MAAc,CAAA;QAClB,IAAI,CAAC;YACH,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,CAAA;QACnC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,CAAC,CAAA;QACvE,CAAC;QAED,IAAI,KAAiB,CAAA;QACrB,IAAI,IAAc,CAAA;QAClB,IAAI,CAAC;YACH,CAAC;YAAA,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,mBAAmB,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,UAAU,EAAE,CAAC,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"prover.js","sourceRoot":"","sources":["../src/prover.ts"],"names":[],"mappings":"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"}
|
package/dist/report-data.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* hardware stack. The SDK verifies against a closed, version-pinned registry:
|
|
5
5
|
*
|
|
6
6
|
* - antseed-rd-v1 the canonical, compositional scheme. The nonce is always bound;
|
|
7
|
-
* optional fields (peerId, e2ePubkey) are included only when their
|
|
7
|
+
* optional fields (peerId, e2ePubkey, channelBinding) are included only when their
|
|
8
8
|
* ingredient is present, in canonical tag order, each tagged and
|
|
9
9
|
* length-prefixed. One rule covers every combination — the node
|
|
10
10
|
* cap is the {peerId} case. A new field takes a new tag and version bump.
|
|
@@ -24,6 +24,8 @@ export interface BindingIngredients {
|
|
|
24
24
|
e2ePubkey?: string;
|
|
25
25
|
/** ACI workload keyset digest, "sha256:<64 hex>" — the ACI ingredient. */
|
|
26
26
|
keysetDigest?: string;
|
|
27
|
+
/** 64-hex session hash of the buyer↔seller connection the attestation ran over (node cap). */
|
|
28
|
+
channelBinding?: string;
|
|
27
29
|
}
|
|
28
30
|
export interface ReportDataScheme {
|
|
29
31
|
id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report-data.d.ts","sourceRoot":"","sources":["../src/report-data.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,WAAW,kBAAkB;IACjC,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,0EAA0E;IAC1E,YAAY,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"report-data.d.ts","sourceRoot":"","sources":["../src/report-data.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,WAAW,kBAAkB;IACjC,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,0EAA0E;IAC1E,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,8FAA8F;IAC9F,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAA;IACV,wFAAwF;IACxF,UAAU,EAAE,EAAE,GAAG,EAAE,CAAA;IACnB,+EAA+E;IAC/E,KAAK,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,kBAAkB,GAAG,UAAU,CAAA;IAC7D,iFAAiF;IACjF,QAAQ,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,kBAAkB,GAAG,UAAU,CAAA;CACjE;AAsBD,eAAO,MAAM,WAAW,EAAE,gBAoBzB,CAAA;AAED,eAAO,MAAM,mBAAmB,EAAE,gBAmBjC,CAAA;AAED,eAAO,MAAM,WAAW,EAAE,gBAmBzB,CAAA;AAED,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAIhE,CAAA;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAE5E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,UAAU,EACjB,GAAG,EAAE,kBAAkB,GACtB,MAAM,GAAG,IAAI,CAcf"}
|
package/dist/report-data.js
CHANGED
|
@@ -14,6 +14,7 @@ function lenPrefixed(b) {
|
|
|
14
14
|
const FIELDS = [
|
|
15
15
|
{ tag: 0x01, get: (i) => (i.peerId ? Buffer.from(i.peerId.toLowerCase(), 'hex') : null) },
|
|
16
16
|
{ tag: 0x02, get: (i) => (i.e2ePubkey ? Buffer.from(i.e2ePubkey, 'base64') : null) },
|
|
17
|
+
{ tag: 0x03, get: (i) => (i.channelBinding ? Buffer.from(i.channelBinding.toLowerCase(), 'hex') : null) },
|
|
17
18
|
];
|
|
18
19
|
export const antseedRdV1 = {
|
|
19
20
|
id: RD_DOMAIN,
|