@p0security/cli 0.8.1 → 0.8.3

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.
Files changed (48) hide show
  1. package/dist/commands/__tests__/grant.test.d.ts +1 -0
  2. package/dist/commands/__tests__/grant.test.js +55 -0
  3. package/dist/commands/grant.d.ts +4 -0
  4. package/dist/commands/grant.js +17 -0
  5. package/dist/commands/index.js +2 -0
  6. package/dist/commands/request.d.ts +0 -8
  7. package/dist/commands/request.js +3 -102
  8. package/dist/commands/scp.d.ts +1 -1
  9. package/dist/commands/scp.js +5 -4
  10. package/dist/commands/shared/index.d.ts +4 -0
  11. package/dist/commands/shared/index.js +67 -0
  12. package/dist/commands/shared/request.d.ts +14 -0
  13. package/dist/commands/shared/request.js +115 -0
  14. package/dist/commands/{shared.d.ts → shared/ssh.d.ts} +12 -22
  15. package/dist/commands/{shared.js → shared/ssh.js} +21 -75
  16. package/dist/commands/ssh.d.ts +1 -1
  17. package/dist/commands/ssh.js +3 -3
  18. package/dist/common/retry.d.ts +9 -0
  19. package/dist/common/retry.js +50 -0
  20. package/dist/drivers/auth.d.ts +1 -1
  21. package/dist/drivers/auth.js +7 -3
  22. package/dist/plugins/aws/config.d.ts +1 -1
  23. package/dist/plugins/aws/idc/index.d.ts +16 -0
  24. package/dist/plugins/aws/idc/index.js +150 -0
  25. package/dist/plugins/aws/ssh.d.ts +3 -3
  26. package/dist/plugins/aws/ssh.js +75 -11
  27. package/dist/plugins/aws/types.d.ts +29 -5
  28. package/dist/plugins/google/ssh.d.ts +5 -13
  29. package/dist/plugins/google/ssh.js +71 -10
  30. package/dist/plugins/google/types.d.ts +11 -3
  31. package/dist/plugins/login.d.ts +3 -0
  32. package/dist/plugins/login.js +10 -0
  33. package/dist/plugins/oidc/login.d.ts +33 -2
  34. package/dist/plugins/oidc/login.js +100 -60
  35. package/dist/plugins/okta/aws.d.ts +1 -1
  36. package/dist/plugins/okta/aws.js +2 -2
  37. package/dist/plugins/okta/login.js +11 -1
  38. package/dist/plugins/ping/login.d.ts +2 -1
  39. package/dist/plugins/ping/login.js +11 -1
  40. package/dist/plugins/ssh/index.d.ts +3 -2
  41. package/dist/plugins/ssh/index.js +65 -84
  42. package/dist/types/aws/oidc.d.ts +36 -0
  43. package/dist/types/aws/oidc.js +12 -0
  44. package/dist/types/oidc.d.ts +21 -0
  45. package/dist/types/request.d.ts +2 -7
  46. package/dist/types/ssh.d.ts +47 -0
  47. package/dist/types/ssh.js +5 -0
  48. package/package.json +4 -3
@@ -10,11 +10,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.sshOrScp = void 0;
13
+ /** Copyright © 2024-present P0 Security
14
+
15
+ This file is part of @p0security/cli
16
+
17
+ @p0security/cli is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.
18
+
19
+ @p0security/cli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
20
+
21
+ You should have received a copy of the GNU General Public License along with @p0security/cli. If not, see <https://www.gnu.org/licenses/>.
22
+ **/
23
+ const ssh_1 = require("../../commands/shared/ssh");
13
24
  const keys_1 = require("../../common/keys");
14
25
  const stdio_1 = require("../../drivers/stdio");
15
- const util_1 = require("../../util");
16
- const install_1 = require("../aws/ssm/install");
17
- const aws_1 = require("../okta/aws");
18
26
  const ssh_agent_1 = require("../ssh-agent");
19
27
  const node_child_process_1 = require("node:child_process");
20
28
  /** Matches the error message that AWS SSM print1 when access is not propagated */
