@ethernity-cloud/sdk-js 1.1.0 → 1.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.
@@ -28,6 +28,9 @@ services:
28
28
  - SCONE_LAS_ADDR=las
29
29
  - SCONE_CONFIG_ID=__ENCLAVE_NAME_SECURELOCK__/application
30
30
  - SCONE_HEAP=1024M
31
+ # Must match the --stack the securelock binary was signed with (build.mjs),
32
+ # otherwise SCONE recomputes MRENCLAVE at load and re-signs as debug.
33
+ - SCONE_STACK=4M
31
34
  - SCONE_LOG=DEBUG
32
35
  - SCONE_ALLOW_DLOPEN=1
33
36
  - SCONE_EXTENSIONS_PATH=/lib/libbinary-fs.so
@@ -1,3 +1,10 @@
1
+ # Publish-time compose: used by ecld-publish to compute the MRENCLAVE
2
+ # (SCONE_HASH=1) and extract the enclave certificate LOCALLY. It intentionally
3
+ # does NOT mount /dev/sgx_enclave so it runs on a developer machine WITHOUT SGX
4
+ # (SCONE_HASH is a build measurement; enclaves reach SGX via LAS over TCP). When
5
+ # no local SGX is present, cert extraction falls back to the remote
6
+ # publickey.ethernity.cloud service. The on-node runtime uses
7
+ # docker-compose-final.yml, which targets real SGX hardware.
1
8
  version: '3.2'
2
9
  services:
3
10
  las:
@@ -6,8 +13,6 @@ services:
6
13
  image: localhost:5000/etny-las
7
14
  entrypoint: "/las_entrypoint.sh"
8
15
  command: "/usr/local/bin/las"
9
- devices:
10
- - "/dev/sgx_enclave:/dev/sgx_enclave"
11
16
  restart: on-failure
12
17
  ports:
13
18
  - target: 18766
@@ -26,12 +31,13 @@ services:
26
31
  - SCONE_LAS_ADDR=las
27
32
  - SCONE_CONFIG_ID=__ENCLAVE_NAME_SECURELOCK__/application
28
33
  - SCONE_HEAP=1024M
34
+ # Must match the --stack the securelock binary was signed with (build.mjs),
35
+ # otherwise SCONE recomputes MRENCLAVE at load and re-signs as debug.
36
+ - SCONE_STACK=4M
29
37
  - SCONE_LOG=DEBUG
30
38
  - SCONE_ALLOW_DLOPEN=1
31
39
  - SCONE_EXTENSIONS_PATH=/lib/libbinary-fs.so
32
40
  restart: on-failure:5
33
- devices:
34
- - "/dev/sgx_enclave:/dev/sgx_enclave"
35
41
  depends_on:
36
42
  - las
37
43
 
@@ -50,8 +56,6 @@ services:
50
56
  - SCONE_ALLOW_DLOPEN=1
51
57
  - SCONE_EXTENSIONS_PATH=/lib/libbinary-fs.so
52
58
  restart: on-failure
53
- devices:
54
- - "/dev/sgx_enclave:/dev/sgx_enclave"
55
59
  depends_on:
56
60
  - las
57
61
 
@@ -70,7 +74,5 @@ services:
70
74
  - SCONE_ALLOW_DLOPEN=1
71
75
  - SCONE_EXTENSIONS_PATH=/lib/libbinary-fs.so
72
76
  restart: on-failure:5
73
- devices:
74
- - "/dev/sgx_enclave:/dev/sgx_enclave"
75
77
  depends_on:
76
78
  - las
package/nodenithy/run.js CHANGED
@@ -73,6 +73,30 @@ const runDockerCommand = (service) => {
73
73
  return output.split('\n').filter(line => !/Creating|Pulling|latest|Digest/.test(line)).join('');
74
74
  };
75
75
 
