@catladder/cli 0.0.0-main-0d7b031b → 0.0.0-main-018e2dee
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/apps/cli/src/apps/cli/commands/project/doctor/checkLocalAccess.js +1 -0
- package/dist/apps/cli/src/apps/cli/commands/project/doctor/checkLocalAccess.js.map +1 -1
- package/dist/apps/cli/src/apps/cli/commands/project/setup/setupLocalAccess.d.ts +1 -1
- package/dist/apps/cli/src/apps/cli/commands/project/setup/setupLocalAccess.js +3 -1
- package/dist/apps/cli/src/apps/cli/commands/project/setup/setupLocalAccess.js.map +1 -1
- package/dist/apps/cli/src/localAccess/declared.d.ts +6 -0
- package/dist/apps/cli/src/localAccess/declared.js +15 -1
- package/dist/apps/cli/src/localAccess/declared.js.map +1 -1
- package/dist/apps/cli/src/localAccess/keyFiles.d.ts +4 -2
- package/dist/apps/cli/src/localAccess/keyFiles.js +12 -8
- package/dist/apps/cli/src/localAccess/keyFiles.js.map +1 -1
- package/dist/bundles/catenv/index.js +56 -10
- package/dist/bundles/cli/index.js +60 -11
- package/dist/bundles/skills/catladder-secrets/SKILL.md +11 -0
- package/dist/packages/pipeline/src/localAccess/index.d.ts +7 -0
- package/dist/packages/pipeline/src/localAccess/index.js +29 -1
- package/dist/packages/pipeline/src/localAccess/index.js.map +1 -1
- package/dist/packages/pipeline/src/types/config.d.ts +20 -2
- package/dist/skills/catladder-secrets/SKILL.md +11 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/apps/cli/commands/project/doctor/{checkLocalAccess.test.ts → __tests__/checkLocalAccess.test.ts} +19 -4
- package/src/apps/cli/commands/project/doctor/checkLocalAccess.ts +2 -0
- package/src/apps/cli/commands/project/setup/setupLocalAccess.ts +4 -1
- package/src/localAccess/__tests__/keyFiles.test.ts +59 -0
- package/src/localAccess/declared.ts +20 -1
- package/src/localAccess/keyFiles.ts +21 -9
|
@@ -21,6 +21,7 @@ const checkLocalAccess = async (report, config, contexts, inspector) => {
|
|
|
21
21
|
let declared;
|
|
22
22
|
try {
|
|
23
23
|
declared = (0, pipeline_1.getLocalAccessGcpRoles)(config, context.env);
|
|
24
|
+
(0, pipeline_1.getLocalAccessGcpCredentialsEnvVars)(config, context.name);
|
|
24
25
|
}
|
|
25
26
|
catch (e) {
|
|
26
27
|
return { label, invalid: e.message };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkLocalAccess.js","sourceRoot":"","sources":["../../../../../../../../../src/apps/cli/commands/project/doctor/checkLocalAccess.ts"],"names":[],"mappings":";;;AACA,
|
|
1
|
+
{"version":3,"file":"checkLocalAccess.js","sourceRoot":"","sources":["../../../../../../../../../src/apps/cli/commands/project/doctor/checkLocalAccess.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ComponentContext } from "../../../../../../../../packages/pipeline/src/index.js";
|
|
2
2
|
import type { IO } from "../../../../../core/types";
|
|
3
3
|
/**
|
|
4
|
-
* provisions the
|
|
4
|
+
* provisions the local access (`localAccess` in catladder.ts)
|
|
5
5
|
* of a google cloud run component/env: a dedicated service account with
|
|
6
6
|
* exactly the declared bindings and its key in the secret store. Also
|
|
7
7
|
* removes what is no longer declared.
|
|
@@ -5,7 +5,7 @@ const pipeline_1 = require("../../../../../../../../packages/pipeline/src/index.
|
|
|
5
5
|
const getProjectConfig_1 = require("../../../../../config/getProjectConfig");
|
|
6
6
|
const localAccess_1 = require("../../../../../gcloud/localAccess");
|
|
7
7
|
/**
|
|
8
|
-
* provisions the
|
|
8
|
+
* provisions the local access (`localAccess` in catladder.ts)
|
|
9
9
|
* of a google cloud run component/env: a dedicated service account with
|
|
10
10
|
* exactly the declared bindings and its key in the secret store. Also
|
|
11
11
|
* removes what is no longer declared.
|
|
@@ -17,6 +17,8 @@ const setupLocalAccess = async (instance, context) => {
|
|
|
17
17
|
return;
|
|
18
18
|
const projectConfig = await (0, getProjectConfig_1.getProjectConfig)();
|
|
19
19
|
const roles = (0, pipeline_1.getLocalAccessGcpRoles)(projectConfig, context.env);
|
|
20
|
+
// validates `credentialsEnvVar` (catenv silently skips invalid ones)
|
|
21
|
+
(0, pipeline_1.getLocalAccessGcpCredentialsEnvVars)(projectConfig, context.name);
|
|
20
22
|
if (roles.length > 0 && (0, pipeline_1.getVaultConfig)(projectConfig).type === "gitlab") {
|
|
21
23
|
// the gitlab vault stores secrets as CI variables available to every
|
|
22
24
|
// job on every branch: the key would leak to anyone who can push
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setupLocalAccess.js","sourceRoot":"","sources":["../../../../../../../../../src/apps/cli/commands/project/setup/setupLocalAccess.ts"],"names":[],"mappings":";;;AACA,
|
|
1
|
+
{"version":3,"file":"setupLocalAccess.js","sourceRoot":"","sources":["../../../../../../../../../src/apps/cli/commands/project/setup/setupLocalAccess.ts"],"names":[],"mappings":";;;AACA,kDAK6B;AAC7B,6EAA0E;AAE1E,mEAAkF;AAElF;;;;;GAKG;AACI,MAAM,gBAAgB,GAAG,KAAK,EACnC,QAAY,EACZ,OAAyB,EACzB,EAAE;;IACF,MAAM,MAAM,GAAG,MAAA,OAAO,CAAC,MAAM,0CAAE,MAAM,CAAC;IACtC,IAAI,CAAC,IAAA,yBAAc,EAAC,MAAM,EAAE,iBAAiB,CAAC;QAAE,OAAO;IACvD,MAAM,aAAa,GAAG,MAAM,IAAA,mCAAgB,GAAE,CAAC;IAC/C,MAAM,KAAK,GAAG,IAAA,iCAAsB,EAAC,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IACjE,qEAAqE;IACrE,IAAA,8CAAmC,EAAC,aAAa,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,IAAA,yBAAc,EAAC,aAAa,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACxE,qEAAqE;QACrE,iEAAiE;QACjE,MAAM,IAAI,KAAK,CACb,gBAAgB,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,IAAI,qMAAqM,CACjP,CAAC;IACJ,CAAC;IAED,QAAQ,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;IACrD,MAAM,IAAA,2CAA6B,EACjC,QAAQ,EACR,OAAO,EACP,MAAM,CAAC,SAAS,EAChB,KAAK,CACN,CAAC;AACJ,CAAC,CAAC;AA1BW,QAAA,gBAAgB,oBA0B3B"}
|
|
@@ -6,3 +6,9 @@ import type { Config } from "../../../../packages/pipeline/src/index.js";
|
|
|
6
6
|
* the invalid declaration loudly).
|
|
7
7
|
*/
|
|
8
8
|
export declare const getDeclaredLocalAccessEnvs: (config: Config, componentName: string) => string[];
|
|
9
|
+
/**
|
|
10
|
+
* the declared `credentialsEnvVar` names of a component, mapped to their
|
|
11
|
+
* env. Empty instead of throwing on an invalid declaration, see
|
|
12
|
+
* {@link getDeclaredLocalAccessEnvs}.
|
|
13
|
+
*/
|
|
14
|
+
export declare const getDeclaredLocalAccessCredentialsEnvVars: (config: Config, componentName: string) => Record<string, string>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getDeclaredLocalAccessEnvs = void 0;
|
|
3
|
+
exports.getDeclaredLocalAccessCredentialsEnvVars = exports.getDeclaredLocalAccessEnvs = void 0;
|
|
4
4
|
const pipeline_1 = require("../../../../packages/pipeline/src/index.js");
|
|
5
5
|
/**
|
|
6
6
|
* the envs of a component declaring gcp local access. An invalid
|
|
@@ -17,4 +17,18 @@ const getDeclaredLocalAccessEnvs = (config, componentName) => {
|
|
|
17
17
|
}
|
|
18
18
|
};
|
|
19
19
|
exports.getDeclaredLocalAccessEnvs = getDeclaredLocalAccessEnvs;
|
|
20
|
+
/**
|
|
21
|
+
* the declared `credentialsEnvVar` names of a component, mapped to their
|
|
22
|
+
* env. Empty instead of throwing on an invalid declaration, see
|
|
23
|
+
* {@link getDeclaredLocalAccessEnvs}.
|
|
24
|
+
*/
|
|
25
|
+
const getDeclaredLocalAccessCredentialsEnvVars = (config, componentName) => {
|
|
26
|
+
try {
|
|
27
|
+
return (0, pipeline_1.getLocalAccessGcpCredentialsEnvVars)(config, componentName);
|
|
28
|
+
}
|
|
29
|
+
catch (_a) {
|
|
30
|
+
return {};
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
exports.getDeclaredLocalAccessCredentialsEnvVars = getDeclaredLocalAccessCredentialsEnvVars;
|
|
20
34
|
//# sourceMappingURL=declared.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"declared.js","sourceRoot":"","sources":["../../../../../src/localAccess/declared.ts"],"names":[],"mappings":";;;AACA,
|
|
1
|
+
{"version":3,"file":"declared.js","sourceRoot":"","sources":["../../../../../src/localAccess/declared.ts"],"names":[],"mappings":";;;AACA,kDAG6B;AAE7B;;;;;GAKG;AACI,MAAM,0BAA0B,GAAG,CACxC,MAAc,EACd,aAAqB,EACX,EAAE;IACZ,IAAI,CAAC;QACH,OAAO,IAAA,gCAAqB,EAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACtD,CAAC;IAAC,WAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC,CAAC;AATW,QAAA,0BAA0B,8BASrC;AAEF;;;;GAIG;AACI,MAAM,wCAAwC,GAAG,CACtD,MAAc,EACd,aAAqB,EACG,EAAE;IAC1B,IAAI,CAAC;QACH,OAAO,IAAA,8CAAmC,EAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACpE,CAAC;IAAC,WAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC,CAAC;AATW,QAAA,wCAAwC,4CASnD"}
|
|
@@ -5,12 +5,14 @@ export declare const getLocalAccessKeyFileName: (env: string, componentName: str
|
|
|
5
5
|
/**
|
|
6
6
|
* env var exposing the key file path. Deliberately NOT
|
|
7
7
|
* GOOGLE_APPLICATION_CREDENTIALS: the key must only be used where a
|
|
8
|
-
* command opts in (isolated gcloud config
|
|
8
|
+
* command opts in (isolated gcloud config, or a declared
|
|
9
|
+
* `credentialsEnvVar`), never by ADC implicitly.
|
|
9
10
|
*/
|
|
10
11
|
export declare const getLocalAccessKeyFileVarName: (env: string) => string;
|
|
11
12
|
/**
|
|
12
13
|
* env vars pointing at the key files that exist for the component
|
|
13
|
-
* (only paths, no secrets)
|
|
14
|
+
* (only paths, no secrets): one per env, plus the declared
|
|
15
|
+
* `credentialsEnvVar` names
|
|
14
16
|
*/
|
|
15
17
|
export declare const getLocalAccessKeyFileVars: (config: Config, componentName: string) => Promise<Record<string, string>>;
|
|
16
18
|
/**
|
|
@@ -15,7 +15,8 @@ exports.getLocalAccessKeyFileName = getLocalAccessKeyFileName;
|
|
|
15
15
|
/**
|
|
16
16
|
* env var exposing the key file path. Deliberately NOT
|
|
17
17
|
* GOOGLE_APPLICATION_CREDENTIALS: the key must only be used where a
|
|
18
|
-
* command opts in (isolated gcloud config
|
|
18
|
+
* command opts in (isolated gcloud config, or a declared
|
|
19
|
+
* `credentialsEnvVar`), never by ADC implicitly.
|
|
19
20
|
*/
|
|
20
21
|
const getLocalAccessKeyFileVarName = (env) => `CATLADDER_LOCAL_ACCESS_GCP_${sanitize(env).toUpperCase()}_KEY_FILE`;
|
|
21
22
|
exports.getLocalAccessKeyFileVarName = getLocalAccessKeyFileVarName;
|
|
@@ -23,16 +24,19 @@ exports.getLocalAccessKeyFileVarName = getLocalAccessKeyFileVarName;
|
|
|
23
24
|
const getFolder = async () => (0, path_1.join)(await (0, gitProjectInformation_1.getProjectRootPath)(), ".catladder", "local-access");
|
|
24
25
|
/**
|
|
25
26
|
* env vars pointing at the key files that exist for the component
|
|
26
|
-
* (only paths, no secrets)
|
|
27
|
+
* (only paths, no secrets): one per env, plus the declared
|
|
28
|
+
* `credentialsEnvVar` names
|
|
27
29
|
*/
|
|
28
30
|
const getLocalAccessKeyFileVars = async (config, componentName) => {
|
|
29
31
|
const folder = await getFolder();
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
(0,
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
const getPath = (env) => (0, path_1.join)(folder, (0, exports.getLocalAccessKeyFileName)(env, componentName));
|
|
33
|
+
return Object.fromEntries([
|
|
34
|
+
...(0, declared_1.getDeclaredLocalAccessEnvs)(config, componentName).map((env) => [
|
|
35
|
+
(0, exports.getLocalAccessKeyFileVarName)(env),
|
|
36
|
+
getPath(env),
|
|
37
|
+
]),
|
|
38
|
+
...Object.entries((0, declared_1.getDeclaredLocalAccessCredentialsEnvVars)(config, componentName)).map(([name, env]) => [name, getPath(env)]),
|
|
39
|
+
].filter(([, path]) => (0, fs_1.existsSync)(path)));
|
|
36
40
|
};
|
|
37
41
|
exports.getLocalAccessKeyFileVars = getLocalAccessKeyFileVars;
|
|
38
42
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keyFiles.js","sourceRoot":"","sources":["../../../../../src/localAccess/keyFiles.ts"],"names":[],"mappings":";;;AACA,kDAG6B;AAC7B,0CAA4D;AAC5D,2BAAgC;AAChC,+BAA4B;AAE5B,gEAA6D;AAC7D,
|
|
1
|
+
{"version":3,"file":"keyFiles.js","sourceRoot":"","sources":["../../../../../src/localAccess/keyFiles.ts"],"names":[],"mappings":"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"}
|
|
@@ -948,7 +948,7 @@ exports.gitProjectInformation = gitProjectInformation;
|
|
|
948
948
|
"use strict";
|
|
949
949
|
|
|
950
950
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
951
|
-
exports.getDeclaredLocalAccessEnvs = void 0;
|
|
951
|
+
exports.getDeclaredLocalAccessCredentialsEnvVars = exports.getDeclaredLocalAccessEnvs = void 0;
|
|
952
952
|
const pipeline_1 = __nccwpck_require__(53695);
|
|
953
953
|
/**
|
|
954
954
|
* the envs of a component declaring gcp local access. An invalid
|
|
@@ -965,6 +965,20 @@ const getDeclaredLocalAccessEnvs = (config, componentName) => {
|
|
|
965
965
|
}
|
|
966
966
|
};
|
|
967
967
|
exports.getDeclaredLocalAccessEnvs = getDeclaredLocalAccessEnvs;
|
|
968
|
+
/**
|
|
969
|
+
* the declared `credentialsEnvVar` names of a component, mapped to their
|
|
970
|
+
* env. Empty instead of throwing on an invalid declaration, see
|
|
971
|
+
* {@link getDeclaredLocalAccessEnvs}.
|
|
972
|
+
*/
|
|
973
|
+
const getDeclaredLocalAccessCredentialsEnvVars = (config, componentName) => {
|
|
974
|
+
try {
|
|
975
|
+
return (0, pipeline_1.getLocalAccessGcpCredentialsEnvVars)(config, componentName);
|
|
976
|
+
}
|
|
977
|
+
catch (_a) {
|
|
978
|
+
return {};
|
|
979
|
+
}
|
|
980
|
+
};
|
|
981
|
+
exports.getDeclaredLocalAccessCredentialsEnvVars = getDeclaredLocalAccessCredentialsEnvVars;
|
|
968
982
|
//# sourceMappingURL=declared.js.map
|
|
969
983
|
|
|
970
984
|
/***/ }),
|
|
@@ -990,7 +1004,8 @@ exports.getLocalAccessKeyFileName = getLocalAccessKeyFileName;
|
|
|
990
1004
|
/**
|
|
991
1005
|
* env var exposing the key file path. Deliberately NOT
|
|
992
1006
|
* GOOGLE_APPLICATION_CREDENTIALS: the key must only be used where a
|
|
993
|
-
* command opts in (isolated gcloud config
|
|
1007
|
+
* command opts in (isolated gcloud config, or a declared
|
|
1008
|
+
* `credentialsEnvVar`), never by ADC implicitly.
|
|
994
1009
|
*/
|
|
995
1010
|
const getLocalAccessKeyFileVarName = (env) => `CATLADDER_LOCAL_ACCESS_GCP_${sanitize(env).toUpperCase()}_KEY_FILE`;
|
|
996
1011
|
exports.getLocalAccessKeyFileVarName = getLocalAccessKeyFileVarName;
|
|
@@ -998,16 +1013,19 @@ exports.getLocalAccessKeyFileVarName = getLocalAccessKeyFileVarName;
|
|
|
998
1013
|
const getFolder = async () => (0, path_1.join)(await (0, gitProjectInformation_1.getProjectRootPath)(), ".catladder", "local-access");
|
|
999
1014
|
/**
|
|
1000
1015
|
* env vars pointing at the key files that exist for the component
|
|
1001
|
-
* (only paths, no secrets)
|
|
1016
|
+
* (only paths, no secrets): one per env, plus the declared
|
|
1017
|
+
* `credentialsEnvVar` names
|
|
1002
1018
|
*/
|
|
1003
1019
|
const getLocalAccessKeyFileVars = async (config, componentName) => {
|
|
1004
1020
|
const folder = await getFolder();
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
(0,
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1021
|
+
const getPath = (env) => (0, path_1.join)(folder, (0, exports.getLocalAccessKeyFileName)(env, componentName));
|
|
1022
|
+
return Object.fromEntries([
|
|
1023
|
+
...(0, declared_1.getDeclaredLocalAccessEnvs)(config, componentName).map((env) => [
|
|
1024
|
+
(0, exports.getLocalAccessKeyFileVarName)(env),
|
|
1025
|
+
getPath(env),
|
|
1026
|
+
]),
|
|
1027
|
+
...Object.entries((0, declared_1.getDeclaredLocalAccessCredentialsEnvVars)(config, componentName)).map(([name, env]) => [name, getPath(env)]),
|
|
1028
|
+
].filter(([, path]) => (0, fs_1.existsSync)(path)));
|
|
1011
1029
|
};
|
|
1012
1030
|
exports.getLocalAccessKeyFileVars = getLocalAccessKeyFileVars;
|
|
1013
1031
|
/**
|
|
@@ -12890,13 +12908,16 @@ __exportStar(__nccwpck_require__(54165), exports);
|
|
|
12890
12908
|
"use strict";
|
|
12891
12909
|
|
|
12892
12910
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
12893
|
-
exports.diffRoleBindings = exports.getLocalAccessGcpSecretName = exports.getLocalAccessGcpEnvs = exports.getLocalAccessGcpRoles = exports.getLocalAccessConfig = exports.getDeniedLocalAccessRoleReason = exports.LOCAL_ACCESS_GCP_SA_NAME = exports.LOCAL_ACCESS_GCP_PRESETS = void 0;
|
|
12911
|
+
exports.getLocalAccessGcpCredentialsEnvVars = exports.diffRoleBindings = exports.getLocalAccessGcpSecretName = exports.getLocalAccessGcpEnvs = exports.getLocalAccessGcpRoles = exports.getLocalAccessConfig = exports.getDeniedLocalAccessRoleReason = exports.LOCAL_ACCESS_GCP_SA_NAME = exports.LOCAL_ACCESS_GCP_PRESETS = void 0;
|
|
12894
12912
|
const configruedEnvs_1 = __nccwpck_require__(38866);
|
|
12895
12913
|
const getEnvConfig_1 = __nccwpck_require__(69578);
|
|
12896
12914
|
const types_1 = __nccwpck_require__(79689);
|
|
12897
12915
|
exports.LOCAL_ACCESS_GCP_PRESETS = {
|
|
12898
12916
|
// no run.viewer on purpose, see LocalAccessGcpPreset
|
|
12899
12917
|
logs: ["roles/logging.viewer"],
|
|
12918
|
+
// not read-only, see LocalAccessGcpPreset; only reachable as a
|
|
12919
|
+
// preset, getDeniedLocalAccessRoleReason rejects it in `roles`
|
|
12920
|
+
vertex: ["roles/aiplatform.user"],
|
|
12900
12921
|
};
|
|
12901
12922
|
/** name prefix of the service account `project setup` creates (see getGcloudServiceAccountNames) */
|
|
12902
12923
|
exports.LOCAL_ACCESS_GCP_SA_NAME = "local-diag";
|
|
@@ -13036,6 +13057,31 @@ const diffRoleBindings = (desired, current) => ({
|
|
|
13036
13057
|
extra: current.filter((role) => !desired.includes(role)),
|
|
13037
13058
|
});
|
|
13038
13059
|
exports.diffRoleBindings = diffRoleBindings;
|
|
13060
|
+
const ENV_VAR_NAME_FORMAT = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
13061
|
+
/**
|
|
13062
|
+
* the extra env var names (`credentialsEnvVar`) under which the local
|
|
13063
|
+
* env of a component exports the key file path, mapped to the env whose
|
|
13064
|
+
* key they point at. Throws on a malformed name or on two envs
|
|
13065
|
+
* exporting the same name (e.g. a project default declaring it).
|
|
13066
|
+
*/
|
|
13067
|
+
const getLocalAccessGcpCredentialsEnvVars = (config, componentName) => {
|
|
13068
|
+
var _a, _b;
|
|
13069
|
+
const vars = {};
|
|
13070
|
+
for (const env of (0, exports.getLocalAccessGcpEnvs)(config, componentName)) {
|
|
13071
|
+
const name = (_b = (_a = (0, exports.getLocalAccessConfig)(config, env)) === null || _a === void 0 ? void 0 : _a.gcp) === null || _b === void 0 ? void 0 : _b.credentialsEnvVar;
|
|
13072
|
+
if (!name)
|
|
13073
|
+
continue;
|
|
13074
|
+
if (!ENV_VAR_NAME_FORMAT.test(name)) {
|
|
13075
|
+
throw new Error(`localAccess (${env}): credentialsEnvVar '${name}' is not a valid env var name`);
|
|
13076
|
+
}
|
|
13077
|
+
if (vars[name]) {
|
|
13078
|
+
throw new Error(`localAccess (${componentName}): credentialsEnvVar '${name}' is declared by both ${vars[name]} and ${env}; declare it in one env only (environments.<env>.localAccess)`);
|
|
13079
|
+
}
|
|
13080
|
+
vars[name] = env;
|
|
13081
|
+
}
|
|
13082
|
+
return vars;
|
|
13083
|
+
};
|
|
13084
|
+
exports.getLocalAccessGcpCredentialsEnvVars = getLocalAccessGcpCredentialsEnvVars;
|
|
13039
13085
|
//# sourceMappingURL=index.js.map
|
|
13040
13086
|
|
|
13041
13087
|
/***/ }),
|
|
@@ -1093,6 +1093,7 @@ const checkLocalAccess = async (report, config, contexts, inspector) => {
|
|
|
1093
1093
|
let declared;
|
|
1094
1094
|
try {
|
|
1095
1095
|
declared = (0, pipeline_1.getLocalAccessGcpRoles)(config, context.env);
|
|
1096
|
+
(0, pipeline_1.getLocalAccessGcpCredentialsEnvVars)(config, context.name);
|
|
1096
1097
|
}
|
|
1097
1098
|
catch (e) {
|
|
1098
1099
|
return { label, invalid: e.message };
|
|
@@ -2198,7 +2199,7 @@ const pipeline_1 = __nccwpck_require__(53695);
|
|
|
2198
2199
|
const getProjectConfig_1 = __nccwpck_require__(70478);
|
|
2199
2200
|
const localAccess_1 = __nccwpck_require__(94216);
|
|
2200
2201
|
/**
|
|
2201
|
-
* provisions the
|
|
2202
|
+
* provisions the local access (`localAccess` in catladder.ts)
|
|
2202
2203
|
* of a google cloud run component/env: a dedicated service account with
|
|
2203
2204
|
* exactly the declared bindings and its key in the secret store. Also
|
|
2204
2205
|
* removes what is no longer declared.
|
|
@@ -2210,6 +2211,8 @@ const setupLocalAccess = async (instance, context) => {
|
|
|
2210
2211
|
return;
|
|
2211
2212
|
const projectConfig = await (0, getProjectConfig_1.getProjectConfig)();
|
|
2212
2213
|
const roles = (0, pipeline_1.getLocalAccessGcpRoles)(projectConfig, context.env);
|
|
2214
|
+
// validates `credentialsEnvVar` (catenv silently skips invalid ones)
|
|
2215
|
+
(0, pipeline_1.getLocalAccessGcpCredentialsEnvVars)(projectConfig, context.name);
|
|
2213
2216
|
if (roles.length > 0 && (0, pipeline_1.getVaultConfig)(projectConfig).type === "gitlab") {
|
|
2214
2217
|
// the gitlab vault stores secrets as CI variables available to every
|
|
2215
2218
|
// job on every branch: the key would leak to anyone who can push
|
|
@@ -6982,7 +6985,7 @@ exports.startKubePortForward = startKubePortForward;
|
|
|
6982
6985
|
"use strict";
|
|
6983
6986
|
|
|
6984
6987
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
6985
|
-
exports.getDeclaredLocalAccessEnvs = void 0;
|
|
6988
|
+
exports.getDeclaredLocalAccessCredentialsEnvVars = exports.getDeclaredLocalAccessEnvs = void 0;
|
|
6986
6989
|
const pipeline_1 = __nccwpck_require__(53695);
|
|
6987
6990
|
/**
|
|
6988
6991
|
* the envs of a component declaring gcp local access. An invalid
|
|
@@ -6999,6 +7002,20 @@ const getDeclaredLocalAccessEnvs = (config, componentName) => {
|
|
|
6999
7002
|
}
|
|
7000
7003
|
};
|
|
7001
7004
|
exports.getDeclaredLocalAccessEnvs = getDeclaredLocalAccessEnvs;
|
|
7005
|
+
/**
|
|
7006
|
+
* the declared `credentialsEnvVar` names of a component, mapped to their
|
|
7007
|
+
* env. Empty instead of throwing on an invalid declaration, see
|
|
7008
|
+
* {@link getDeclaredLocalAccessEnvs}.
|
|
7009
|
+
*/
|
|
7010
|
+
const getDeclaredLocalAccessCredentialsEnvVars = (config, componentName) => {
|
|
7011
|
+
try {
|
|
7012
|
+
return (0, pipeline_1.getLocalAccessGcpCredentialsEnvVars)(config, componentName);
|
|
7013
|
+
}
|
|
7014
|
+
catch (_a) {
|
|
7015
|
+
return {};
|
|
7016
|
+
}
|
|
7017
|
+
};
|
|
7018
|
+
exports.getDeclaredLocalAccessCredentialsEnvVars = getDeclaredLocalAccessCredentialsEnvVars;
|
|
7002
7019
|
//# sourceMappingURL=declared.js.map
|
|
7003
7020
|
|
|
7004
7021
|
/***/ }),
|
|
@@ -7024,7 +7041,8 @@ exports.getLocalAccessKeyFileName = getLocalAccessKeyFileName;
|
|
|
7024
7041
|
/**
|
|
7025
7042
|
* env var exposing the key file path. Deliberately NOT
|
|
7026
7043
|
* GOOGLE_APPLICATION_CREDENTIALS: the key must only be used where a
|
|
7027
|
-
* command opts in (isolated gcloud config
|
|
7044
|
+
* command opts in (isolated gcloud config, or a declared
|
|
7045
|
+
* `credentialsEnvVar`), never by ADC implicitly.
|
|
7028
7046
|
*/
|
|
7029
7047
|
const getLocalAccessKeyFileVarName = (env) => `CATLADDER_LOCAL_ACCESS_GCP_${sanitize(env).toUpperCase()}_KEY_FILE`;
|
|
7030
7048
|
exports.getLocalAccessKeyFileVarName = getLocalAccessKeyFileVarName;
|
|
@@ -7032,16 +7050,19 @@ exports.getLocalAccessKeyFileVarName = getLocalAccessKeyFileVarName;
|
|
|
7032
7050
|
const getFolder = async () => (0, path_1.join)(await (0, gitProjectInformation_1.getProjectRootPath)(), ".catladder", "local-access");
|
|
7033
7051
|
/**
|
|
7034
7052
|
* env vars pointing at the key files that exist for the component
|
|
7035
|
-
* (only paths, no secrets)
|
|
7053
|
+
* (only paths, no secrets): one per env, plus the declared
|
|
7054
|
+
* `credentialsEnvVar` names
|
|
7036
7055
|
*/
|
|
7037
7056
|
const getLocalAccessKeyFileVars = async (config, componentName) => {
|
|
7038
7057
|
const folder = await getFolder();
|
|
7039
|
-
|
|
7040
|
-
|
|
7041
|
-
(0,
|
|
7042
|
-
|
|
7043
|
-
|
|
7044
|
-
|
|
7058
|
+
const getPath = (env) => (0, path_1.join)(folder, (0, exports.getLocalAccessKeyFileName)(env, componentName));
|
|
7059
|
+
return Object.fromEntries([
|
|
7060
|
+
...(0, declared_1.getDeclaredLocalAccessEnvs)(config, componentName).map((env) => [
|
|
7061
|
+
(0, exports.getLocalAccessKeyFileVarName)(env),
|
|
7062
|
+
getPath(env),
|
|
7063
|
+
]),
|
|
7064
|
+
...Object.entries((0, declared_1.getDeclaredLocalAccessCredentialsEnvVars)(config, componentName)).map(([name, env]) => [name, getPath(env)]),
|
|
7065
|
+
].filter(([, path]) => (0, fs_1.existsSync)(path)));
|
|
7045
7066
|
};
|
|
7046
7067
|
exports.getLocalAccessKeyFileVars = getLocalAccessKeyFileVars;
|
|
7047
7068
|
/**
|
|
@@ -19920,13 +19941,16 @@ __exportStar(__nccwpck_require__(54165), exports);
|
|
|
19920
19941
|
"use strict";
|
|
19921
19942
|
|
|
19922
19943
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
19923
|
-
exports.diffRoleBindings = exports.getLocalAccessGcpSecretName = exports.getLocalAccessGcpEnvs = exports.getLocalAccessGcpRoles = exports.getLocalAccessConfig = exports.getDeniedLocalAccessRoleReason = exports.LOCAL_ACCESS_GCP_SA_NAME = exports.LOCAL_ACCESS_GCP_PRESETS = void 0;
|
|
19944
|
+
exports.getLocalAccessGcpCredentialsEnvVars = exports.diffRoleBindings = exports.getLocalAccessGcpSecretName = exports.getLocalAccessGcpEnvs = exports.getLocalAccessGcpRoles = exports.getLocalAccessConfig = exports.getDeniedLocalAccessRoleReason = exports.LOCAL_ACCESS_GCP_SA_NAME = exports.LOCAL_ACCESS_GCP_PRESETS = void 0;
|
|
19924
19945
|
const configruedEnvs_1 = __nccwpck_require__(38866);
|
|
19925
19946
|
const getEnvConfig_1 = __nccwpck_require__(69578);
|
|
19926
19947
|
const types_1 = __nccwpck_require__(79689);
|
|
19927
19948
|
exports.LOCAL_ACCESS_GCP_PRESETS = {
|
|
19928
19949
|
// no run.viewer on purpose, see LocalAccessGcpPreset
|
|
19929
19950
|
logs: ["roles/logging.viewer"],
|
|
19951
|
+
// not read-only, see LocalAccessGcpPreset; only reachable as a
|
|
19952
|
+
// preset, getDeniedLocalAccessRoleReason rejects it in `roles`
|
|
19953
|
+
vertex: ["roles/aiplatform.user"],
|
|
19930
19954
|
};
|
|
19931
19955
|
/** name prefix of the service account `project setup` creates (see getGcloudServiceAccountNames) */
|
|
19932
19956
|
exports.LOCAL_ACCESS_GCP_SA_NAME = "local-diag";
|
|
@@ -20066,6 +20090,31 @@ const diffRoleBindings = (desired, current) => ({
|
|
|
20066
20090
|
extra: current.filter((role) => !desired.includes(role)),
|
|
20067
20091
|
});
|
|
20068
20092
|
exports.diffRoleBindings = diffRoleBindings;
|
|
20093
|
+
const ENV_VAR_NAME_FORMAT = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
20094
|
+
/**
|
|
20095
|
+
* the extra env var names (`credentialsEnvVar`) under which the local
|
|
20096
|
+
* env of a component exports the key file path, mapped to the env whose
|
|
20097
|
+
* key they point at. Throws on a malformed name or on two envs
|
|
20098
|
+
* exporting the same name (e.g. a project default declaring it).
|
|
20099
|
+
*/
|
|
20100
|
+
const getLocalAccessGcpCredentialsEnvVars = (config, componentName) => {
|
|
20101
|
+
var _a, _b;
|
|
20102
|
+
const vars = {};
|
|
20103
|
+
for (const env of (0, exports.getLocalAccessGcpEnvs)(config, componentName)) {
|
|
20104
|
+
const name = (_b = (_a = (0, exports.getLocalAccessConfig)(config, env)) === null || _a === void 0 ? void 0 : _a.gcp) === null || _b === void 0 ? void 0 : _b.credentialsEnvVar;
|
|
20105
|
+
if (!name)
|
|
20106
|
+
continue;
|
|
20107
|
+
if (!ENV_VAR_NAME_FORMAT.test(name)) {
|
|
20108
|
+
throw new Error(`localAccess (${env}): credentialsEnvVar '${name}' is not a valid env var name`);
|
|
20109
|
+
}
|
|
20110
|
+
if (vars[name]) {
|
|
20111
|
+
throw new Error(`localAccess (${componentName}): credentialsEnvVar '${name}' is declared by both ${vars[name]} and ${env}; declare it in one env only (environments.<env>.localAccess)`);
|
|
20112
|
+
}
|
|
20113
|
+
vars[name] = env;
|
|
20114
|
+
}
|
|
20115
|
+
return vars;
|
|
20116
|
+
};
|
|
20117
|
+
exports.getLocalAccessGcpCredentialsEnvVars = getLocalAccessGcpCredentialsEnvVars;
|
|
20069
20118
|
//# sourceMappingURL=index.js.map
|
|
20070
20119
|
|
|
20071
20120
|
/***/ }),
|
|
@@ -143,6 +143,17 @@ non-CI vault (e.g. bitwarden) — `project setup` refuses with the gitlab
|
|
|
143
143
|
vault. After a key rotation on another machine, run
|
|
144
144
|
`catenv --vault-mode refresh`.
|
|
145
145
|
|
|
146
|
+
The `vertex` preset grants `roles/aiplatform.user` (to call Vertex AI
|
|
147
|
+
models, e.g. local evals). It is **not** read-only: it can use and bill
|
|
148
|
+
every Vertex AI API of the project and create/change/delete Vertex AI
|
|
149
|
+
resources; it is only accepted as a preset, never in `roles`. Add
|
|
150
|
+
`credentialsEnvVar: "GOOGLE_APPLICATION_CREDENTIALS"` (in one env only)
|
|
151
|
+
to have catenv export the key path under that name as well, so google
|
|
152
|
+
client libraries use it without `gcloud auth application-default login`.
|
|
153
|
+
The variable lands in the component's `.env` (e.g. `apps/web/.env`), not
|
|
154
|
+
in a root `.env`: scripts run from the repo root must load that file
|
|
155
|
+
(`node --env-file-if-exists=apps/web/.env …`).
|
|
156
|
+
|
|
146
157
|
## Related skills
|
|
147
158
|
|
|
148
159
|
- `catladder-config` — general catladder.ts structure and regeneration
|
|
@@ -44,3 +44,10 @@ export declare const diffRoleBindings: (desired: string[], current: string[]) =>
|
|
|
44
44
|
missing: string[];
|
|
45
45
|
extra: string[];
|
|
46
46
|
};
|
|
47
|
+
/**
|
|
48
|
+
* the extra env var names (`credentialsEnvVar`) under which the local
|
|
49
|
+
* env of a component exports the key file path, mapped to the env whose
|
|
50
|
+
* key they point at. Throws on a malformed name or on two envs
|
|
51
|
+
* exporting the same name (e.g. a project default declaring it).
|
|
52
|
+
*/
|
|
53
|
+
export declare const getLocalAccessGcpCredentialsEnvVars: (config: Config, componentName: string) => Record<string, string>;
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.diffRoleBindings = exports.getLocalAccessGcpSecretName = exports.getLocalAccessGcpEnvs = exports.getLocalAccessGcpRoles = exports.getLocalAccessConfig = exports.getDeniedLocalAccessRoleReason = exports.LOCAL_ACCESS_GCP_SA_NAME = exports.LOCAL_ACCESS_GCP_PRESETS = void 0;
|
|
3
|
+
exports.getLocalAccessGcpCredentialsEnvVars = exports.diffRoleBindings = exports.getLocalAccessGcpSecretName = exports.getLocalAccessGcpEnvs = exports.getLocalAccessGcpRoles = exports.getLocalAccessConfig = exports.getDeniedLocalAccessRoleReason = exports.LOCAL_ACCESS_GCP_SA_NAME = exports.LOCAL_ACCESS_GCP_PRESETS = void 0;
|
|
4
4
|
const configruedEnvs_1 = require("../config/configruedEnvs");
|
|
5
5
|
const getEnvConfig_1 = require("../context/getEnvConfig");
|
|
6
6
|
const types_1 = require("../deploy/types");
|
|
7
7
|
exports.LOCAL_ACCESS_GCP_PRESETS = {
|
|
8
8
|
// no run.viewer on purpose, see LocalAccessGcpPreset
|
|
9
9
|
logs: ["roles/logging.viewer"],
|
|
10
|
+
// not read-only, see LocalAccessGcpPreset; only reachable as a
|
|
11
|
+
// preset, getDeniedLocalAccessRoleReason rejects it in `roles`
|
|
12
|
+
vertex: ["roles/aiplatform.user"],
|
|
10
13
|
};
|
|
11
14
|
/** name prefix of the service account `project setup` creates (see getGcloudServiceAccountNames) */
|
|
12
15
|
exports.LOCAL_ACCESS_GCP_SA_NAME = "local-diag";
|
|
@@ -146,4 +149,29 @@ const diffRoleBindings = (desired, current) => ({
|
|
|
146
149
|
extra: current.filter((role) => !desired.includes(role)),
|
|
147
150
|
});
|
|
148
151
|
exports.diffRoleBindings = diffRoleBindings;
|
|
152
|
+
const ENV_VAR_NAME_FORMAT = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
153
|
+
/**
|
|
154
|
+
* the extra env var names (`credentialsEnvVar`) under which the local
|
|
155
|
+
* env of a component exports the key file path, mapped to the env whose
|
|
156
|
+
* key they point at. Throws on a malformed name or on two envs
|
|
157
|
+
* exporting the same name (e.g. a project default declaring it).
|
|
158
|
+
*/
|
|
159
|
+
const getLocalAccessGcpCredentialsEnvVars = (config, componentName) => {
|
|
160
|
+
var _a, _b;
|
|
161
|
+
const vars = {};
|
|
162
|
+
for (const env of (0, exports.getLocalAccessGcpEnvs)(config, componentName)) {
|
|
163
|
+
const name = (_b = (_a = (0, exports.getLocalAccessConfig)(config, env)) === null || _a === void 0 ? void 0 : _a.gcp) === null || _b === void 0 ? void 0 : _b.credentialsEnvVar;
|
|
164
|
+
if (!name)
|
|
165
|
+
continue;
|
|
166
|
+
if (!ENV_VAR_NAME_FORMAT.test(name)) {
|
|
167
|
+
throw new Error(`localAccess (${env}): credentialsEnvVar '${name}' is not a valid env var name`);
|
|
168
|
+
}
|
|
169
|
+
if (vars[name]) {
|
|
170
|
+
throw new Error(`localAccess (${componentName}): credentialsEnvVar '${name}' is declared by both ${vars[name]} and ${env}; declare it in one env only (environments.<env>.localAccess)`);
|
|
171
|
+
}
|
|
172
|
+
vars[name] = env;
|
|
173
|
+
}
|
|
174
|
+
return vars;
|
|
175
|
+
};
|
|
176
|
+
exports.getLocalAccessGcpCredentialsEnvVars = getLocalAccessGcpCredentialsEnvVars;
|
|
149
177
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../packages/pipeline/src/localAccess/index.ts"],"names":[],"mappings":";;;AAAA,6DAAsD;AACtD,0DAAuD;AACvD,2CAAiD;AAGpC,QAAA,wBAAwB,GACnC;IACE,qDAAqD;IACrD,IAAI,EAAE,CAAC,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../packages/pipeline/src/localAccess/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -250,8 +250,13 @@ export declare const isEnvironmentDisabled: (environments: EnvironmentsConfig |
|
|
|
250
250
|
* `roles/run.viewer`: cloud run services/jobs are deployed with
|
|
251
251
|
* their secrets as plain env vars, so anything with `run.*.get`
|
|
252
252
|
* can read every deployed secret.
|
|
253
|
+
* - `vertex`: `roles/aiplatform.user`, to call Vertex AI models (e.g.
|
|
254
|
+
* for local evals). NOT read-only: it may use (and bill) every Vertex
|
|
255
|
+
* AI API of the project and create, change and delete Vertex AI
|
|
256
|
+
* resources (datasets, endpoints, models, jobs). It reads no other
|
|
257
|
+
* service's data. Only available as a preset, `roles` rejects it.
|
|
253
258
|
*/
|
|
254
|
-
export type LocalAccessGcpPreset = "logs";
|
|
259
|
+
export type LocalAccessGcpPreset = "logs" | "vertex";
|
|
255
260
|
export type LocalAccessGcpConfig = {
|
|
256
261
|
/** preset role bundles, see {@link LocalAccessGcpPreset} */
|
|
257
262
|
presets?: LocalAccessGcpPreset[];
|
|
@@ -269,9 +274,22 @@ export type LocalAccessGcpConfig = {
|
|
|
269
274
|
* What you grant beyond the allow-list is your responsibility.
|
|
270
275
|
*/
|
|
271
276
|
allowAnyRole?: boolean;
|
|
277
|
+
/**
|
|
278
|
+
* also export the key file path under this env var name in the
|
|
279
|
+
* `local` env of the component (in addition to
|
|
280
|
+
* `CATLADDER_LOCAL_ACCESS_GCP_<ENV>_KEY_FILE`), e.g.
|
|
281
|
+
* `GOOGLE_APPLICATION_CREDENTIALS` so google client libraries use the
|
|
282
|
+
* key instead of a personal ADC login. Every process that loads the
|
|
283
|
+
* component's env then acts as the service account, so declare it in
|
|
284
|
+
* one env only (two envs exporting the same name are rejected).
|
|
285
|
+
* Overrides a var of the same name declared in `vars` while the key
|
|
286
|
+
* file exists.
|
|
287
|
+
*/
|
|
288
|
+
credentialsEnvVar?: string;
|
|
272
289
|
};
|
|
273
290
|
/**
|
|
274
|
-
* which
|
|
291
|
+
* which access LOCAL use gets for an env (read-only, unless a preset
|
|
292
|
+
* like `vertex` says otherwise). `project setup`
|
|
275
293
|
* creates a dedicated service account per component/env, grants exactly
|
|
276
294
|
* these bindings (and removes bindings no longer declared) and stores
|
|
277
295
|
* its key in the secret store under the `local` env — never in CI
|
|
@@ -143,6 +143,17 @@ non-CI vault (e.g. bitwarden) — `project setup` refuses with the gitlab
|
|
|
143
143
|
vault. After a key rotation on another machine, run
|
|
144
144
|
`catenv --vault-mode refresh`.
|
|
145
145
|
|
|
146
|
+
The `vertex` preset grants `roles/aiplatform.user` (to call Vertex AI
|
|
147
|
+
models, e.g. local evals). It is **not** read-only: it can use and bill
|
|
148
|
+
every Vertex AI API of the project and create/change/delete Vertex AI
|
|
149
|
+
resources; it is only accepted as a preset, never in `roles`. Add
|
|
150
|
+
`credentialsEnvVar: "GOOGLE_APPLICATION_CREDENTIALS"` (in one env only)
|
|
151
|
+
to have catenv export the key path under that name as well, so google
|
|
152
|
+
client libraries use it without `gcloud auth application-default login`.
|
|
153
|
+
The variable lands in the component's `.env` (e.g. `apps/web/.env`), not
|
|
154
|
+
in a root `.env`: scripts run from the repo root must load that file
|
|
155
|
+
(`node --env-file-if-exists=apps/web/.env …`).
|
|
156
|
+
|
|
146
157
|
## Related skills
|
|
147
158
|
|
|
148
159
|
- `catladder-config` — general catladder.ts structure and regeneration
|