Skip to content

Commit

Permalink
feat(integrations): Add AWS Secrets Manager IAM Role + Region
Browse files Browse the repository at this point in the history
  • Loading branch information
McPizza0 committed Nov 22, 2024
1 parent 1a084d8 commit aec770d
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 1 deletion.
24 changes: 24 additions & 0 deletions backend/src/server/routes/v1/integration-router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,30 @@ export const registerIntegrationRouter = async (server: FastifyZodProvider) => {
id: req.params.integrationId
});

if (integration.integration === "aws-secret-manager") {
// Fetch additional AWS integration details
const awsRoleDetails = await server.services.integration.getIntegrationAWSAssumeRoleArn({
actorId: req.permission.id,
actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
id: req.params.integrationId
});

if (integration.metadata) {
integration.metadata = {
...integration.metadata,
awsRegion: integration.region,
awsIamRole: awsRoleDetails.role
};
} else {
integration.metadata = {
awsRegion: integration.region,
awsIamRole: awsRoleDetails.role
};
}
}

return { integration };
}
});
Expand Down
42 changes: 42 additions & 0 deletions backend/src/services/integration/integration-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { TIntegrationAuthDALFactory } from "../integration-auth/integration-auth
import { TIntegrationAuthServiceFactory } from "../integration-auth/integration-auth-service";
import { deleteIntegrationSecrets } from "../integration-auth/integration-delete-secret";
import { TKmsServiceFactory } from "../kms/kms-service";
import { KmsDataKey } from "../kms/kms-types";
import { TProjectBotServiceFactory } from "../project-bot/project-bot-service";
import { TSecretDALFactory } from "../secret/secret-dal";
import { TSecretQueueFactory } from "../secret/secret-queue";
Expand Down Expand Up @@ -237,6 +238,46 @@ export const integrationServiceFactory = ({
return { ...integration, envId: integration.environment.id };
};

const getIntegrationAWSIamRole = async ({ id, actor, actorAuthMethod, actorId, actorOrgId }: TGetIntegrationDTO) => {
const integration = await integrationDAL.findById(id);

if (!integration) {
throw new NotFoundError({
message: `Integration with ID '${id}' not found`
});
}

const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
integration?.projectId || "",
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);

const integrationAuth = await integrationAuthDAL.findById(integration.integrationAuthId);

const { decryptor: secretManagerDecryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.SecretManager,
projectId: integration.projectId
});
let awsIamRole;
if (integrationAuth.encryptedAwsAssumeIamRoleArn) {
const awsAssumeRoleArn = secretManagerDecryptor({
cipherTextBlob: Buffer.from(integrationAuth.encryptedAwsAssumeIamRoleArn)
}).toString();
if (awsAssumeRoleArn) {
const [, role] = awsAssumeRoleArn.split(":role/");
awsIamRole = role;
}
}

return {
role: awsIamRole
};
};

const deleteIntegration = async ({
actorId,
id,
Expand Down Expand Up @@ -329,6 +370,7 @@ export const integrationServiceFactory = ({
deleteIntegration,
listIntegrationByProject,
getIntegration,
getIntegrationAWSAssumeRoleArn: getIntegrationAWSIamRole,
syncIntegration
};
};
3 changes: 3 additions & 0 deletions frontend/src/hooks/api/integrations/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ export type TIntegration = {
shouldMaskSecrets?: boolean;
shouldProtectSecrets?: boolean;
shouldEnableDelete?: boolean;

awsIamRole?: string;
awsRegion?: string;
};
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ const metadataMappings: Record<keyof NonNullable<TIntegrationWithEnv["metadata"]
shouldDisableDelete: "AWS Secret Deletion Disabled",
shouldMaskSecrets: "GitLab Secrets Masking Enabled",
shouldProtectSecrets: "GitLab Secret Protection Enabled",
shouldEnableDelete: "GitHub Secret Deletion Enabled"
shouldEnableDelete: "GitHub Secret Deletion Enabled",
awsIamRole: "AWS IAM Role",
awsRegion: "AWS Region"
} as const;

export const IntegrationSettingsSection = ({ integration }: Props) => {
Expand Down

0 comments on commit aec770d

Please sign in to comment.