76
+ // Extract the runtime enclave measurement (SCONE_HASH) as a bare 64-hex string.
77
+ // Mirrors Python extract_scone_hash: the enclave prints its MRENCLAVE somewhere
78
+ // in the SCONE_HASH=1 output; pick the first 64-hex token.
79
+ const extractSconeHash = (service) => {
80
+ const output = runDockerCommand(service);
81
+ const m = output.match(/\b[a-fA-F0-9]{64}\b/);
82
+ if (!m) throw new Error(`No SHA256 MRENCLAVE found in ${service} SCONE_HASH output.`);
83
+ return m[0];
84
+ };
85
+
86
+ // Read the MRENCLAVE that was signed at build time (baked into the image as
87
+ // /signed_mrenclave.txt by the securelock Dockerfile on mainnet). Mirrors Python
88
+ // extract_signed_mrenclave. Returns '' if the file is absent (testnet builds).
89
+ const extractSignedMrenclave = (service) => {
90
+ try {
91
+ const command = `docker-compose -f docker-compose.yml run --no-deps --entrypoint cat ${service} /signed_mrenclave.txt`;
92
+ const output = execSync(command, { stdio: ['pipe', 'pipe', 'pipe'] }).toString().trim();
93
+ const m = output.match(/\b[a-fA-F0-9]{64}\b/);
94
+ return m ? m[0] : '';
95
+ } catch (e) {
96
+ return '';
97
+ }
98
+ };
99
+
76
100
  const main = async () => {
77
101
  process.env.NODE_NO_WARNINGS = 1
78
102
  const backupFiles = ['docker-compose.yml.tmpl', 'docker-compose-final.yml.tmpl'];
@@ -86,13 +110,32 @@ const main = async () => {
86
110
  });
87
111
 
88
112
 
89
- process.env.MRENCLAVE_SECURELOCK = runDockerCommand('etny-securelock');
113
+ process.env.MRENCLAVE_SECURELOCK = extractSconeHash('etny-securelock');
90
114
  console.log(`MRENCLAVE_SECURELOCK: ${process.env.MRENCLAVE_SECURELOCK}`);
91
115
  // process.env.MRENCLAVE_TRUSTEDZONE = runDockerCommand('etny-trustedzone');
92
116
  // console.log(`MRENCLAVE_TRUSTEDZONE: ${process.env.MRENCLAVE_TRUSTEDZONE}`);
93
117
  // process.env.MRENCLAVE_VALIDATOR = runDockerCommand('etny-validator');
94
118
  // console.log(`MRENCLAVE_VALIDATOR: ${process.env.MRENCLAVE_VALIDATOR}`);
95
119
 
120
+ // ----- MRENCLAVE match-gate (mainnet) -----
121
+ // The runtime enclave measured just above (SCONE_HASH, with the same env the
122
+ // harvest uses) MUST match the MRENCLAVE that was signed --production at build
123
+ // time (baked into /signed_mrenclave.txt). A mismatch means SCONE recomputed
124
+ // the measurement at load because the runtime enclave-creation params drifted
125
+ // from the signed binary -- and a runtime recompute yields a DEBUG enclave
126
+ // that CAS rejects ("Debug mode is enabled"). Refuse to publish rather than
127
+ // register an untrusted identity on-chain or fail opaquely later.
128
+ if (isMainnet) {
129
+ const signedMrenclave = extractSignedMrenclave('etny-securelock');
130
+ if (!signedMrenclave || signedMrenclave !== process.env.MRENCLAVE_SECURELOCK) {
131
+ console.error(`Error: securelock runtime MRENCLAVE (${process.env.MRENCLAVE_SECURELOCK}) != signed MRENCLAVE (${signedMrenclave}).`);
132
+ console.error(' The runtime enclave differs from the --production-signed binary (SCONE recomputed -> debug).');
133
+ console.error(' Refusing to publish. Rebuild with the current SDK (ecld-build) and retry.');
134
+ process.exit(1);
135
+ }
136
+ console.log('\t✔ MRENCLAVE match-gate passed: runtime enclave matches the --production-signed MRENCLAVE');
137
+ }
138
+
96
139
  writeEnv('MRENCLAVE_SECURELOCK', process.env.MRENCLAVE_SECURELOCK);
97
140
  // writeEnv('MRENCLAVE_TRUSTEDZONE', process.env.MRENCLAVE_TRUSTEDZONE);
98
141
  // writeEnv('MRENCLAVE_VALIDATOR', process.env.MRENCLAVE_VALIDATOR);
