@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.
- package/dist/commands/__tests__/grant.test.d.ts +1 -0
- package/dist/commands/__tests__/grant.test.js +55 -0
- package/dist/commands/grant.d.ts +4 -0
- package/dist/commands/grant.js +17 -0
- package/dist/commands/index.js +2 -0
- package/dist/commands/request.d.ts +0 -8
- package/dist/commands/request.js +3 -102
- package/dist/commands/scp.d.ts +1 -1
- package/dist/commands/scp.js +5 -4
- package/dist/commands/shared/index.d.ts +4 -0
- package/dist/commands/shared/index.js +67 -0
- package/dist/commands/shared/request.d.ts +14 -0
- package/dist/commands/shared/request.js +115 -0
- package/dist/commands/{shared.d.ts → shared/ssh.d.ts} +12 -22
- package/dist/commands/{shared.js → shared/ssh.js} +21 -75
- package/dist/commands/ssh.d.ts +1 -1
- package/dist/commands/ssh.js +3 -3
- package/dist/common/retry.d.ts +9 -0
- package/dist/common/retry.js +50 -0
- package/dist/drivers/auth.d.ts +1 -1
- package/dist/drivers/auth.js +7 -3
- package/dist/plugins/aws/config.d.ts +1 -1
- package/dist/plugins/aws/idc/index.d.ts +16 -0
- package/dist/plugins/aws/idc/index.js +150 -0
- package/dist/plugins/aws/ssh.d.ts +3 -3
- package/dist/plugins/aws/ssh.js +75 -11
- package/dist/plugins/aws/types.d.ts +29 -5
- package/dist/plugins/google/ssh.d.ts +5 -13
- package/dist/plugins/google/ssh.js +71 -10
- package/dist/plugins/google/types.d.ts +11 -3
- package/dist/plugins/login.d.ts +3 -0
- package/dist/plugins/login.js +10 -0
- package/dist/plugins/oidc/login.d.ts +33 -2
- package/dist/plugins/oidc/login.js +100 -60
- package/dist/plugins/okta/aws.d.ts +1 -1
- package/dist/plugins/okta/aws.js +2 -2
- package/dist/plugins/okta/login.js +11 -1
- package/dist/plugins/ping/login.d.ts +2 -1
- package/dist/plugins/ping/login.js +11 -1
- package/dist/plugins/ssh/index.d.ts +3 -2
- package/dist/plugins/ssh/index.js +65 -84
- package/dist/types/aws/oidc.d.ts +36 -0
- package/dist/types/aws/oidc.js +12 -0
- package/dist/types/oidc.d.ts +21 -0
- package/dist/types/request.d.ts +2 -7
- package/dist/types/ssh.d.ts +47 -0
- package/dist/types/ssh.js +5 -0
- 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
|
|
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
|
|
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
|
|
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 ${
|
|
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
|
-
(
|
|
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
|
|
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
|
-
|
|
259
|
-
|
|
260
|
-
|
|
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
|
|
263
|
-
account: data.accountId,
|
|
264
|
-
role: data.role,
|
|
265
|
-
});
|
|
244
|
+
return null;
|
|
266
245
|
});
|
|
267
|
-
const sshOrScp = (authn,
|
|
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
|
-
|
|
272
|
-
const credential =
|
|
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 } =
|
|
254
|
+
const { command, args } = createCommand(request, cmdArgs, proxyCommand);
|
|
275
255
|
if (cmdArgs.debug) {
|
|
276
|
-
const reproCommands =
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
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:
|
|
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 });
|
package/dist/types/oidc.d.ts
CHANGED
|
@@ -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
|
+
};
|
package/dist/types/request.d.ts
CHANGED
|
@@ -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 {
|
|
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;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@p0security/cli",
|
|
3
|
-
"version": "0.8.
|
|
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.
|
|
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
|
}
|