mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
PR fix suggestions for aws secret rotations
This commit is contained in:
@@ -8,7 +8,7 @@ export const AWS_IAM_USER_SECRET_ROTATION_LIST_OPTION: TSecretRotationV2ListItem
|
||||
connection: AppConnection.AWS,
|
||||
template: {
|
||||
secretsMapping: {
|
||||
accessKeyId: "AWS_ACCESS_KEY",
|
||||
accessKeyId: "AWS_ACCESS_KEY_ID",
|
||||
secretAccessKey: "AWS_SECRET_ACCESS_KEY"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ export const awsIamUserSecretRotationFactory: TRotationFactory<
|
||||
TAwsIamUserSecretRotationGeneratedCredentials
|
||||
> = (secretRotation) => {
|
||||
const {
|
||||
parameters: { region, clientName },
|
||||
parameters: { region, userName },
|
||||
connection,
|
||||
secretsMapping
|
||||
} = secretRotation;
|
||||
@@ -27,26 +27,29 @@ export const awsIamUserSecretRotationFactory: TRotationFactory<
|
||||
const { credentials } = await getAwsConnectionConfig(connection, region);
|
||||
const iam = new AWS.IAM({ credentials });
|
||||
|
||||
const { AccessKeyMetadata } = await iam.listAccessKeys({ UserName: clientName }).promise();
|
||||
const { AccessKeyMetadata } = await iam.listAccessKeys({ UserName: userName }).promise();
|
||||
|
||||
if (AccessKeyMetadata && AccessKeyMetadata.length > 0) {
|
||||
for (const key of AccessKeyMetadata) {
|
||||
if (key.Status === "Inactive" && key.AccessKeyId) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await iam
|
||||
.deleteAccessKey({
|
||||
UserName: clientName,
|
||||
AccessKeyId: key.AccessKeyId
|
||||
})
|
||||
.promise();
|
||||
}
|
||||
}
|
||||
// Delete inactive keys
|
||||
await Promise.all(
|
||||
AccessKeyMetadata.map((key) => {
|
||||
if (key.Status === "Inactive" && key.AccessKeyId) {
|
||||
return iam
|
||||
.deleteAccessKey({
|
||||
UserName: userName,
|
||||
AccessKeyId: key.AccessKeyId
|
||||
})
|
||||
.promise();
|
||||
}
|
||||
return Promise.resolve();
|
||||
})
|
||||
);
|
||||
|
||||
const activeKey = AccessKeyMetadata.find((k) => k.Status === "Active");
|
||||
if (activeKey && activeKey.AccessKeyId) {
|
||||
await iam
|
||||
.updateAccessKey({
|
||||
UserName: clientName,
|
||||
UserName: userName,
|
||||
AccessKeyId: activeKey.AccessKeyId,
|
||||
Status: "Inactive"
|
||||
})
|
||||
@@ -54,7 +57,7 @@ export const awsIamUserSecretRotationFactory: TRotationFactory<
|
||||
}
|
||||
}
|
||||
|
||||
const { AccessKey } = await iam.createAccessKey({ UserName: clientName }).promise();
|
||||
const { AccessKey } = await iam.createAccessKey({ UserName: userName }).promise();
|
||||
|
||||
return {
|
||||
accessKeyId: AccessKey.AccessKeyId,
|
||||
@@ -77,15 +80,16 @@ export const awsIamUserSecretRotationFactory: TRotationFactory<
|
||||
const { credentials } = await getAwsConnectionConfig(connection, region);
|
||||
const iam = new AWS.IAM({ credentials });
|
||||
|
||||
for (const generatedCredential of generatedCredentials) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await iam
|
||||
.deleteAccessKey({
|
||||
UserName: clientName,
|
||||
AccessKeyId: generatedCredential.accessKeyId
|
||||
})
|
||||
.promise();
|
||||
}
|
||||
await Promise.all(
|
||||
generatedCredentials.map((generatedCredential) =>
|
||||
iam
|
||||
.deleteAccessKey({
|
||||
UserName: userName,
|
||||
AccessKeyId: generatedCredential.accessKeyId
|
||||
})
|
||||
.promise()
|
||||
)
|
||||
);
|
||||
|
||||
return callback();
|
||||
};
|
||||
|
||||
@@ -20,11 +20,11 @@ export const AwsIamUserSecretRotationGeneratedCredentialsSchema = z
|
||||
.max(2);
|
||||
|
||||
const AwsIamUserSecretRotationParametersSchema = z.object({
|
||||
clientName: z
|
||||
userName: z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1, "Client Name Required")
|
||||
.describe(SecretRotations.PARAMETERS.AWS_IAM_USER_SECRET.clientName),
|
||||
.describe(SecretRotations.PARAMETERS.AWS_IAM_USER_SECRET.userName),
|
||||
region: z.nativeEnum(AWSRegion).describe(SecretRotations.PARAMETERS.AWS_IAM_USER_SECRET.region)
|
||||
});
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { AppConnection } from "@app/services/app-connection/app-connection-enums
|
||||
|
||||
export const SECRET_ROTATION_NAME_MAP: Record<SecretRotation, string> = {
|
||||
[SecretRotation.PostgresCredentials]: "PostgreSQL Credentials",
|
||||
[SecretRotation.MsSqlCredentials]: "Microsoft SQL Sever Credentials",
|
||||
[SecretRotation.MsSqlCredentials]: "Microsoft SQL Server Credentials",
|
||||
[SecretRotation.Auth0ClientSecret]: "Auth0 Client Secret",
|
||||
[SecretRotation.AwsIamUserSecret]: "AWS IAM User Secret"
|
||||
};
|
||||
|
||||
@@ -2017,7 +2017,7 @@ export const SecretRotations = {
|
||||
clientId: "The client ID of the Auth0 Application to rotate the client secret for."
|
||||
},
|
||||
AWS_IAM_USER_SECRET: {
|
||||
clientName: "The name of the client to rotate credentials for.",
|
||||
userName: "The name of the client to rotate credentials for.",
|
||||
region: "The AWS region to rotate credentials for."
|
||||
}
|
||||
},
|
||||
|
||||
@@ -69,7 +69,17 @@ export const registerAwsConnectionRouter = async (server: FastifyZodProvider) =>
|
||||
schema: {
|
||||
params: z.object({
|
||||
connectionId: z.string().uuid()
|
||||
})
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
iamUsers: z
|
||||
.object({
|
||||
UserName: z.string(),
|
||||
Arn: z.string()
|
||||
})
|
||||
.array()
|
||||
})
|
||||
}
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT]),
|
||||
handler: async (req) => {
|
||||
|
||||
@@ -78,9 +78,16 @@ const listAwsIamUsers = async (appConnection: TAwsConnection) => {
|
||||
|
||||
const iam = new AWS.IAM({ credentials });
|
||||
|
||||
const users = await iam.listUsers().promise();
|
||||
const userEntries: AWS.IAM.User[] = [];
|
||||
let userMarker: string | undefined;
|
||||
do {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
const response = await iam.listUsers({ MaxItems: 100, Marker: userMarker }).promise();
|
||||
userEntries.push(...(response.Users || []));
|
||||
userMarker = response.Marker;
|
||||
} while (userMarker);
|
||||
|
||||
return users.Users;
|
||||
return userEntries;
|
||||
};
|
||||
|
||||
export const awsConnectionService = (getAppConnection: TGetAppConnectionFunc) => {
|
||||
|
||||
@@ -114,7 +114,7 @@ In the following steps, we explore the end-to-end workflow for setting up this s
|
||||
"minutes": 29.5
|
||||
},
|
||||
"parameters": {
|
||||
"clientName": "<string>",
|
||||
"userName": "<string>",
|
||||
"region": "us-east-1"
|
||||
},
|
||||
"secretsMapping": {
|
||||
@@ -171,7 +171,7 @@ In the following steps, we explore the end-to-end workflow for setting up this s
|
||||
"lastRotationMessage": "<string>",
|
||||
"type": "aws-iam-user-secret",
|
||||
"parameters": {
|
||||
"clientName": "<string>",
|
||||
"userName": "<string>",
|
||||
"region": "us-east-1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ export const AwsIamUserSecretRotationParametersFields = () => {
|
||||
return (
|
||||
<>
|
||||
<Controller
|
||||
name="parameters.clientName"
|
||||
name="parameters.userName"
|
||||
control={control}
|
||||
render={({ field: { value, onChange }, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
@@ -70,13 +70,13 @@ export const AwsIamUserSecretRotationParametersFields = () => {
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
control={control}
|
||||
name="parameters.region"
|
||||
render={({ field: { value, onChange }, fieldState: { error } }) => (
|
||||
<FormControl isError={Boolean(error)} errorText={error?.message} label="Region">
|
||||
<AwsRegionSelect value={value} onChange={onChange} />
|
||||
</FormControl>
|
||||
)}
|
||||
control={control}
|
||||
name="parameters.region"
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -19,11 +19,11 @@ export const AwsIamUserSecretRotationReviewFields = () => {
|
||||
<>
|
||||
<SecretRotationReviewSection label="Parameters">
|
||||
<GenericFieldLabel label="Region">{parameters.region}</GenericFieldLabel>
|
||||
<GenericFieldLabel label="User Name">{parameters.clientName}</GenericFieldLabel>
|
||||
<GenericFieldLabel label="User Name">{parameters.userName}</GenericFieldLabel>
|
||||
</SecretRotationReviewSection>
|
||||
<SecretRotationReviewSection label="Secrets Mapping">
|
||||
<GenericFieldLabel label="Access Key ID">{accessKeyId}</GenericFieldLabel>
|
||||
<GenericFieldLabel label="Access Key Secret">{secretAccessKey}</GenericFieldLabel>
|
||||
<GenericFieldLabel label="Secret Access Key ID">{accessKeyId}</GenericFieldLabel>
|
||||
<GenericFieldLabel label="Secret Access Key">{secretAccessKey}</GenericFieldLabel>
|
||||
</SecretRotationReviewSection>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -35,7 +35,7 @@ export const AwsIamUserSecretRotationSecretsMappingFields = () => {
|
||||
)
|
||||
},
|
||||
{
|
||||
name: "Client Secret",
|
||||
name: "Secret Access Key",
|
||||
input: (
|
||||
<Controller
|
||||
render={({ field: { value, onChange }, fieldState: { error } }) => (
|
||||
|
||||
@@ -7,7 +7,7 @@ export const AwsIamUserSecretRotationSchema = z
|
||||
.object({
|
||||
type: z.literal(SecretRotation.AwsIamUserSecret),
|
||||
parameters: z.object({
|
||||
clientName: z.string().trim().min(1, "Client Name required"),
|
||||
userName: z.string().trim().min(1, "User Name required"),
|
||||
region: z.string().trim().min(1, "Region required")
|
||||
}),
|
||||
secretsMapping: z.object({
|
||||
|
||||
@@ -28,7 +28,4 @@ export type TAwsConnectionListIamUsersResponse = {
|
||||
iamUsers: TAwsConnectionIamUser[];
|
||||
};
|
||||
|
||||
export type TAwsIamUserSecret = {
|
||||
arn: string;
|
||||
UserName: string;
|
||||
};
|
||||
export type TAwsIamUserSecret = TAwsConnectionIamUser;
|
||||
|
||||
@@ -9,7 +9,7 @@ export type TAwsIamUserSecretRotation = TSecretRotationV2Base & {
|
||||
type: SecretRotation.AwsIamUserSecret;
|
||||
parameters: {
|
||||
region: string;
|
||||
clientName: string;
|
||||
userName: string;
|
||||
};
|
||||
secretsMapping: {
|
||||
accessKeyId: string;
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
TAwsIamUserSecretRotation,
|
||||
TAwsIamUserSecretRotationGeneratedCredentialsResponse,
|
||||
TAwsIamUserSecretRotationOption
|
||||
} from "@app/hooks/api/secretRotationsV2/types/aws-iam-access-key-rotation";
|
||||
} from "@app/hooks/api/secretRotationsV2/types/aws-iam-user-secret-rotation";
|
||||
import {
|
||||
TMsSqlCredentialsRotation,
|
||||
TMsSqlCredentialsRotationGeneratedCredentialsResponse
|
||||
|
||||
Reference in New Issue
Block a user