package/package.json CHANGED
@@ -1,48 +1,48 @@
1
1
  {
2
- "name": "@ethernity-cloud/sdk-js",
3
- "version": "1.1.0",
4
- "description": "A package to run ethernity cloud build scripts",
5
- "scripts": {
6
- "ecld-build": "cross-env node ./node_modules/@ethernity-cloud/sdk-js/build.js",
7
- "ecld-publish": "cross-env node ./node_modules/@ethernity-cloud/sdk-js/publish.js",
8
- "ecld-init": "cross-env node ./node_modules/@ethernity-cloud/sdk-js/init.js",
9
- "ecld-run": "cross-env ecld-run",
10
- "postinstall": "node postinstall.js"
11
- },
12
- "bin": {
13
- "ecld-build": "./build.js",
14
- "ecld-publish": "./publish.js",
15
- "ecld-init": "./init.js",
16
- "postinstall": "./postinstall.js"
17
- },
18
- "files": [
19
- "nodenithy/*",
20
- "pynithy/*",
21
- "build.js",
22
- "init.js",
23
- "publish.js",
24
- "postinstall.js"
25
- ],
26
- "dependencies": {
27
- "@ethernity-cloud/runner": "^0.0.26",
28
- "axios": "^1.7.2",
29
- "commander": "^12.1.0",
30
- "dotenv": "^16.4.5",
31
- "eth-lib": "^0.1.29",
32
- "ethers": "^5.5.4",
33
- "kubo-rpc-client": "^4.1.1",
34
- "web3": "^4.9.0",
35
- "cross-env": "^7.0.3",
36
- "shelljs": "^0.8.5",
37
- "shx": "^0.3.4",
38
- "node-forge": "^1.3.1",
39
- "cli-progress": "^3.12.0",
40
- "react": "^18.3.1",
41
- "react-dom": "^18.3.1",
42
- "react-scripts": "^5.0.1",
43
- "web-vitals": "^2.1.4",
44
- "adm-zip": "^0.5.14"
45
- },
46
- "author": "Alexandru Luca",
47
- "license": "AGPL-3.0"
2
+ "name": "@ethernity-cloud/sdk-js",
3
+ "version": "1.2.0",
4
+ "description": "A package to run ethernity cloud build scripts",
5
+ "scripts": {
6
+ "ecld-build": "cross-env node ./node_modules/@ethernity-cloud/sdk-js/build.js",
7
+ "ecld-publish": "cross-env node ./node_modules/@ethernity-cloud/sdk-js/publish.js",
8
+ "ecld-init": "cross-env node ./node_modules/@ethernity-cloud/sdk-js/init.js",
9
+ "ecld-run": "cross-env ecld-run",
10
+ "postinstall": "node postinstall.js"
11
+ },
12
+ "bin": {
13
+ "ecld-build": "./build.js",
14
+ "ecld-publish": "./publish.js",
15
+ "ecld-init": "./init.js",
16
+ "postinstall": "./postinstall.js"
17
+ },
18
+ "files": [
19
+ "nodenithy/*",
20
+ "pynithy/*",
21
+ "build.js",
22
+ "init.js",
23
+ "publish.js",
24
+ "postinstall.js"
25
+ ],
26
+ "dependencies": {
27
+ "@ethernity-cloud/runner": "^0.0.26",
28
+ "axios": "^1.7.2",
29
+ "commander": "^12.1.0",
30
+ "dotenv": "^16.4.5",
31
+ "eth-lib": "^0.1.29",
32
+ "ethers": "^5.5.4",
33
+ "kubo-rpc-client": "^4.1.1",
34
+ "web3": "^4.9.0",
35
+ "cross-env": "^7.0.3",
36
+ "shelljs": "^0.8.5",
37
+ "shx": "^0.3.4",
38
+ "node-forge": "^1.3.1",
39
+ "cli-progress": "^3.12.0",
40
+ "react": "^18.3.1",
41
+ "react-dom": "^18.3.1",
42
+ "react-scripts": "^5.0.1",
43
+ "web-vitals": "^2.1.4",
44
+ "adm-zip": "^0.5.14"
45
+ },
46
+ "author": "Alexandru Luca",
47
+ "license": "AGPL-3.0"
48
48
  }
@@ -64,13 +64,29 @@ COPY --from=build /libbinary-fs.so /lib/libbinary-fs.so
64
64
 
65
65
  RUN openssl genrsa -3 -out /enclave-key.pem 3072
66
66
 
67
+ # SCONE runtime env. Must match the enclave-creation params passed to
68
+ # scone-signer below (any drift makes SCONE recompute + debug re-sign at load,
69
+ # which CAS rejects on mainnet). Values mirror the run/docker-compose securelock
70
+ # service (SCONE_HEAP=1024M, SCONE_STACK=4M, dlopen=1, extensions=libbinary-fs).
67
71
  ENV SCONE_LOG=INFO
