Merge pull request #1763 from Infisical/aws-sm-ps-check

Update implementation for AWS SM/PS integration KMS ID option
This commit is contained in:
Maidul Islam
2024-04-29 20:44:54 -04:00
committed by GitHub
6 changed files with 96 additions and 106 deletions

View File

@@ -566,20 +566,32 @@ export const integrationAuthServiceFactory = ({
}
});
const kms = new AWS.KMS();
const aliases = await kms.listAliases({}).promise();
const keys = await kms.listKeys({}).promise();
const response = keys
.Keys!.map((key) => {
const keyAlias = aliases.Aliases!.find((alias) => key.KeyId === alias.TargetKeyId);
if (!keyAlias?.AliasName?.includes("alias/aws/")) {
return { id: String(key.KeyId), alias: String(keyAlias?.AliasName || key.KeyId) };
}
return { id: "null", alias: "null" };
})
.filter((elem) => elem.id !== "null");
return [...response, { id: "null", alias: "default" }];
const keyAliases = aliases.Aliases!.filter((alias) => {
if (!alias.TargetKeyId) return false;
if (integrationAuth.integration === Integrations.AWS_PARAMETER_STORE && alias.AliasName === "alias/aws/ssm")
return true;
if (
integrationAuth.integration === Integrations.AWS_SECRET_MANAGER &&
alias.AliasName === "alias/aws/secretsmanager"
)
return true;
if (alias.AliasName?.includes("alias/aws/")) return false;
return alias.TargetKeyId;
});
const keysWithAliases = keyAliases.map((alias) => {
return {
id: alias.TargetKeyId!,
alias: alias.AliasName!
};
});
return keysWithAliases;
};
const getQoveryProjects = async ({

View File

@@ -489,7 +489,7 @@ const syncSecretsAWSParameterStore = async ({
Name: `${integration.path}${key}`,
Type: "SecureString",
Value: secrets[key].value,
KeyId: metadata.kmsKeyId ? metadata.kmsKeyId : undefined,
...(metadata.kmsKeyId && { KeyId: metadata.kmsKeyId }),
// Overwrite: true,
Tags: metadata.secretAWSTag
? metadata.secretAWSTag.map((tag: { key: string; value: string }) => ({
@@ -572,7 +572,6 @@ const syncSecretsAWSSecretManager = async ({
if (awsSecretManagerSecret?.SecretString) {
awsSecretManagerSecretObj = JSON.parse(awsSecretManagerSecret.SecretString);
}
if (!isEqual(awsSecretManagerSecretObj, secKeyVal)) {
await secretsManager.send(
new UpdateSecretCommand({
@@ -587,7 +586,7 @@ const syncSecretsAWSSecretManager = async ({
new CreateSecretCommand({
Name: integration.app as string,
SecretString: JSON.stringify(secKeyVal),
KmsKeyId: metadata.kmsKeyId ? metadata.kmsKeyId : null,
...(metadata.kmsKeyId && { KmsKeyId: metadata.kmsKeyId }),
Tags: metadata.secretAWSTag
? metadata.secretAWSTag.map((tag: { key: string; value: string }) => ({ Key: tag.key, Value: tag.value }))
: []

View File

@@ -31,7 +31,9 @@ Prerequisites:
"secretsmanager:UpdateSecret",
"secretsmanager:TagResource", // if you need to add tags to secrets
"kms:ListKeys", // if you need to specify the KMS key
"kms:ListAliases" // if you need to specify the KMS key
"kms:ListAliases", // if you need to specify the KMS key
"kms:Encrypt", // if you need to specify the KMS key
"kms:Decrypt" // if you need to specify the KMS key
],
"Resource": "*"
}

View File

@@ -48,10 +48,9 @@ const integrationAuthKeys = {
integrationAuthId,
region
}: {
integrationAuthId: string,
region: string
}) =>
[{ integrationAuthId, region }, "integrationAuthAwsKmsKeyIds"] as const,
integrationAuthId: string;
region: string;
}) => [{ integrationAuthId, region }, "integrationAuthAwsKmsKeyIds"] as const,
getIntegrationAuthQoveryOrgs: (integrationAuthId: string) =>
[{ integrationAuthId }, "integrationAuthQoveryOrgs"] as const,
getIntegrationAuthQoveryProjects: ({
@@ -226,27 +225,6 @@ const fetchIntegrationAuthQoveryOrgs = async (integrationAuthId: string) => {
return orgs;
};
const fetchIntegrationAuthAwsKmsKeys = async ({
integrationAuthId,
region
}: {
integrationAuthId: string;
region: string;
}) => {
const {
data: { kmsKeys }
} = await apiRequest.get<{ kmsKeys: KmsKey[] }>(
`/api/v1/integration-auth/${integrationAuthId}/aws-secrets-manager/kms-keys`,
{
params: {
region
}
}
);
return kmsKeys;
};
const fetchIntegrationAuthQoveryProjects = async ({
integrationAuthId,
orgId
@@ -586,11 +564,22 @@ export const useGetIntegrationAuthAwsKmsKeys = ({
integrationAuthId,
region
}),
queryFn: () =>
fetchIntegrationAuthAwsKmsKeys({
integrationAuthId,
region
}),
queryFn: async () => {
if (!region) return [];
const {
data: { kmsKeys }
} = await apiRequest.get<{ kmsKeys: KmsKey[] }>(
`/api/v1/integration-auth/${integrationAuthId}/aws-secrets-manager/kms-keys`,
{
params: {
region
}
}
);
return kmsKeys;
},
enabled: true
});
};

View File

@@ -100,19 +100,12 @@ export default function AWSParameterStoreCreateIntegrationPage() {
}
}, [workspace]);
const { data: integrationAuthAwsKmsKeys, isLoading: isIntegrationAuthAwsKmsKeysLoading } =
useGetIntegrationAuthAwsKmsKeys({
integrationAuthId: String(integrationAuthId),
integrationAuthId: String(integrationAuthId),
region: selectedAWSRegion
});
useEffect(() => {
if (integrationAuthAwsKmsKeys) {
setKmsKeyId(String(integrationAuthAwsKmsKeys?.filter(key => key.alias === "default")[0]?.id))
}
}, [integrationAuthAwsKmsKeys])
const isValidAWSParameterStorePath = (awsStorePath: string) => {
const pattern = /^\/([\w-]+\/)*[\w-]+\/$/;
return pattern.test(awsStorePath) && awsStorePath.length <= 2048;
@@ -143,16 +136,15 @@ export default function AWSParameterStoreCreateIntegrationPage() {
metadata: {
...(shouldTag
? {
secretAWSTag: [{
key: tagKey,
value: tagValue
}]
secretAWSTag: [
{
key: tagKey,
value: tagValue
}
]
}
: {}),
...((kmsKeyId && integrationAuthAwsKmsKeys?.filter(key => key.id === kmsKeyId)[0]?.alias !== "default") ?
{
kmsKeyId
}: {})
...(kmsKeyId && { kmsKeyId })
}
});
@@ -165,7 +157,10 @@ export default function AWSParameterStoreCreateIntegrationPage() {
}
};
return (integrationAuth && workspace && selectedSourceEnvironment && !isIntegrationAuthAwsKmsKeysLoading) ? (
return integrationAuth &&
workspace &&
selectedSourceEnvironment &&
!isIntegrationAuthAwsKmsKeysLoading ? (
<div className="flex h-full w-full flex-col items-center justify-center">
<Head>
<title>Set Up AWS Parameter Integration</title>
@@ -241,7 +236,10 @@ export default function AWSParameterStoreCreateIntegrationPage() {
<FormControl label="AWS Region">
<Select
value={selectedAWSRegion}
onValueChange={(val) => setSelectedAWSRegion(val)}
onValueChange={(val) => {
setSelectedAWSRegion(val);
setKmsKeyId("");
}}
className="w-full border border-mineshaft-500"
>
{awsRegions.map((awsRegion) => (
@@ -285,20 +283,16 @@ export default function AWSParameterStoreCreateIntegrationPage() {
</div>
{shouldTag && (
<div className="mt-4">
<FormControl
label="Tag Key"
>
<Input
placeholder="managed-by"
<FormControl label="Tag Key">
<Input
placeholder="managed-by"
value={tagKey}
onChange={(e) => setTagKey(e.target.value)}
/>
</FormControl>
<FormControl
label="Tag Value"
>
<Input
placeholder="infisical"
<FormControl label="Tag Value">
<Input
placeholder="infisical"
value={tagValue}
onChange={(e) => setTagValue(e.target.value)}
/>
@@ -309,7 +303,7 @@ export default function AWSParameterStoreCreateIntegrationPage() {
<Select
value={kmsKeyId}
onValueChange={(e) => {
setKmsKeyId(e)
setKmsKeyId(e);
}}
className="w-full border border-mineshaft-500"
>
@@ -362,7 +356,7 @@ export default function AWSParameterStoreCreateIntegrationPage() {
<title>Set Up AWS Parameter Store Integration</title>
<link rel="icon" href="/infisical.ico" />
</Head>
{(isintegrationAuthLoading || isIntegrationAuthAwsKmsKeysLoading) ? (
{isintegrationAuthLoading || isIntegrationAuthAwsKmsKeysLoading ? (
<img
src="/images/loading/loading.gif"
height={70}

View File

@@ -96,19 +96,12 @@ export default function AWSSecretManagerCreateIntegrationPage() {
const [isLoading, setIsLoading] = useState(false);
const [shouldTag, setShouldTag] = useState(false);
const { data: integrationAuthAwsKmsKeys, isLoading: isIntegrationAuthAwsKmsKeysLoading } =
useGetIntegrationAuthAwsKmsKeys({
integrationAuthId: String(integrationAuthId),
integrationAuthId: String(integrationAuthId),
region: selectedAWSRegion
});
useEffect(() => {
if (integrationAuthAwsKmsKeys) {
setKmsKeyId(String(integrationAuthAwsKmsKeys?.filter(key => key.alias === "alias/aws/secretsmanager")[0]?.id))
}
}, [integrationAuthAwsKmsKeys])
useEffect(() => {
if (workspace) {
setSelectedSourceEnvironment(workspace.environments[0].slug);
@@ -142,16 +135,15 @@ export default function AWSSecretManagerCreateIntegrationPage() {
metadata: {
...(shouldTag
? {
secretAWSTag: [{
key: tagKey,
value: tagValue
}]
secretAWSTag: [
{
key: tagKey,
value: tagValue
}
]
}
: {}),
...((kmsKeyId && integrationAuthAwsKmsKeys?.filter(key => key.id === kmsKeyId)[0]?.alias !== "default") ?
{
kmsKeyId
}: {})
...(kmsKeyId && { kmsKeyId })
}
});
@@ -164,7 +156,10 @@ export default function AWSSecretManagerCreateIntegrationPage() {
}
};
return (integrationAuth && workspace && selectedSourceEnvironment && !isIntegrationAuthAwsKmsKeysLoading) ? (
return integrationAuth &&
workspace &&
selectedSourceEnvironment &&
!isIntegrationAuthAwsKmsKeysLoading ? (
<div className="flex h-full w-full flex-col items-center justify-center">
<Head>
<title>Set Up AWS Secrets Manager Integration</title>
@@ -240,7 +235,10 @@ export default function AWSSecretManagerCreateIntegrationPage() {
<FormControl label="AWS Region">
<Select
value={selectedAWSRegion}
onValueChange={(val) => setSelectedAWSRegion(val)}
onValueChange={(val) => {
setSelectedAWSRegion(val);
setKmsKeyId("");
}}
className="w-full border border-mineshaft-500"
>
{awsRegions.map((awsRegion) => (
@@ -284,20 +282,16 @@ export default function AWSSecretManagerCreateIntegrationPage() {
</div>
{shouldTag && (
<div className="mt-4">
<FormControl
label="Tag Key"
>
<Input
placeholder="managed-by"
<FormControl label="Tag Key">
<Input
placeholder="managed-by"
value={tagKey}
onChange={(e) => setTagKey(e.target.value)}
/>
</FormControl>
<FormControl
label="Tag Value"
>
<Input
placeholder="infisical"
<FormControl label="Tag Value">
<Input
placeholder="infisical"
value={tagValue}
onChange={(e) => setTagValue(e.target.value)}
/>
@@ -308,7 +302,7 @@ export default function AWSSecretManagerCreateIntegrationPage() {
<Select
value={kmsKeyId}
onValueChange={(e) => {
setKmsKeyId(e)
setKmsKeyId(e);
}}
className="w-full border border-mineshaft-500"
>
@@ -361,7 +355,7 @@ export default function AWSSecretManagerCreateIntegrationPage() {
<title>Set Up AWS Secrets Manager Integration</title>
<link rel="icon" href="/infisical.ico" />
</Head>
{(isintegrationAuthLoading || isIntegrationAuthAwsKmsKeysLoading) ? (
{isintegrationAuthLoading || isIntegrationAuthAwsKmsKeysLoading ? (
<img
src="/images/loading/loading.gif"
height={70}