@@ -33,18 +41,11 @@ const UNAUTHORIZED_TUNNEL_USER_MESSAGE = /Error while connecting \[4033: 'not au
33
41
  const UNAUTHORIZED_INSTANCES_GET_MESSAGE = /Required 'compute\.instances\.get' permission/;
34
42
  const DESTINATION_READ_ERROR = /Error while connecting \[4010: 'destination read failed'\]/;
35
43
  const GOOGLE_LOGIN_MESSAGE = /You do not currently have an active account selected/;
44
+ const SUDO_MESSAGE = /Sorry, user .+ may not run sudo on .+/; // The output of `sudo -v` when the user is not allowed to run sudo
36
45
  /** Maximum amount of time after SSH subprocess starts to check for {@link UNPROVISIONED_ACCESS_MESSAGES}
37
46
  * in the process's stderr
38
47
  */
39
48
  const DEFAULT_VALIDATION_WINDOW_MS = 5e3;
40
- /** Maximum number of attempts to start an SSH session
41
- *
42
- * Note that each attempt consumes ~ 1 s.
43
- */
44
- const DEFAULT_MAX_SSH_RETRIES = 30;
45
- const GCP_MAX_SSH_RETRIES = 120; // GCP requires more time to propagate access
46
- /** The name of the SessionManager port forwarding document. This document is managed by AWS. */
47
- const START_SSH_SESSION_DOCUMENT_NAME = "AWS-StartSSHSession";
48
49
  /**
49
50
  * AWS
50
51
  * There are 2 cases of unprovisioned access in AWS
@@ -55,7 +56,7 @@ const START_SSH_SESSION_DOCUMENT_NAME = "AWS-StartSSHSession";
55
56
  * 2: results in CONNECTION_CLOSED_MESSAGE
56
57
  *
57
58
  * Google Cloud
58
- * There are 5 cases of unprovisioned access in Google Cloud.
59
+ * There are 7 cases of unprovisioned access in Google Cloud.
59
60
  * These are all potentially subject to propagation delays.
60
61
  * 1. The linux user name is not present in the user's Google Workspace profile `posixAccounts` attribute
61
62
  * 2. The public key is not present in the user's Google Workspace profile `sshPublicKeys` attribute
@@ -64,17 +65,20 @@ const START_SSH_SESSION_DOCUMENT_NAME = "AWS-StartSSHSession";
64
65
  * 5. The user doesn't have osLogin or osAdminLogin role to the instance
65
66
  * 5.a. compute.instances.get permission is missing
66
67
  * 5.b. compute.instances.osLogin permission is missing
67
- * 6: Rare occurrence, the exact conditions so far undetermined (together with CONNECTION_CLOSED_MESSAGE)
68
+ * 6. compute.instances.osAdminLogin is not provisioned but compute.instances.osLogin is - happens when a user upgrades existing access to sudo
69
+ * 7: Rare occurrence, the exact conditions so far undetermined (together with CONNECTION_CLOSED_MESSAGE)
68
70
  *
69
71
  * 1, 2, 3 (yes!), 5b: result in PUBLIC_KEY_DENIED_MESSAGE
70
72
  * 4: results in UNAUTHORIZED_TUNNEL_USER_MESSAGE and also CONNECTION_CLOSED_MESSAGE
71
73
  * 5a: results in UNAUTHORIZED_INSTANCES_GET_MESSAGE
72
- * 6: results in DESTINATION_READ_ERROR and also CONNECTION_CLOSED_MESSAGE
74
+ * 6: results in SUDO_MESSAGE
75
+ * 7: results in DESTINATION_READ_ERROR and also CONNECTION_CLOSED_MESSAGE
73
76
  */
74
77
  const UNPROVISIONED_ACCESS_MESSAGES = [
75
78
  { pattern: UNAUTHORIZED_START_SESSION_MESSAGE },
76
79
  { pattern: CONNECTION_CLOSED_MESSAGE },
77
80
  { pattern: PUBLIC_KEY_DENIED_MESSAGE },
81
+ { pattern: SUDO_MESSAGE },
78
82
  { pattern: UNAUTHORIZED_TUNNEL_USER_MESSAGE },
79
83
  { pattern: UNAUTHORIZED_INSTANCES_GET_MESSAGE, validationWindowMs: 30e3 },
80
84
  { pattern: DESTINATION_READ_ERROR },
@@ -125,11 +129,6 @@ const spawnChildProcess = (credential, command, args, stdio) => (0, node_child_p
125
129
  stdio,
126
130
  shell: false,
127
131
  });
128
- const friendlyProvider = (provider) => provider === "aws"
129
- ? "AWS"
130
- : provider === "gcloud"
131
- ? "Google Cloud"
132
- : (0, util_1.throwAssertNever)(provider);
133
132
  /** Starts an SSM session in the terminal by spawning `aws ssm` as a subprocess
134
133
  *
135
134
  * Requires `aws ssm` to be installed on the client machine.
@@ -137,6 +136,7 @@ const friendlyProvider = (provider) => provider === "aws"
137
136
  function spawnSshNode(options) {
138
137
  return __awaiter(this, void 0, void 0, function* () {
139
138
  return new Promise((resolve, reject) => {
139
+ const provider = ssh_1.SSH_PROVIDERS[options.provider];
140
140
  const child = spawnChildProcess(options.credential, options.command, options.args, options.stdio);
141
141
  // TODO ENG-2284 support login with Google Cloud: currently return a boolean to indicate if the exception was a Google login error.
142
142
  const { isAccessPropagated, isGoogleLoginException } = accessPropagationGuard(child, options.debug);
@@ -151,7 +151,7 @@ function spawnSshNode(options) {
151
151
  (0, stdio_1.print2)(`Waiting for access to propagate. Retrying SSH session... (remaining attempts: ${attemptsRemaining})`);
152
152
  }
153
153
  if (attemptsRemaining <= 0) {
154
- reject(`Access did not propagate through ${friendlyProvider(options.provider)} before max retry attempts were exceeded. Please contact support@p0.dev for assistance.`);
154
+ reject(`Access did not propagate through ${provider.friendlyName} before max retry attempts were exceeded. Please contact support@p0.dev for assistance.`);
155
155
  return;
156
156
  }
157
157
  spawnSshNode(Object.assign(Object.assign({}, options), { attemptsRemaining: attemptsRemaining - 1 }))
@@ -164,50 +164,16 @@ function spawnSshNode(options) {
164
164
  return;
165
165
  }
166
166
  (_a = options.abortController) === null || _a === void 0 ? void 0 : _a.abort(code);
167
- (0, stdio_1.print2)(`SSH session terminated`);
167
+ if (!options.isAccessPropagationPreTest)
168
+ (0, stdio_1.print2)(`SSH session terminated`);
168
169
  resolve(code);
169
170
  });
170
171
  });
171
172
  });
172
173
  }
173
- const createProxyCommands = (data, args, debug) => {
174
- let proxyCommand;
175
- if (data.type === "aws") {
176
- proxyCommand = [
177
- "aws",
178
- "ssm",
179
- "start-session",
180
- "--region",
181
- data.region,
182
- "--target",
183
- "%h",
184
- "--document-name",
185
- START_SSH_SESSION_DOCUMENT_NAME,
186
- "--parameters",
187
- '"portNumber=%p"',
188
- ];
189
- }
190
- else if (data.type === "gcloud") {
191
- proxyCommand = [
192
- "gcloud",
193
- "compute",
194
- "start-iap-tunnel",
195
- data.id,
196
- "%p",
197
- // --listen-on-stdin flag is required for interactive SSH session.
198
- // It is undocumented on page https://cloud.google.com/sdk/gcloud/reference/compute/start-iap-tunnel
199
- // but mention on page https://cloud.google.com/iap/docs/tcp-by-host
200
- // and also found in `gcloud ssh --dry-run` output
201
- "--listen-on-stdin",
202
- `--zone=${data.zone}`,
203
- `--project=${data.projectId}`,
204
- ];
205
- }
206
- else {
207
- throw (0, util_1.assertNever)(data);
208
- }
174
+ const createCommand = (data, args, proxyCommand) => {
209
175
  const commonArgs = [
210
- ...(debug ? ["-v"] : []),
176
+ ...(args.debug ? ["-v"] : []),
211
177
  "-o",
212
178
  `ProxyCommand=${proxyCommand.join(" ")}`,
213
179
  ];
@@ -255,38 +221,53 @@ const transformForShell = (args) => {
255
221
  return arg;
256
222
  });
257
223
  };
258
- const awsLogin = (authn, data) => __awaiter(void 0, void 0, void 0, function* () {
259
- if (!(yield (0, install_1.ensureSsmInstall)())) {
260
- throw "Please try again after installing the required AWS utilities";
224
+ /** Construct another command to use for testing access propagation prior to actually logging in the user to the ssh session */
225
+ const preTestAccessPropagationIfNeeded = (sshProvider, request, cmdArgs, proxyCommand, credential) => __awaiter(void 0, void 0, void 0, function* () {
226
+ const testCmdArgs = sshProvider.preTestAccessPropagationArgs(cmdArgs);
227
+ // Pre-testing comes at a performance cost because we have to execute another ssh subprocess after
228
+ // a successful test. Only do when absolutely necessary.
229
+ if (testCmdArgs) {
230
+ const { command, args } = createCommand(request, testCmdArgs, proxyCommand);
231
+ // Assumes that this is a non-interactive ssh command that exits automatically
232
+ return spawnSshNode({
233
+ credential,
234
+ abortController: new AbortController(),
235
+ command,
236
+ args,
237
+ stdio: ["inherit", "inherit", "pipe"],
238
+ debug: cmdArgs.debug,
239
+ provider: request.type,
240
+ attemptsRemaining: sshProvider.maxRetries,
241
+ isAccessPropagationPreTest: true,
242
+ });
261
243
  }
262
- return yield (0, aws_1.assumeRoleWithOktaSaml)(authn, {
263
- account: data.accountId,
264
- role: data.role,
265
- });
244
+ return null;
266
245
  });
267
- const sshOrScp = (authn, data, cmdArgs, privateKey) => __awaiter(void 0, void 0, void 0, function* () {
246
+ const sshOrScp = (authn, request, cmdArgs, privateKey) => __awaiter(void 0, void 0, void 0, function* () {
268
247
  if (!privateKey) {
269
248
  throw "Failed to load a private key for this request. Please contact support@p0.dev for assistance.";
270
249
  }
271
- // TODO ENG-2284 support login with Google Cloud
272
- const credential = data.type === "aws" ? yield awsLogin(authn, data) : undefined;
250
+ const sshProvider = ssh_1.SSH_PROVIDERS[request.type];
251
+ const credential = yield sshProvider.cloudProviderLogin(authn, request);
252
+ const proxyCommand = sshProvider.proxyCommand(request);
273
253
  return (0, ssh_agent_1.withSshAgent)(cmdArgs, () => __awaiter(void 0, void 0, void 0, function* () {
274
- const { command, args } = createProxyCommands(data, cmdArgs, cmdArgs.debug);
254
+ const { command, args } = createCommand(request, cmdArgs, proxyCommand);
275
255
  if (cmdArgs.debug) {
276
- const reproCommands = [
277
- `eval $(ssh-agent)`,
278
- `ssh-add "${keys_1.PRIVATE_KEY_PATH}"`,
279
- // TODO ENG-2284 support login with Google Cloud
280
- ...(data.type === "aws"
281
- ? [
282
- `eval $(p0 aws role assume ${data.role} --account ${data.accountId})`,
283
- ]
284
- : []),
285
- `${command} ${transformForShell(args).join(" ")}`,
286
- ];
287
- (0, stdio_1.print2)(`Execute the following commands to create a similar SSH/SCP session:\n*** COMMANDS BEGIN ***\n${reproCommands.join("\n")}\n*** COMMANDS END ***"\n`);
256
+ const reproCommands = sshProvider.reproCommands(request);
257
+ if (reproCommands) {
258
+ const repro = [
259
+ `eval $(ssh-agent)`,
260
+ `ssh-add "${keys_1.PRIVATE_KEY_PATH}"`,
261
+ ...reproCommands,
262
+ `${command} ${transformForShell(args).join(" ")}`,
263
+ ].join("\n");
264
+ (0, stdio_1.print2)(`Execute the following commands to create a similar SSH/SCP session:\n*** COMMANDS BEGIN ***\n${repro}\n*** COMMANDS END ***"\n`);
265
+ }
266
+ }
267
+ const exitCode = yield preTestAccessPropagationIfNeeded(sshProvider, request, cmdArgs, proxyCommand, credential);
268
+ if (exitCode && exitCode !== 0) {
269
+ return exitCode; // Only exit if there was an error when pre-testing
288
270
  }
289
- const maxRetries = data.type === "gcloud" ? GCP_MAX_SSH_RETRIES : DEFAULT_MAX_SSH_RETRIES;
290
271
  return spawnSshNode({
291
272
  credential,
292
273
  abortController: new AbortController(),
@@ -294,8 +275,8 @@ const sshOrScp = (authn, data, cmdArgs, privateKey) => __awaiter(void 0, void 0,
294
275
  args,
295
276
  stdio: ["inherit", "inherit", "pipe"],
296
277
  debug: cmdArgs.debug,
297
- provider: data.type,
298
- attemptsRemaining: maxRetries,
278
+ provider: request.type,
279
+ attemptsRemaining: sshProvider.maxRetries,
299
280
  });
300
281
  }));
301
282
  });
@@ -0,0 +1,36 @@
1
+ /** Copyright © 2024-present P0 Security
2
+
3
+ This file is part of @p0security/cli
4
+
5
+ @p0security/cli is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.
6
+
7
+ @p0security/cli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
8
+
9
+ You should have received a copy of the GNU General Public License along with @p0security/cli. If not, see <https://www.gnu.org/licenses/>.
10
+ **/
11
+ export declare type AWSClientInformation = {
12
+ authorizationEndpoint: string;
13
+ clientId: string;
14
+ clientIdIssuedAt: number;
15
+ clientSecret: string;
16
+ clientSecretExpiresAt: number;
17
+ tokenEndpoint: string;
18
+ };
19
+ /**
20
+ * AWS OIDC token response uses camelCase instead of snake_case
21
+ */
22
+ export declare type AWSTokenResponse = {
23
+ accessToken: string;
24
+ expiresIn: number;
25
+ idToken: string;
26
+ refreshToken: string;
27
+ tokenType: string;
28
+ };
29
+ export declare type AWSAuthorizeResponse = {
30
+ deviceCode: string;
31
+ expiresIn: number;
32
+ interval: number;
33
+ userCode: string;
34
+ verificationUri: string;
35
+ verificationUriComplete: string;
36
+ };
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ /** Copyright © 2024-present P0 Security
3
+
4
+ This file is part of @p0security/cli
5
+
6
+ @p0security/cli is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.
7
+
8
+ @p0security/cli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
9
+
10
+ You should have received a copy of the GNU General Public License along with @p0security/cli. If not, see <https://www.gnu.org/licenses/>.
11
+ **/
12
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,3 +1,4 @@
1
+ import { LoginPluginType } from "../plugins/login";
1
2
  /** Copyright © 2024-present P0 Security
2
3
 
3
4
  This file is part of @p0security/cli
@@ -39,3 +40,23 @@ export declare type TokenResponse = {
39
40
  export declare type TokenErrorResponse = {
40
41
  error: "access_denied" | "authorization_pending" | "bad grant type" | "expired_token" | "missing parameter" | "not found" | "slow_down";
41
42
  };
43
+ export declare type OidcLoginSteps<A> = {
44
+ providerType: LoginPluginType;
45
+ validateResponse: (response: Response) => Promise<Response>;
46
+ buildAuthorizeRequest: () => {
47
+ url: string;
48
+ init: RequestInit;
49
+ };
50
+ buildTokenRequest: (authorize: A) => {
51
+ url: string;
52
+ init: RequestInit;
53
+ };
54
+ processAuthzResponse: (authorize: A) => {
55
+ user_code: string;
56
+ verification_uri_complete: string;
57
+ };
58
+ processAuthzExpiry: (authorize: A) => {
59
+ expires_in: number;
60
+ interval: number;
61
+ };
62
+ };
@@ -8,16 +8,10 @@ This file is part of @p0security/cli
8
8
 
9
9
  You should have received a copy of the GNU General Public License along with @p0security/cli. If not, see <https://www.gnu.org/licenses/>.
10
10
  **/
11
- import { AwsPermissionSpec, AwsSsh } from "../plugins/aws/types";
12
- import { GcpPermissionSpec, GcpSsh } from "../plugins/google/types";
11
+ import { PluginSshRequest } from "./ssh";
13
12
  export declare const DONE_STATUSES: readonly ["DONE", "DONE_NOTIFIED"];
14
13
  export declare const DENIED_STATUSES: readonly ["DENIED", "DENIED_NOTIFIED"];
15
14
  export declare const ERROR_STATUSES: readonly ["ERRORED", "ERRORED", "ERRORED_NOTIFIED"];
16
- export declare type CliRequest = AwsSsh | GcpSsh;
17
- export declare type PluginRequest = AwsPermissionSpec | GcpPermissionSpec;
18
- export declare type CliPermissionSpec<P extends PluginRequest, C extends object | undefined = undefined> = P & {
19
- cliLocalData: C;
20
- };
21
15
  export declare type PermissionSpec<K extends string, P extends {
22
16
  type: string;
23
17
  }, G extends object | undefined = undefined> = {
@@ -25,6 +19,7 @@ export declare type PermissionSpec<K extends string, P extends {
25
19
  permission: P;
26
20
  generated: G;
27
21
  };
22
+ export declare type PluginRequest = PluginSshRequest;
28
23
  export declare type Request<P extends PluginRequest> = P & {
29
24
  status: string;
30
25
  principal: string;
@@ -0,0 +1,47 @@
1
+ /** Copyright © 2024-present P0 Security
2
+
3
+ This file is part of @p0security/cli
4
+
5
+ @p0security/cli is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.
6
+
7
+ @p0security/cli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
8
+
9
+ You should have received a copy of the GNU General Public License along with @p0security/cli. If not, see <https://www.gnu.org/licenses/>.
10
+ **/
11
+ import { CommandArgs } from "../commands/shared/ssh";
12
+ import { AwsSsh, AwsSshPermissionSpec, AwsSshRequest } from "../plugins/aws/types";
13
+ import { GcpSsh, GcpSshPermissionSpec, GcpSshRequest } from "../plugins/google/types";
14
+ import { Authn } from "./identity";
15
+ import { Request } from "./request";
16
+ export declare type CliSshRequest = AwsSsh | GcpSsh;
17
+ export declare type PluginSshRequest = AwsSshPermissionSpec | GcpSshPermissionSpec;
18
+ export declare type CliPermissionSpec<P extends PluginSshRequest, C extends object | undefined> = P & {
19
+ cliLocalData: C;
20
+ };
21
+ export declare const SupportedSshProviders: readonly ["aws", "gcloud"];
22
+ export declare type SupportedSshProvider = (typeof SupportedSshProviders)[number];
23
+ export declare type SshProvider<PR extends PluginSshRequest = PluginSshRequest, O extends object | undefined = undefined, SR extends SshRequest = SshRequest, C extends object | undefined = undefined> = {
24
+ requestToSsh: (request: CliPermissionSpec<PR, O>) => SR;
25
+ /** Converts a backend request to a CLI request */
26
+ toCliRequest: (request: Request<PR>, options?: {
27
+ debug?: boolean;
28
+ }) => Promise<Request<CliSshRequest>>;
29
+ /** Logs in the user to the cloud provider */
30
+ cloudProviderLogin: (authn: Authn, request: SR) => Promise<C>;
31
+ /** Returns the command and its arguments that are going to be injected as the ssh ProxyCommand option */
32
+ proxyCommand: (request: SR) => string[];
33
+ /** Each element in the returned array is a command that can be run to reproduce the
34
+ * steps of logging in the user to the ssh session. */
35
+ reproCommands: (request: SR) => string[] | undefined;
36
+ /** Arguments for a pre-test command to verify access propagation prior
37
+ * to actually logging in the user to the ssh session.
38
+ * This must return arguments for a non-interactive command - meaning the `command`
39
+ * and potentially the `args` props must be specified in the returned scp/ssh command.
40
+ * If the return value is undefined then no pre-testing is done prior to executing
41
+ * the actual ssh/scp command.
42
+ */
43
+ preTestAccessPropagationArgs: (cmdArgs: CommandArgs) => CommandArgs | undefined;
44
+ maxRetries: number;
45
+ friendlyName: string;
46
+ };
47
+ export declare type SshRequest = AwsSshRequest | GcpSshRequest;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SupportedSshProviders = void 0;
4
+ // The prefix of installed SSH accounts in P0 is the provider name
5
+ exports.SupportedSshProviders = ["aws", "gcloud"];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@p0security/cli",
3
- "version": "0.8.1",
3
+ "version": "0.8.3",
4
4
  "description": "Execute infra CLI commands with P0 grants",
5
5
  "main": "index.ts",
6
6
  "repository": {
@@ -25,7 +25,7 @@
25
25
  "express": "^4.18.2",
26
26
  "firebase": "^10.7.2",
27
27
  "inquirer": "^9.2.15",
28
- "jsdom": "^24.0.0",
28
+ "jsdom": "^24.1.1",
29
29
  "lodash": "^4.17.21",
30
30
  "node-forge": "^1.3.1",
31
31
  "open": "^8.4.0",
@@ -67,5 +67,6 @@
67
67
  "lint": "yarn prettier --check . && yarn run eslint --max-warnings 0 .",
68
68
  "p0": "node --no-deprecation ./p0",
69
69
  "prepublishOnly": "npm run clean && npm run build"
70
- }
70
+ },
71
+ "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
71
72
  }