From 9d7d5ea420a3ae9ed40699b0fcd128bb4080eb35 Mon Sep 17 00:00:00 2001 From: Miguel Campos Date: Thu, 31 Oct 2024 10:03:51 -0700 Subject: [PATCH 1/8] switch ssh permissions to lifecycle SDK --- src/commands/shared/ssh.ts | 6 +++--- src/plugins/aws/ssh.ts | 15 ++++++++------- src/plugins/aws/types.ts | 28 +++++++++++++--------------- src/plugins/google/ssh.ts | 11 ++++------- src/plugins/google/types.ts | 13 +++++-------- src/types/request.ts | 2 +- 6 files changed, 34 insertions(+), 41 deletions(-) diff --git a/src/commands/shared/ssh.ts b/src/commands/shared/ssh.ts index 57ed4d6..134e289 100644 --- a/src/commands/shared/ssh.ts +++ b/src/commands/shared/ssh.ts @@ -90,7 +90,7 @@ const pluginToCliRequest = async ( request: Request, options?: { debug?: boolean } ): Promise> => - await SSH_PROVIDERS[request.permission.spec.type].toCliRequest( + await SSH_PROVIDERS[request.permission.provider].toCliRequest( request as any, options ); @@ -139,7 +139,7 @@ export const provisionRequest = async ( authn, id ); - if (provisionedRequest.permission.spec.publicKey !== publicKey) { + if (provisionedRequest.permission.publicKey !== publicKey) { throw "Public key mismatch. Please revoke the request and try again."; } @@ -158,7 +158,7 @@ export const prepareRequest = async ( const { provisionedRequest } = result; - const sshProvider = SSH_PROVIDERS[provisionedRequest.permission.spec.type]; + const sshProvider = SSH_PROVIDERS[provisionedRequest.permission.provider]; await sshProvider.ensureInstall(); const cliRequest = await pluginToCliRequest(provisionedRequest, { diff --git a/src/plugins/aws/ssh.ts b/src/plugins/aws/ssh.ts index 85cce00..0e99995 100644 --- a/src/plugins/aws/ssh.ts +++ b/src/plugins/aws/ssh.ts @@ -112,18 +112,19 @@ export const awsSshProvider: SshProvider< requestToSsh: (request) => { const { permission, generated } = request; - const { awsResourcePermission, instanceId, accountId, region } = - permission.spec; - const { idcId, idcRegion } = awsResourcePermission.permission; - const { ssh, name } = generated; - const { linuxUserName } = ssh; + const { resource, region } = permission; + const { idcId, idcRegion, instanceId, accountId } = resource; + const { + linuxUserName, + resource: { name: roleName }, + } = generated; const common = { linuxUserName, accountId, region, id: instanceId }; return !idcId || !idcRegion - ? { ...common, role: name, type: "aws", access: "role" } + ? { ...common, role: roleName, type: "aws", access: "role" } : { ...common, idc: { id: idcId, region: idcRegion }, - permissionSet: name, + permissionSet: roleName, type: "aws", access: "idc", }; diff --git a/src/plugins/aws/types.ts b/src/plugins/aws/types.ts index 0642dd6..51cd5ba 100644 --- a/src/plugins/aws/types.ts +++ b/src/plugins/aws/types.ts @@ -62,27 +62,25 @@ export type AwsConfig = { // -- Specific AWS permission types -export type AwsSshPermission = { - spec: CommonSshPermissionSpec & { +export type AwsSshPermission = CommonSshPermissionSpec & { + provider: "aws"; + region: string; + alias: string; + resource: { + idcRegion: string; + idcId: string; + account: string; instanceId: string; + name: string; + userName: string; + arn: string; accountId: string; - region: string; - type: "aws"; - awsResourcePermission: { - permission: { - idcId?: string; - idcRegion?: string; - }; - }; }; - type: "session"; }; export type AwsSshGenerated = { - name: string; - ssh: { - linuxUserName: string; - }; + resource: { name: string }; + linuxUserName: string; }; export type AwsSshPermissionSpec = PermissionSpec< diff --git a/src/plugins/google/ssh.ts b/src/plugins/google/ssh.ts index 8b85666..f52c5f0 100644 --- a/src/plugins/google/ssh.ts +++ b/src/plugins/google/ssh.ts @@ -107,9 +107,9 @@ export const gcpSshProvider: SshProvider< requestToSsh: (request) => { return { - id: request.permission.spec.instanceName, - projectId: request.permission.spec.projectId, - zone: request.permission.spec.zone, + id: request.permission.instanceName, + projectId: request.permission.projectId, + zone: request.permission.zone, linuxUserName: request.cliLocalData.linuxUserName, type: "gcloud", }; @@ -120,10 +120,7 @@ export const gcpSshProvider: SshProvider< toCliRequest: async (request, options) => ({ ...request, cliLocalData: { - linuxUserName: await importSshKey( - request.permission.spec.publicKey, - options - ), + linuxUserName: await importSshKey(request.permission.publicKey, options), }, }), }; diff --git a/src/plugins/google/types.ts b/src/plugins/google/types.ts index 608822d..1d5c3ab 100644 --- a/src/plugins/google/types.ts +++ b/src/plugins/google/types.ts @@ -12,14 +12,11 @@ import { PermissionSpec } from "../../types/request"; import { CliPermissionSpec } from "../../types/ssh"; import { CommonSshPermissionSpec } from "../ssh/types"; -export type GcpSshPermission = { - spec: CommonSshPermissionSpec & { - instanceName: string; - projectId: string; - zone: string; - type: "gcloud"; - }; - type: "session"; +export type GcpSshPermission = CommonSshPermissionSpec & { + instanceName: string; + projectId: string; + zone: string; + provider: "gcloud"; }; export type GcpSshPermissionSpec = PermissionSpec<"ssh", GcpSshPermission>; diff --git a/src/types/request.ts b/src/types/request.ts index fb0e52c..fc16781 100644 --- a/src/types/request.ts +++ b/src/types/request.ts @@ -21,7 +21,7 @@ export const ERROR_STATUSES = [ export type PermissionSpec< K extends string, - P extends { type: string }, + P extends { provider: string } | { type: string }, G extends object | undefined = undefined, > = { type: K; From 3aa338353587d8a8e487f42f12b9ff09cbb35fd3 Mon Sep 17 00:00:00 2001 From: Miguel Campos Date: Wed, 13 Nov 2024 13:56:29 -0800 Subject: [PATCH 2/8] add placeholder for azure --- src/plugins/aws/ssh.ts | 6 +++--- src/plugins/azure/ssh.ts | 9 +++------ src/plugins/azure/types.ts | 17 ++++++++++++++--- src/types/request.ts | 4 ++-- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/plugins/aws/ssh.ts b/src/plugins/aws/ssh.ts index 0e99995..cd5e1a2 100644 --- a/src/plugins/aws/ssh.ts +++ b/src/plugins/aws/ssh.ts @@ -116,15 +116,15 @@ export const awsSshProvider: SshProvider< const { idcId, idcRegion, instanceId, accountId } = resource; const { linuxUserName, - resource: { name: roleName }, + resource: { name }, } = generated; const common = { linuxUserName, accountId, region, id: instanceId }; return !idcId || !idcRegion - ? { ...common, role: roleName, type: "aws", access: "role" } + ? { ...common, role: name, type: "aws", access: "role" } : { ...common, idc: { id: idcId, region: idcRegion }, - permissionSet: roleName, + permissionSet: name, type: "aws", access: "idc", }; diff --git a/src/plugins/azure/ssh.ts b/src/plugins/azure/ssh.ts index 528b33e..df48f7f 100644 --- a/src/plugins/azure/ssh.ts +++ b/src/plugins/azure/ssh.ts @@ -57,8 +57,8 @@ export const azureSshProvider: SshProvider< // TODO: Placeholder requestToSsh: (request) => ({ type: "azure", - id: request.permission.spec.instanceId, - instanceId: request.permission.spec.instanceId, + id: request.permission.resource.instanceId, + instanceId: request.permission.resource.instanceId, linuxUserName: request.cliLocalData.linuxUserName, }), @@ -69,10 +69,7 @@ export const azureSshProvider: SshProvider< toCliRequest: async (request, options) => ({ ...request, cliLocalData: { - linuxUserName: await importSshKey( - request.permission.spec.publicKey, - options - ), + linuxUserName: await importSshKey(request.permission.publicKey, options), }, }), }; diff --git a/src/plugins/azure/types.ts b/src/plugins/azure/types.ts index faeaf58..7c1fa09 100644 --- a/src/plugins/azure/types.ts +++ b/src/plugins/azure/types.ts @@ -20,9 +20,20 @@ export type AzureSsh = CliPermissionSpec< { linuxUserName: string } >; -export type AzureSshPermission = { - type: "session"; - spec: CommonSshPermissionSpec & AzureNodeSpec; +export type AzureSshPermission = CommonSshPermissionSpec & { + provider: "azure"; + destination: string; + parent: string | undefined; + group: string | undefined; + resource: { + instanceName: string; + instanceId: string; + subscriptionId: string; + subscriptionName: string; + resourceGroupId: string; + region: string; + networkInterfaceIds: string[]; + }; }; // TODO: Placeholder; probably wrong diff --git a/src/types/request.ts b/src/types/request.ts index fc16781..2a69b4a 100644 --- a/src/types/request.ts +++ b/src/types/request.ts @@ -9,7 +9,7 @@ This file is part of @p0security/cli You should have received a copy of the GNU General Public License along with @p0security/cli. If not, see . **/ import { K8sPermissionSpec } from "../plugins/kubeconfig/types"; -import { PluginSshRequest } from "./ssh"; +import { PluginSshRequest, SupportedSshProvider } from "./ssh"; export const DONE_STATUSES = ["DONE", "DONE_NOTIFIED"] as const; export const DENIED_STATUSES = ["DENIED", "DENIED_NOTIFIED"] as const; @@ -21,7 +21,7 @@ export const ERROR_STATUSES = [ export type PermissionSpec< K extends string, - P extends { provider: string } | { type: string }, + P extends { provider: SupportedSshProvider } | { type: string }, G extends object | undefined = undefined, > = { type: K; From ca57b618e91a5f25342c02b56f177f066aca4013 Mon Sep 17 00:00:00 2001 From: Miguel Campos Date: Wed, 13 Nov 2024 14:07:21 -0800 Subject: [PATCH 3/8] fix unit tests --- src/commands/__tests__/ssh.test.ts | 41 +++++++++++++++++++----------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/src/commands/__tests__/ssh.test.ts b/src/commands/__tests__/ssh.test.ts index c6d62ff..24651a6 100644 --- a/src/commands/__tests__/ssh.test.ts +++ b/src/commands/__tests__/ssh.test.ts @@ -11,6 +11,7 @@ You should have received a copy of the GNU General Public License along with @p0 import { TEST_PUBLIC_KEY } from "../../common/__mocks__/keys"; import { fetchCommand } from "../../drivers/api"; import { print1, print2 } from "../../drivers/stdio"; +import { AwsSshGenerated, AwsSshPermission } from "../../plugins/aws/types"; import { sshOrScp } from "../../plugins/ssh"; import { mockGetDoc } from "../../testing/firestore"; import { sleep } from "../../util"; @@ -30,24 +31,34 @@ const mockSshOrScp = sshOrScp as jest.Mock; const mockPrint1 = print1 as jest.Mock; const mockPrint2 = print2 as jest.Mock; -const MOCK_REQUEST = { - status: "DONE", - generated: { +const MOCK_PERMISSION: AwsSshPermission = { + provider: "aws", + publicKey: TEST_PUBLIC_KEY, + region: "region", + alias: "alias", + resource: { + account: "accountId", + accountId: "accountId", + arn: "arn", + idcRegion: "idcRegion", + idcId: "idcId", name: "name", - ssh: { - linuxUserName: "linuxUserName", - }, + userName: "userName", + instanceId: "instanceId", }, - permission: { - spec: { - awsResourcePermission: { permission: {} }, - instanceId: "instanceId", - accountId: "accountId", - region: "region", - publicKey: TEST_PUBLIC_KEY, - type: "aws", - }, +}; + +const MOCK_GENERATED: AwsSshGenerated = { + resource: { + name: "name", }, + linuxUserName: "linuxUserName", +}; + +const MOCK_REQUEST = { + status: "DONE", + generated: MOCK_GENERATED, + permission: MOCK_PERMISSION, }; mockGetDoc({ From fdf210d04f8e90f1b5fedca1fb25fa4716e3068c Mon Sep 17 00:00:00 2001 From: Miguel Campos Date: Wed, 13 Nov 2024 14:30:53 -0800 Subject: [PATCH 4/8] sort --- src/plugins/aws/types.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/aws/types.ts b/src/plugins/aws/types.ts index 51cd5ba..3466612 100644 --- a/src/plugins/aws/types.ts +++ b/src/plugins/aws/types.ts @@ -67,14 +67,14 @@ export type AwsSshPermission = CommonSshPermissionSpec & { region: string; alias: string; resource: { - idcRegion: string; - idcId: string; account: string; + accountId: string; + arn: string; + idcId: string; + idcRegion: string; instanceId: string; name: string; userName: string; - arn: string; - accountId: string; }; }; From 260a12c4ab0e826b58548278f587795db5986384 Mon Sep 17 00:00:00 2001 From: Miguel Campos Date: Wed, 13 Nov 2024 14:44:00 -0800 Subject: [PATCH 5/8] fix gcloud types --- src/plugins/google/ssh.ts | 4 ++-- src/plugins/google/types.ts | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/plugins/google/ssh.ts b/src/plugins/google/ssh.ts index f52c5f0..0e0aca3 100644 --- a/src/plugins/google/ssh.ts +++ b/src/plugins/google/ssh.ts @@ -107,8 +107,8 @@ export const gcpSshProvider: SshProvider< requestToSsh: (request) => { return { - id: request.permission.instanceName, - projectId: request.permission.projectId, + id: request.permission.resource.instanceName, + projectId: request.permission.resource.projectId, zone: request.permission.zone, linuxUserName: request.cliLocalData.linuxUserName, type: "gcloud", diff --git a/src/plugins/google/types.ts b/src/plugins/google/types.ts index 1d5c3ab..12e133a 100644 --- a/src/plugins/google/types.ts +++ b/src/plugins/google/types.ts @@ -13,10 +13,12 @@ import { CliPermissionSpec } from "../../types/ssh"; import { CommonSshPermissionSpec } from "../ssh/types"; export type GcpSshPermission = CommonSshPermissionSpec & { - instanceName: string; - projectId: string; zone: string; provider: "gcloud"; + resource: { + instanceName: string; + projectId: string; + }; }; export type GcpSshPermissionSpec = PermissionSpec<"ssh", GcpSshPermission>; From 88e939df70e400fb52ef5162bcd22e917fc38e20 Mon Sep 17 00:00:00 2001 From: Miguel Campos Date: Thu, 14 Nov 2024 15:15:40 -0800 Subject: [PATCH 6/8] update package number --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index f61a2ee..d366384 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@p0security/cli", - "version": "0.11.4", + "version": "0.12.0", "description": "Execute infra CLI commands with P0 grants", "main": "index.ts", "repository": { @@ -77,4 +77,4 @@ "prepublishOnly": "npm run clean && npm run build" }, "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" -} +} \ No newline at end of file From 1893eb7af964863eac38e26e9847173ced527046 Mon Sep 17 00:00:00 2001 From: Miguel Campos Date: Thu, 14 Nov 2024 15:17:30 -0800 Subject: [PATCH 7/8] put whitespace back --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d366384..aa3864e 100644 --- a/package.json +++ b/package.json @@ -77,4 +77,4 @@ "prepublishOnly": "npm run clean && npm run build" }, "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" -} \ No newline at end of file +} From 53bc53e0c1dd1a43f98e747609d95bf950a5bce8 Mon Sep 17 00:00:00 2001 From: Miguel Campos Date: Thu, 14 Nov 2024 15:57:41 -0800 Subject: [PATCH 8/8] fix order; fix destructure --- src/plugins/aws/ssh.ts | 6 ++---- src/plugins/google/types.ts | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/plugins/aws/ssh.ts b/src/plugins/aws/ssh.ts index cd5e1a2..22fbe32 100644 --- a/src/plugins/aws/ssh.ts +++ b/src/plugins/aws/ssh.ts @@ -114,10 +114,8 @@ export const awsSshProvider: SshProvider< const { permission, generated } = request; const { resource, region } = permission; const { idcId, idcRegion, instanceId, accountId } = resource; - const { - linuxUserName, - resource: { name }, - } = generated; + const { linuxUserName, resource: generatedResource } = generated; + const { name } = generatedResource; const common = { linuxUserName, accountId, region, id: instanceId }; return !idcId || !idcRegion ? { ...common, role: name, type: "aws", access: "role" } diff --git a/src/plugins/google/types.ts b/src/plugins/google/types.ts index 12e133a..3f9f8d5 100644 --- a/src/plugins/google/types.ts +++ b/src/plugins/google/types.ts @@ -13,8 +13,8 @@ import { CliPermissionSpec } from "../../types/ssh"; import { CommonSshPermissionSpec } from "../ssh/types"; export type GcpSshPermission = CommonSshPermissionSpec & { - zone: string; provider: "gcloud"; + zone: string; resource: { instanceName: string; projectId: string; @@ -29,11 +29,11 @@ export type GcpSsh = CliPermissionSpec< >; export type GcpSshRequest = { + type: "gcloud"; linuxUserName: string; projectId: string; zone: string; id: string; - type: "gcloud"; }; type PosixAccount = {