@hsuite/smart-engines-cli 1.4.2 → 1.5.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.
|
@@ -1,61 +1,54 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Runtime-env forwarding for `hsuite deploy` / `hsuite redeploy
|
|
2
|
+
* Runtime-env forwarding for `hsuite deploy` / `hsuite redeploy`.
|
|
3
3
|
*
|
|
4
|
-
* THE
|
|
5
|
-
*
|
|
6
|
-
* The CLI reads the developer's `.env.local` (`--env`)
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* smart-app's `BaaSAuthService` found no `XRPL_SEED` and silently booted
|
|
11
|
-
* OPEN / in-memory mode (`/baas/status` → `{"mode":"memory","appId":null}`).
|
|
4
|
+
* THE MODEL
|
|
5
|
+
* ---------
|
|
6
|
+
* The CLI reads the developer's `.env.local` (`--env`) and forwards its runtime
|
|
7
|
+
* vars into the deployed customer-env — the per-app k8s Secret the deployer
|
|
8
|
+
* mirrors, PQC-encrypted (kyber-aes-v1) at rest. So the deployed app runs with
|
|
9
|
+
* the SAME config the developer runs locally, with no allowlist to maintain.
|
|
12
10
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* the developer's OWN XRPL wallet (`XRPL_SEED` in `.env.local`, whose address
|
|
19
|
-
* holds the subscription NFT) — there is NO separate app / protocol identity.
|
|
11
|
+
* FORWARD-ALL, MINUS A SMALL DENYLIST
|
|
12
|
+
* -----------------------------------
|
|
13
|
+
* EVERY key in `.env.local` is forwarded EXCEPT {@link NON_FORWARDED_KEYS} — so
|
|
14
|
+
* ANY variable the app reads (including ones this CLI has never heard of) "just
|
|
15
|
+
* works" in the deployed container. The denylist withholds only:
|
|
20
16
|
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
17
|
+
* 1. The PLATFORM-RESOLVED connection URLs (`SMART_HOST_URL` / `VALIDATOR_URL`
|
|
18
|
+
* / `GATEWAY_URL`). Locally these point at the public testnet gateway (from
|
|
19
|
+
* `hsuite init`); IN-CLUSTER the deployer's cluster-env injects the INTERNAL
|
|
20
|
+
* service URL plus a TSS-minted `APP_TOKEN`. Forwarding the developer's
|
|
21
|
+
* external URL would OVERRIDE the internal one, and the pod would try to
|
|
22
|
+
* reach the public gateway from inside the cluster (unreachable) → the app
|
|
23
|
+
* silently boots open/in-memory mode. So these are cluster-resolved, never
|
|
24
|
+
* forwarded — the SDK consumes them via `BaasClient.fromEnv`.
|
|
25
|
+
* 2. The LOCAL-ONLY safety toggles (`DEV_MODE` / `ALLOW_INSECURE`) — a stale
|
|
26
|
+
* `true` in a developer's `.env.local` must never silently propagate into a
|
|
27
|
+
* live deployment. A deploy that genuinely needs one sets it explicitly via
|
|
28
|
+
* `manifest.backend.env`.
|
|
29
29
|
*
|
|
30
|
-
* The
|
|
31
|
-
*
|
|
30
|
+
* The developer's identity secret (`XRPL_SEED`, whose wallet holds the
|
|
31
|
+
* subscription NFT) IS forwarded — the app uses it for owner-signed chain ops;
|
|
32
|
+
* the in-cluster BaaS *session* itself comes from the deployer's `APP_TOKEN`, not
|
|
33
|
+
* from a challenge.
|
|
32
34
|
*/
|
|
33
35
|
import type { EnvMap } from './env';
|
|
34
36
|
/**
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* with that schema: a key the smart-app reads at runtime but that is absent here
|
|
40
|
-
* would not reach the container (the #1564 class of bug), and a key here that the
|
|
41
|
-
* smart-app never reads is harmless noise in the Secret.
|
|
42
|
-
*
|
|
43
|
-
* Deliberately EXCLUDES purely deploy-time / CLI-only vars that the deployed
|
|
44
|
-
* container never consumes:
|
|
45
|
-
* - `SUBSCRIPTION_NFT_SERIAL` — a `hsuite subscribe` book-keeping value.
|
|
46
|
-
* - `VALIDATOR_API_KEY` / `SMART_HOST_API_KEY` — the in-cluster app authenticates
|
|
47
|
-
* as its wallet (Web3 challenge-response); a raw API key is a deploy-time /
|
|
48
|
-
* local-only convenience, not a container runtime credential, and the deployer
|
|
49
|
-
* injects the mediated `SMART_HOST_URL` / `APP_TOKEN` via the cluster-env
|
|
50
|
-
* Secret. (Forwarding a raw validator key would also widen the tenant's
|
|
51
|
-
* credential surface for no runtime benefit.)
|
|
37
|
+
* Keys withheld from customer-env forwarding. See the file header for the two
|
|
38
|
+
* classes (platform-resolved connection URLs + local-only safety toggles) and
|
|
39
|
+
* WHY forwarding them breaks or endangers a deployment. Everything else in
|
|
40
|
+
* `.env.local` is forwarded verbatim.
|
|
52
41
|
*/
|
|
53
|
-
export declare const
|
|
42
|
+
export declare const NON_FORWARDED_KEYS: ReadonlySet<string>;
|
|
54
43
|
/**
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
44
|
+
* Keys whose presence lets the deployed app authenticate as the developer's
|
|
45
|
+
* wallet for owner-signed chain operations. `XRPL_SEED` is forwarded (it is NOT
|
|
46
|
+
* on the denylist); this guard fails a deploy loud rather than silently shipping
|
|
47
|
+
* an app with no owner key, unless `allowOpenMode` opts into a zero-cred fork.
|
|
48
|
+
*
|
|
49
|
+
* (The in-cluster BaaS *session* comes from the deployer's `APP_TOKEN`, so a
|
|
50
|
+
* deployed app reaches cluster mode regardless; this guard is about the owner
|
|
51
|
+
* signing key the developer almost always intends to ship.)
|
|
59
52
|
*/
|
|
60
53
|
export declare const CLUSTER_MODE_REQUIRED_KEYS: readonly string[];
|
|
61
54
|
export interface ResolveRuntimeEnvInput {
|
|
@@ -64,19 +57,13 @@ export interface ResolveRuntimeEnvInput {
|
|
|
64
57
|
/** `manifest.backend.env` — explicit, committed, NON-secret overrides. */
|
|
65
58
|
manifestEnv?: Record<string, string>;
|
|
66
59
|
/**
|
|
67
|
-
* Opt-in escape hatch for an intentional
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* When true, the developer's `XRPL_SEED` is DELIBERATELY WITHHELD from the
|
|
71
|
-
* forwarded container env (so the deployed app boots open/in-memory mode), and
|
|
72
|
-
* the fail-loud {@link OpenModeDeployError} is suppressed. The seed still exists
|
|
73
|
-
* in `.env.local` for the local deploy-time work (auth + attestation signing) —
|
|
74
|
-
* it is just not injected into the running container.
|
|
60
|
+
* Opt-in escape hatch for an intentional zero-cred deploy — e.g. a fork demo
|
|
61
|
+
* the developer wants to run without shipping their `XRPL_SEED`.
|
|
75
62
|
*
|
|
76
|
-
* When
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
63
|
+
* When true, `XRPL_SEED` is DELIBERATELY WITHHELD from the forwarded container
|
|
64
|
+
* env and the fail-loud {@link OpenModeDeployError} is suppressed. The seed
|
|
65
|
+
* still exists in `.env.local` for the local deploy-time work (auth +
|
|
66
|
+
* attestation signing) — it is just not injected into the running container.
|
|
80
67
|
*/
|
|
81
68
|
allowOpenMode?: boolean;
|
|
82
69
|
/**
|
|
@@ -87,12 +74,11 @@ export interface ResolveRuntimeEnvInput {
|
|
|
87
74
|
warn?: (message: string) => void;
|
|
88
75
|
}
|
|
89
76
|
/**
|
|
90
|
-
* A
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
* on the message.
|
|
77
|
+
* A credential-less deploy was blocked. Thrown by {@link resolveRuntimeEnv} when
|
|
78
|
+
* the resolved container env carries no `XRPL_SEED` and `allowOpenMode` is not
|
|
79
|
+
* set — so a deploy never SILENTLY ships an app with no owner signing key. The
|
|
80
|
+
* remedy (populate `.env.local` via `hsuite init` + `hsuite subscribe`, or opt
|
|
81
|
+
* in explicitly) is on the message.
|
|
96
82
|
*/
|
|
97
83
|
export declare class OpenModeDeployError extends Error {
|
|
98
84
|
constructor(missing: readonly string[]);
|
|
@@ -100,24 +86,21 @@ export declare class OpenModeDeployError extends Error {
|
|
|
100
86
|
/**
|
|
101
87
|
* Resolve the runtime env the deployed container should receive.
|
|
102
88
|
*
|
|
103
|
-
* Merge + precedence
|
|
104
|
-
* 1.
|
|
105
|
-
*
|
|
89
|
+
* Merge + precedence:
|
|
90
|
+
* 1. Forward EVERY var from `.env.local` EXCEPT {@link NON_FORWARDED_KEYS}
|
|
91
|
+
* (platform-resolved URLs + local-only toggles). Empty values are dropped.
|
|
106
92
|
* 2. Overlay `manifest.backend.env` LAST, so an explicitly-set manifest key
|
|
107
93
|
* WINS. The manifest is the committed, explicit override surface for
|
|
108
|
-
* NON-secret config (ports, feature flags
|
|
109
|
-
*
|
|
110
|
-
* hand-written into a committed manifest.
|
|
94
|
+
* NON-secret config (ports, feature flags); secrets flow from `.env.local`
|
|
95
|
+
* automatically and never need to live in a committed manifest.
|
|
111
96
|
*
|
|
112
97
|
* Rationale for manifest-wins: a value a developer deliberately typed into the
|
|
113
98
|
* manifest is an intentional per-deploy override and must not be silently shadowed
|
|
114
|
-
* by whatever happens to sit in their local `.env.local`.
|
|
115
|
-
* are NOT expected in the manifest — they flow from `.env.local` — so the two
|
|
116
|
-
* surfaces do not normally collide on secret keys.
|
|
99
|
+
* by whatever happens to sit in their local `.env.local`.
|
|
117
100
|
*
|
|
118
|
-
* Fail-loud
|
|
119
|
-
*
|
|
120
|
-
*
|
|
101
|
+
* Fail-loud: if the merged result has no `XRPL_SEED` and `allowOpenMode` is not
|
|
102
|
+
* set, throws {@link OpenModeDeployError} rather than shipping a silent
|
|
103
|
+
* credential-less app.
|
|
121
104
|
*
|
|
122
105
|
* @throws {OpenModeDeployError} when the resolved env is credential-less and
|
|
123
106
|
* `allowOpenMode` is not set.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-env.d.ts","sourceRoot":"","sources":["../../src/_lib/runtime-env.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"runtime-env.d.ts","sourceRoot":"","sources":["../../src/_lib/runtime-env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAEpC;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,MAAM,CASjD,CAAC;AAEH;;;;;;;;;GASG;AACH,eAAO,MAAM,0BAA0B,EAAE,SAAS,MAAM,EAAkB,CAAC;AAE3E,MAAM,WAAW,sBAAsB;IACrC,uEAAuE;IACvE,GAAG,EAAE,MAAM,CAAC;IACZ,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;OAIG;IACH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC;AAWD;;;;;;GAMG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,SAAS,MAAM,EAAE;CAWvC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,sBAAsB,GAC5B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA6CxB"}
|
package/dist/_lib/runtime-env.js
CHANGED
|
@@ -1,76 +1,32 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.OpenModeDeployError = exports.CLUSTER_MODE_REQUIRED_KEYS = exports.
|
|
3
|
+
exports.OpenModeDeployError = exports.CLUSTER_MODE_REQUIRED_KEYS = exports.NON_FORWARDED_KEYS = void 0;
|
|
4
4
|
exports.resolveRuntimeEnv = resolveRuntimeEnv;
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* with that schema: a key the smart-app reads at runtime but that is absent here
|
|
11
|
-
* would not reach the container (the #1564 class of bug), and a key here that the
|
|
12
|
-
* smart-app never reads is harmless noise in the Secret.
|
|
13
|
-
*
|
|
14
|
-
* Deliberately EXCLUDES purely deploy-time / CLI-only vars that the deployed
|
|
15
|
-
* container never consumes:
|
|
16
|
-
* - `SUBSCRIPTION_NFT_SERIAL` — a `hsuite subscribe` book-keeping value.
|
|
17
|
-
* - `VALIDATOR_API_KEY` / `SMART_HOST_API_KEY` — the in-cluster app authenticates
|
|
18
|
-
* as its wallet (Web3 challenge-response); a raw API key is a deploy-time /
|
|
19
|
-
* local-only convenience, not a container runtime credential, and the deployer
|
|
20
|
-
* injects the mediated `SMART_HOST_URL` / `APP_TOKEN` via the cluster-env
|
|
21
|
-
* Secret. (Forwarding a raw validator key would also widen the tenant's
|
|
22
|
-
* credential surface for no runtime benefit.)
|
|
6
|
+
* Keys withheld from customer-env forwarding. See the file header for the two
|
|
7
|
+
* classes (platform-resolved connection URLs + local-only safety toggles) and
|
|
8
|
+
* WHY forwarding them breaks or endangers a deployment. Everything else in
|
|
9
|
+
* `.env.local` is forwarded verbatim.
|
|
23
10
|
*/
|
|
24
|
-
exports.
|
|
25
|
-
//
|
|
26
|
-
'
|
|
27
|
-
'PORT',
|
|
28
|
-
'APP_ID',
|
|
29
|
-
'APP_NAME',
|
|
30
|
-
'APP_DESCRIPTION',
|
|
31
|
-
// CORS
|
|
32
|
-
'CORS_ORIGINS',
|
|
33
|
-
// XRPL — the developer's own wallet identity (holds the subscription NFT).
|
|
34
|
-
'XRPL_NETWORK',
|
|
35
|
-
'XRPL_ADDRESS',
|
|
36
|
-
'XRPL_SEED',
|
|
37
|
-
'XRPL_PUBLIC_KEY',
|
|
38
|
-
// Subscription binding
|
|
39
|
-
'SUBSCRIPTION_APP_ID',
|
|
40
|
-
'DEPLOYED_APP_ID',
|
|
41
|
-
// Cluster connection (the deployer also injects mediated in-cluster URLs via
|
|
42
|
-
// the cluster-env Secret; a developer override still forwards here).
|
|
43
|
-
'VALIDATOR_URL',
|
|
11
|
+
exports.NON_FORWARDED_KEYS = new Set([
|
|
12
|
+
// Platform-resolved connection URLs — the deployer injects the INTERNAL ones
|
|
13
|
+
// (+ APP_TOKEN) via cluster-env; the developer's external values must not win.
|
|
44
14
|
'SMART_HOST_URL',
|
|
45
|
-
|
|
46
|
-
'
|
|
47
|
-
|
|
48
|
-
'
|
|
49
|
-
'
|
|
50
|
-
|
|
51
|
-
'GEMINI_API_KEY',
|
|
52
|
-
'AI_BASE_URL',
|
|
53
|
-
'AI_API_KEY',
|
|
54
|
-
'AI_MAX_TOKENS',
|
|
55
|
-
'DISCORD_WEBHOOK_URL',
|
|
56
|
-
'WEATHER_PAYOUT_ADDRESS',
|
|
57
|
-
// Misc runtime
|
|
58
|
-
'REQUEST_TIMEOUT',
|
|
59
|
-
'DEBUG',
|
|
60
|
-
// Subscription behaviour
|
|
61
|
-
'AUTO_SUBSCRIBE',
|
|
62
|
-
'SUBSCRIPTION_TIER',
|
|
63
|
-
// NOTE: `DEV_MODE` / `ALLOW_INSECURE` are deliberately NOT forwarded — they are
|
|
64
|
-
// local-dev safety toggles, and a stale `DEV_MODE=true` / `ALLOW_INSECURE=true`
|
|
65
|
-
// sitting in a developer's `.env.local` must not silently propagate into a live
|
|
66
|
-
// deployment. A deploy that genuinely needs one can set it explicitly (and
|
|
67
|
-
// intentionally) via `manifest.backend.env`.
|
|
68
|
-
];
|
|
15
|
+
'VALIDATOR_URL',
|
|
16
|
+
'GATEWAY_URL',
|
|
17
|
+
// Local-only safety toggles — never propagate into a live deploy.
|
|
18
|
+
'DEV_MODE',
|
|
19
|
+
'ALLOW_INSECURE',
|
|
20
|
+
]);
|
|
69
21
|
/**
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
22
|
+
* Keys whose presence lets the deployed app authenticate as the developer's
|
|
23
|
+
* wallet for owner-signed chain operations. `XRPL_SEED` is forwarded (it is NOT
|
|
24
|
+
* on the denylist); this guard fails a deploy loud rather than silently shipping
|
|
25
|
+
* an app with no owner key, unless `allowOpenMode` opts into a zero-cred fork.
|
|
26
|
+
*
|
|
27
|
+
* (The in-cluster BaaS *session* comes from the deployer's `APP_TOKEN`, so a
|
|
28
|
+
* deployed app reaches cluster mode regardless; this guard is about the owner
|
|
29
|
+
* signing key the developer almost always intends to ship.)
|
|
74
30
|
*/
|
|
75
31
|
exports.CLUSTER_MODE_REQUIRED_KEYS = ['XRPL_SEED'];
|
|
76
32
|
/**
|
|
@@ -82,20 +38,18 @@ function looksLikeSecretKey(key) {
|
|
|
82
38
|
return /(_SEED|_PRIVATE_KEY|_API_KEY|_SECRET|_TOKEN|_PASSWORD|_MNEMONIC)$/.test(key);
|
|
83
39
|
}
|
|
84
40
|
/**
|
|
85
|
-
* A
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
* on the message.
|
|
41
|
+
* A credential-less deploy was blocked. Thrown by {@link resolveRuntimeEnv} when
|
|
42
|
+
* the resolved container env carries no `XRPL_SEED` and `allowOpenMode` is not
|
|
43
|
+
* set — so a deploy never SILENTLY ships an app with no owner signing key. The
|
|
44
|
+
* remedy (populate `.env.local` via `hsuite init` + `hsuite subscribe`, or opt
|
|
45
|
+
* in explicitly) is on the message.
|
|
91
46
|
*/
|
|
92
47
|
class OpenModeDeployError extends Error {
|
|
93
48
|
constructor(missing) {
|
|
94
|
-
super(`Refusing to deploy
|
|
95
|
-
`
|
|
96
|
-
`
|
|
97
|
-
`
|
|
98
|
-
`and BaaS routes 503. Run \`hsuite init\` + \`hsuite subscribe\` so ` +
|
|
49
|
+
super(`Refusing to deploy a credential-less app: the resolved container env is ` +
|
|
50
|
+
`missing ${missing.join(', ')}. The deployed smart-app signs owner ops ` +
|
|
51
|
+
`with YOUR XRPL wallet (the XRPL_SEED in --env), which holds the ` +
|
|
52
|
+
`subscription NFT. Run \`hsuite init\` + \`hsuite subscribe\` so ` +
|
|
99
53
|
`.env.local carries the creds, or pass --allow-open-mode for an ` +
|
|
100
54
|
`intentional zero-cred fork deploy.`);
|
|
101
55
|
this.name = 'OpenModeDeployError';
|
|
@@ -105,24 +59,21 @@ exports.OpenModeDeployError = OpenModeDeployError;
|
|
|
105
59
|
/**
|
|
106
60
|
* Resolve the runtime env the deployed container should receive.
|
|
107
61
|
*
|
|
108
|
-
* Merge + precedence
|
|
109
|
-
* 1.
|
|
110
|
-
*
|
|
62
|
+
* Merge + precedence:
|
|
63
|
+
* 1. Forward EVERY var from `.env.local` EXCEPT {@link NON_FORWARDED_KEYS}
|
|
64
|
+
* (platform-resolved URLs + local-only toggles). Empty values are dropped.
|
|
111
65
|
* 2. Overlay `manifest.backend.env` LAST, so an explicitly-set manifest key
|
|
112
66
|
* WINS. The manifest is the committed, explicit override surface for
|
|
113
|
-
* NON-secret config (ports, feature flags
|
|
114
|
-
*
|
|
115
|
-
* hand-written into a committed manifest.
|
|
67
|
+
* NON-secret config (ports, feature flags); secrets flow from `.env.local`
|
|
68
|
+
* automatically and never need to live in a committed manifest.
|
|
116
69
|
*
|
|
117
70
|
* Rationale for manifest-wins: a value a developer deliberately typed into the
|
|
118
71
|
* manifest is an intentional per-deploy override and must not be silently shadowed
|
|
119
|
-
* by whatever happens to sit in their local `.env.local`.
|
|
120
|
-
* are NOT expected in the manifest — they flow from `.env.local` — so the two
|
|
121
|
-
* surfaces do not normally collide on secret keys.
|
|
72
|
+
* by whatever happens to sit in their local `.env.local`.
|
|
122
73
|
*
|
|
123
|
-
* Fail-loud
|
|
124
|
-
*
|
|
125
|
-
*
|
|
74
|
+
* Fail-loud: if the merged result has no `XRPL_SEED` and `allowOpenMode` is not
|
|
75
|
+
* set, throws {@link OpenModeDeployError} rather than shipping a silent
|
|
76
|
+
* credential-less app.
|
|
126
77
|
*
|
|
127
78
|
* @throws {OpenModeDeployError} when the resolved env is credential-less and
|
|
128
79
|
* `allowOpenMode` is not set.
|
|
@@ -130,26 +81,23 @@ exports.OpenModeDeployError = OpenModeDeployError;
|
|
|
130
81
|
function resolveRuntimeEnv(input) {
|
|
131
82
|
const { env, manifestEnv = {}, allowOpenMode = false, warn } = input;
|
|
132
83
|
const merged = {};
|
|
133
|
-
// 1.
|
|
134
|
-
//
|
|
135
|
-
//
|
|
136
|
-
//
|
|
137
|
-
const withhold = allowOpenMode
|
|
138
|
-
|
|
84
|
+
// 1. Forward every .env.local var except the denylist. Under an explicit
|
|
85
|
+
// open-mode deploy, the owner key (XRPL_SEED) is ALSO withheld so the
|
|
86
|
+
// deployed app ships zero-cred — the seed still exists locally for
|
|
87
|
+
// attestation, it is just not injected into the container.
|
|
88
|
+
const withhold = allowOpenMode
|
|
89
|
+
? new Set([...exports.NON_FORWARDED_KEYS, ...exports.CLUSTER_MODE_REQUIRED_KEYS])
|
|
90
|
+
: exports.NON_FORWARDED_KEYS;
|
|
91
|
+
for (const [key, val] of env) {
|
|
139
92
|
if (withhold.has(key))
|
|
140
93
|
continue;
|
|
141
|
-
const val = env.get(key);
|
|
142
94
|
if (val !== undefined && val !== '') {
|
|
143
95
|
merged[key] = val;
|
|
144
96
|
}
|
|
145
97
|
}
|
|
146
98
|
// 2. manifest.backend.env wins (explicit, committed, non-secret overrides).
|
|
147
|
-
//
|
|
148
|
-
//
|
|
149
|
-
// manifest-only key (e.g. a custom feature flag) passes through verbatim.
|
|
150
|
-
// The allowlist governs only the `.env.local` source (step 1). An empty
|
|
151
|
-
// manifest value is forwarded as-is (an explicit author choice), unlike an
|
|
152
|
-
// empty `.env.local` value which is dropped in step 1.
|
|
99
|
+
// An empty manifest value is forwarded as-is (an explicit author choice),
|
|
100
|
+
// unlike an empty `.env.local` value which is dropped in step 1.
|
|
153
101
|
for (const [key, val] of Object.entries(manifestEnv)) {
|
|
154
102
|
if (warn && looksLikeSecretKey(key)) {
|
|
155
103
|
warn(`manifest.backend.env sets a secret-shaped key "${key}" — the manifest is ` +
|
|
@@ -159,8 +107,7 @@ function resolveRuntimeEnv(input) {
|
|
|
159
107
|
}
|
|
160
108
|
merged[key] = val;
|
|
161
109
|
}
|
|
162
|
-
// 3. Fail loud on a credential-less
|
|
163
|
-
// subscribed app never SILENTLY ships open mode (the #1564 invisible bug).
|
|
110
|
+
// 3. Fail loud on a credential-less deploy unless opted in.
|
|
164
111
|
if (!allowOpenMode) {
|
|
165
112
|
const missing = exports.CLUSTER_MODE_REQUIRED_KEYS.filter((k) => merged[k] === undefined || merged[k] === '');
|
|
166
113
|
if (missing.length > 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-env.js","sourceRoot":"","sources":["../../src/_lib/runtime-env.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"runtime-env.js","sourceRoot":"","sources":["../../src/_lib/runtime-env.ts"],"names":[],"mappings":";;;AA4IA,8CA+CC;AAvJD;;;;;GAKG;AACU,QAAA,kBAAkB,GAAwB,IAAI,GAAG,CAAC;IAC7D,6EAA6E;IAC7E,+EAA+E;IAC/E,gBAAgB;IAChB,eAAe;IACf,aAAa;IACb,kEAAkE;IAClE,UAAU;IACV,gBAAgB;CACjB,CAAC,CAAC;AAEH;;;;;;;;;GASG;AACU,QAAA,0BAA0B,GAAsB,CAAC,WAAW,CAAC,CAAC;AAyB3E;;;;GAIG;AACH,SAAS,kBAAkB,CAAC,GAAW;IACrC,OAAO,mEAAmE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACvF,CAAC;AAED;;;;;;GAMG;AACH,MAAa,mBAAoB,SAAQ,KAAK;IAC5C,YAAY,OAA0B;QACpC,KAAK,CACH,0EAA0E;YACxE,WAAW,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,2CAA2C;YACxE,kEAAkE;YAClE,kEAAkE;YAClE,iEAAiE;YACjE,oCAAoC,CACvC,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAZD,kDAYC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,SAAgB,iBAAiB,CAC/B,KAA6B;IAE7B,MAAM,EAAE,GAAG,EAAE,WAAW,GAAG,EAAE,EAAE,aAAa,GAAG,KAAK,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;IAErE,MAAM,MAAM,GAA2B,EAAE,CAAC;IAE1C,yEAAyE;IACzE,yEAAyE;IACzE,sEAAsE;IACtE,8DAA8D;IAC9D,MAAM,QAAQ,GAAG,aAAa;QAC5B,CAAC,CAAC,IAAI,GAAG,CAAS,CAAC,GAAG,0BAAkB,EAAE,GAAG,kCAA0B,CAAC,CAAC;QACzE,CAAC,CAAC,0BAAkB,CAAC;IACvB,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC;QAC7B,IAAI,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAChC,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;YACpC,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;QACpB,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,6EAA6E;IAC7E,oEAAoE;IACpE,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;QACrD,IAAI,IAAI,IAAI,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC;YACpC,IAAI,CACF,kDAAkD,GAAG,sBAAsB;gBACzE,kEAAkE;gBAClE,kEAAkE;gBAClE,mCAAmC,CACtC,CAAC;QACJ,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IACpB,CAAC;IAED,4DAA4D;IAC5D,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,OAAO,GAAG,kCAA0B,CAAC,MAAM,CAC/C,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,CACnD,CAAC;QACF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,mBAAmB,CAAC,OAAO,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|