68
72
  ENV SCONE_HEAP=1024M
73
+ ENV SCONE_STACK=4M
69
74
  ENV SCONE_ALLOW_DLOPEN=1
70
75
  ENV SCONE_EXTENSIONS_PATH=/lib/libbinary-fs.so
71
76
 
72
- # Disabled production mode for testnet
73
- # RUN scone-signer sign --key=/enclave-key.pem --env --production /usr/local/bin/python3
77
+ # Rendered by build.mjs. Signs the EXECUTED binary (/usr/local/bin/python -- the
78
+ # ENTRYPOINT and the run/publish compose command both run /usr/local/bin/python;
79
+ # python3 is a SEPARATE symlink, signing it leaves the executed binary
80
+ # debug-signed). Mainnet adds --production (CAS/DCAP); testnet omits it (non-CAS
81
+ # self-sign). On testnet builds this line is a no-op comment.
82
+ __SCONE_SIGN__
83
+
84
+ # Record the SIGNED MRENCLAVE so publish (run.js) can assert the runtime enclave
85
+ # measurement matches what was signed before registering the CAS session. Only
86
+ # produced for --production (mainnet); on testnet the file is absent and the
87
+ # check is skipped. Capture to a file first (piping scone-signer into head/grep
88
+ # kills it with SIGPIPE / exit 141 under buildkit's pipefail shell).
89
+ __SIGNED_MRENCLAVE__
74
90
 
75
91
  RUN rm -rf /enclave-key.pem
76
92
 
package/pynithy/build.mjs CHANGED
@@ -26,14 +26,30 @@ const writeEnv = (key, value) => {
26
26
  fs.writeFileSync(envFile, envContent, 'utf8');
27
27
  };
28
28
  // runner name: [smart contract address, image registry address, rpc url, chainid]
29
+ // [templateName]: [smart_contract_address, image_registry_address, rpc_url, chain_id]
30
+ // Kept in sync with etny-{pynithy,nodenithy}/v3/networks.yaml (the authoritative
31
+ // on-chain constants). Covers all supported networks for both dApp types.
29
32
  export const ECRunner = {
30
- 'etny-pynithy-testnet': ['0x02882F03097fE8cD31afbdFbB5D72a498B41112c', '0x15D73a742529C3fb11f3FA32EF7f0CC3870ACA31', 'https://core.bloxberg.org', 8995],
31
- 'etny-nodenithy-testnet': ['0x02882F03097fE8cD31afbdFbB5D72a498B41112c', '0x15D73a742529C3fb11f3FA32EF7f0CC3870ACA31', 'https://core.bloxberg.org', 8995],
32
- 'etny-pynithy': ['0x549A6E06BB2084100148D50F51CF77a3436C3Ae7', '0x15D73a742529C3fb11f3FA32EF7f0CC3870ACA31', 'https://core.bloxberg.org', 8995],
33
- 'etny-nodenithy': ['0x549A6E06BB2084100148D50F51CF77a3436C3Ae7', '0x15D73a742529C3fb11f3FA32EF7f0CC3870ACA31', 'https://core.bloxberg.org', 8995],
34
- 'ecld-nodenithy-testnet': ['0x4274b1188ABCfa0d864aFdeD86bF9545B020dCDf', '0xF7F4eEb3d9a64387F4AcEb6d521b948E6E2fB049', 'https://rpc-mumbai.matic.today', 80001],
35
- 'ecld-pynithy': ['0x439945BE73fD86fcC172179021991E96Beff3Cc4', '0x689f3806874d3c8A973f419a4eB24e6fBA7E830F', 'https://polygon-rpc.com', 137],
36
- 'ecld-nodenithy': ['0x439945BE73fD86fcC172179021991E96Beff3Cc4', '0x689f3806874d3c8A973f419a4eB24e6fBA7E830F', 'https://polygon-rpc.com', 137]
33
+ // --- bloxberg ---
34
+ 'etny-pynithy-testnet': ['0x02882F03097fE8cD31afbdFbB5D72a498B41112c', '0x15D73a742529C3fb11f3FA32EF7f0CC3870ACA31', 'https://bloxberg.ethernity.cloud', 8995],
35
+ 'etny-nodenithy-testnet': ['0x02882F03097fE8cD31afbdFbB5D72a498B41112c', '0x15D73a742529C3fb11f3FA32EF7f0CC3870ACA31', 'https://bloxberg.ethernity.cloud', 8995],
36
+ 'etny-pynithy': ['0x549A6E06BB2084100148D50F51CF77a3436C3Ae7', '0x15D73a742529C3fb11f3FA32EF7f0CC3870ACA31', 'https://bloxberg.ethernity.cloud', 8995],
37
+ 'etny-nodenithy': ['0x549A6E06BB2084100148D50F51CF77a3436C3Ae7', '0x15D73a742529C3fb11f3FA32EF7f0CC3870ACA31', 'https://bloxberg.ethernity.cloud', 8995],
38
+ // --- polygon mainnet ---
39
+ 'ecld-pynithy': ['0x439945BE73fD86fcC172179021991E96Beff3Cc4', '0x689f3806874d3c8A973f419a4eB24e6fBA7E830F', 'https://polygon-bor-rpc.publicnode.com', 137],
40
+ 'ecld-nodenithy': ['0x439945BE73fD86fcC172179021991E96Beff3Cc4', '0x689f3806874d3c8A973f419a4eB24e6fBA7E830F', 'https://polygon-bor-rpc.publicnode.com', 137],
41
+ // --- polygon amoy testnet (replaces deprecated mumbai) ---
42
+ 'ecld-pynithy-amoy': ['0x1579b37C5a69ae02dDd23263A2b1318DE66a27C3', '0xeFA33c3976f31961285Ae4f5D10188616C912728', 'https://rpc-amoy.polygon.technology', 80002],
43
+ 'ecld-nodenithy-amoy': ['0x1579b37C5a69ae02dDd23263A2b1318DE66a27C3', '0xeFA33c3976f31961285Ae4f5D10188616C912728', 'https://rpc-amoy.polygon.technology', 80002],
44
+ // --- iotex testnet ---
45
+ 'ecld-pynithy-iotex-testnet': ['0xD56385A97413Ed80E28B1b54A193b98F2C49c975', '0xa7467A6391816be9367a1cC52E0ef0c15FfE3cCC', 'https://babel-api.testnet.iotex.io', 4690],
46
+ 'ecld-nodenithy-iotex-testnet': ['0xD56385A97413Ed80E28B1b54A193b98F2C49c975', '0xa7467A6391816be9367a1cC52E0ef0c15FfE3cCC', 'https://babel-api.testnet.iotex.io', 4690],
47
+ // --- ethereum sepolia ---
48
+ 'ecld-pynithy-ethereum-sepolia': ['0x29D3eC870565B6A1510232bd950A8Bc8336f0EB2', '0x55e0ad455Be85162b71a790f00Fc305680E3CE53', 'https://ethereum-sepolia-rpc.publicnode.com', 11155111],
49
+ 'ecld-nodenithy-ethereum-sepolia': ['0x29D3eC870565B6A1510232bd950A8Bc8336f0EB2', '0x55e0ad455Be85162b71a790f00Fc305680E3CE53', 'https://ethereum-sepolia-rpc.publicnode.com', 11155111],
50
+ // --- litvm liteforge testnet (shares sepolia contracts; distinct chain/RPC) ---
51
+ 'ecld-pynithy-litvm-testnet': ['0x29D3eC870565B6A1510232bd950A8Bc8336f0EB2', '0x55e0ad455Be85162b71a790f00Fc305680E3CE53', 'https://liteforge.rpc.caldera.xyz/infra-partner-http', 4441],
52
+ 'ecld-nodenithy-litvm-testnet': ['0x29D3eC870565B6A1510232bd950A8Bc8336f0EB2', '0x55e0ad455Be85162b71a790f00Fc305680E3CE53', 'https://liteforge.rpc.caldera.xyz/infra-partner-http', 4441]
37
53
  };
38
54
 
39
55
  const runCommand = (command, canPass = false) => {
@@ -106,17 +122,43 @@ console.log('Building etny-securelock');
106
122
  process.chdir('securelock');
107
123
  // runCommand(`cat Dockerfile.tmpl | sed s/"__ENCLAVE_NAME_SECURELOCK__"/"${ENCLAVE_NAME_SECURELOCK}"/g > Dockerfile`);
108
124
  const dockerfileSecureTemplate = fs.readFileSync('Dockerfile.tmpl', 'utf8');
109
- const dockerfileSecureContent = dockerfileSecureTemplate.replace(/__ENCLAVE_NAME_SECURELOCK__/g, ENCLAVE_NAME_SECURELOCK).replace(/__BUCKET_NAME__/g, templateName + "-v3").replace(/__SMART_CONTRACT_ADDRESS__/g, ECRunner[templateName][0]).replace(/__IMAGE_REGISTRY_ADDRESS__/g, ECRunner[templateName][1]).replace(/__RPC_URL__/g, ECRunner[templateName][2]).replace(/__CHAIN_ID__/g, ECRunner[templateName][3]).replace(/__TRUSTED_ZONE_IMAGE__/g, templateName);
110
-
111
- fs.writeFileSync('Dockerfile', dockerfileSecureContent);
125
+ let dockerfileSecureContent = dockerfileSecureTemplate.replace(/__ENCLAVE_NAME_SECURELOCK__/g, ENCLAVE_NAME_SECURELOCK).replace(/__BUCKET_NAME__/g, templateName + "-v3").replace(/__SMART_CONTRACT_ADDRESS__/g, ECRunner[templateName][0]).replace(/__IMAGE_REGISTRY_ADDRESS__/g, ECRunner[templateName][1]).replace(/__RPC_URL__/g, ECRunner[templateName][2]).replace(/__CHAIN_ID__/g, ECRunner[templateName][3]).replace(/__TRUSTED_ZONE_IMAGE__/g, templateName);
126
+
127
+ // Amount of enclave heap to allocate (SCONE_HEAP); overridable, in sync with the
128
+ // run/docker-compose securelock service.
129
+ const MEMORY_TO_ALLOCATE = (process.env.ECLD_MEMORY_TO_ALLOCATE || '1024M').trim();
130
+
131
+ // CRITICAL (mainnet DCAP): sign /usr/local/bin/python -- the binary the enclave
132
+ // actually EXECUTES (ENTRYPOINT + run/publish compose command both run
133
+ // /usr/local/bin/python). /usr/local/bin/python3 is a SEPARATE symlink; signing
134
+ // it leaves the executed binary DEBUG-signed, so SCONE recomputes MRENCLAVE at
135
+ // load and re-signs as debug -> CAS rejects the DCAP quote on mainnet.
136
+ // The enclave-creation params MUST match the runtime env exactly.
137
+ const signFlags =
138
+ `--key=/enclave-key.pem --env --heap=${MEMORY_TO_ALLOCATE} ` +
139
+ `--stack=4M --dlopen=1 --extensions=/lib/libbinary-fs.so`;
140
+
141
+ const signedMrenclaveStep =
142
+ 'RUN scone-signer info /usr/local/bin/python > /tmp/siginfo.txt 2>&1; \\\n' +
143
+ ' grep -iE "MRENCLAVE:" /tmp/siginfo.txt | sed -n \'1p\' \\\n' +
144
+ ' | sed -E \'s/.*MRENCLAVE:[[:space:]]*//I\' | tr -d \'[:space:]\' > /signed_mrenclave.txt && \\\n' +
145
+ ' echo "SIGNED_MRENCLAVE=$(cat /signed_mrenclave.txt)"';
112
146
 
113
147
  let imagesTag = process.env.BLOCKCHAIN_NETWORK.toLowerCase();
114
148
 
115
149
  if (isMainnet) {
116
- fs.writeFileSync('Dockerfile', dockerfileSecureContent.replace('# RUN scone-signer sign', 'RUN scone-signer sign'));
117
- imagesTag = process.env.BLOCKCHAIN_NETWORK.split("_")[0].toLowerCase()
150
+ dockerfileSecureContent = dockerfileSecureContent
151
+ .replace('__SCONE_SIGN__', `RUN scone-signer sign ${signFlags} --production /usr/local/bin/python`)
152
+ .replace('__SIGNED_MRENCLAVE__', signedMrenclaveStep);
153
+ imagesTag = process.env.BLOCKCHAIN_NETWORK.split("_")[0].toLowerCase();
154
+ } else {
155
+ dockerfileSecureContent = dockerfileSecureContent
156
+ .replace('__SCONE_SIGN__', '# testnet: non-CAS self-sign (no --production sign at build time)')
157
+ .replace('__SIGNED_MRENCLAVE__', '# testnet: no signed MRENCLAVE (self-signed from MR_ENCLAVE at runtime)');
118
158
  }
119
159
 
160
+ fs.writeFileSync('Dockerfile', dockerfileSecureContent);
161
+
120
162
 
121
163
 
122
164