mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 04:27:29 +00:00
Remove assume role from IRSA
This commit is contained in:
@@ -34,6 +34,7 @@ ARG INFISICAL_PLATFORM_VERSION
|
|||||||
ENV VITE_INFISICAL_PLATFORM_VERSION $INFISICAL_PLATFORM_VERSION
|
ENV VITE_INFISICAL_PLATFORM_VERSION $INFISICAL_PLATFORM_VERSION
|
||||||
ARG CAPTCHA_SITE_KEY
|
ARG CAPTCHA_SITE_KEY
|
||||||
ENV VITE_CAPTCHA_SITE_KEY $CAPTCHA_SITE_KEY
|
ENV VITE_CAPTCHA_SITE_KEY $CAPTCHA_SITE_KEY
|
||||||
|
ENV NODE_OPTIONS="--max-old-space-size=8192"
|
||||||
|
|
||||||
# Build
|
# Build
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
@@ -77,6 +78,7 @@ RUN npm ci --only-production
|
|||||||
COPY /backend .
|
COPY /backend .
|
||||||
COPY --chown=non-root-user:nodejs standalone-entrypoint.sh standalone-entrypoint.sh
|
COPY --chown=non-root-user:nodejs standalone-entrypoint.sh standalone-entrypoint.sh
|
||||||
RUN npm i -D tsconfig-paths
|
RUN npm i -D tsconfig-paths
|
||||||
|
ENV NODE_OPTIONS="--max-old-space-size=8192"
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
# Production stage
|
# Production stage
|
||||||
|
|||||||
@@ -16,9 +16,8 @@ import {
|
|||||||
PutUserPolicyCommand,
|
PutUserPolicyCommand,
|
||||||
RemoveUserFromGroupCommand
|
RemoveUserFromGroupCommand
|
||||||
} from "@aws-sdk/client-iam";
|
} from "@aws-sdk/client-iam";
|
||||||
import { AssumeRoleCommand, AssumeRoleWithWebIdentityCommand, STSClient } from "@aws-sdk/client-sts";
|
import { AssumeRoleCommand, STSClient } from "@aws-sdk/client-sts";
|
||||||
import { randomUUID } from "crypto";
|
import { randomUUID } from "crypto";
|
||||||
import { promises as fs } from "fs";
|
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
@@ -90,42 +89,9 @@ export const AwsIamProvider = (): TDynamicProviderFns => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const tokenFilePath =
|
// The SDK will automatically pick up credentials from the environment
|
||||||
appCfg.INFISICAL_KUBERNETES_SERVICE_ACCOUNT_TOKEN_PATH || "/var/run/secrets/kubernetes.io/serviceaccount/token";
|
|
||||||
|
|
||||||
let webIdentityToken;
|
|
||||||
try {
|
|
||||||
webIdentityToken = await fs.readFile(tokenFilePath, "utf-8");
|
|
||||||
} catch (error) {
|
|
||||||
throw new BadRequestError({
|
|
||||||
message: `Failed to get AWS credentials via IRSA: service account token not found at ${tokenFilePath}`
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const stsClient = new STSClient({
|
|
||||||
region: providerInputs.region
|
|
||||||
});
|
|
||||||
|
|
||||||
const command = new AssumeRoleWithWebIdentityCommand({
|
|
||||||
RoleArn: providerInputs.roleArn,
|
|
||||||
RoleSessionName: `infisical-dynamic-secret-irsa-${randomUUID()}`,
|
|
||||||
WebIdentityToken: webIdentityToken,
|
|
||||||
DurationSeconds: 900 // 15 mins
|
|
||||||
});
|
|
||||||
|
|
||||||
const assumeRes = await stsClient.send(command);
|
|
||||||
|
|
||||||
if (!assumeRes.Credentials?.AccessKeyId || !assumeRes.Credentials?.SecretAccessKey) {
|
|
||||||
throw new BadRequestError({ message: "Failed to assume role with web identity - verify IRSA configuration" });
|
|
||||||
}
|
|
||||||
|
|
||||||
const client = new IAMClient({
|
const client = new IAMClient({
|
||||||
region: providerInputs.region,
|
region: providerInputs.region
|
||||||
credentials: {
|
|
||||||
accessKeyId: assumeRes.Credentials.AccessKeyId,
|
|
||||||
secretAccessKey: assumeRes.Credentials.SecretAccessKey,
|
|
||||||
sessionToken: assumeRes.Credentials.SessionToken
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -225,7 +225,6 @@ export const DynamicSecretAwsIamSchema = z.preprocess(
|
|||||||
}),
|
}),
|
||||||
z.object({
|
z.object({
|
||||||
method: z.literal(AwsIamAuthType.IRSA),
|
method: z.literal(AwsIamAuthType.IRSA),
|
||||||
roleArn: z.string().trim().min(1, "Role ARN required"),
|
|
||||||
region: z.string().trim().min(1),
|
region: z.string().trim().min(1),
|
||||||
awsPath: z.string().trim().optional(),
|
awsPath: z.string().trim().optional(),
|
||||||
permissionBoundaryPolicyArn: z.string().trim().optional(),
|
permissionBoundaryPolicyArn: z.string().trim().optional(),
|
||||||
|
|||||||
@@ -115,7 +115,6 @@ export type TDynamicSecretProvider =
|
|||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
method: DynamicSecretAwsIamAuth.IRSA;
|
method: DynamicSecretAwsIamAuth.IRSA;
|
||||||
roleArn: string;
|
|
||||||
region: string;
|
region: string;
|
||||||
awsPath?: string;
|
awsPath?: string;
|
||||||
policyDocument?: string;
|
policyDocument?: string;
|
||||||
|
|||||||
+5
-9
@@ -14,8 +14,8 @@ import {
|
|||||||
SelectItem,
|
SelectItem,
|
||||||
TextArea
|
TextArea
|
||||||
} from "@app/components/v2";
|
} from "@app/components/v2";
|
||||||
import { useGetServerConfig } from "@app/hooks/api/admin";
|
|
||||||
import { useCreateDynamicSecret } from "@app/hooks/api";
|
import { useCreateDynamicSecret } from "@app/hooks/api";
|
||||||
|
import { useGetServerConfig } from "@app/hooks/api/admin";
|
||||||
import {
|
import {
|
||||||
DynamicSecretAwsIamAuth,
|
DynamicSecretAwsIamAuth,
|
||||||
DynamicSecretProviders
|
DynamicSecretProviders
|
||||||
@@ -65,7 +65,6 @@ const formSchema = z.object({
|
|||||||
}),
|
}),
|
||||||
z.object({
|
z.object({
|
||||||
method: z.literal(DynamicSecretAwsIamAuth.IRSA),
|
method: z.literal(DynamicSecretAwsIamAuth.IRSA),
|
||||||
roleArn: z.string().trim().min(1),
|
|
||||||
region: z.string().trim().min(1),
|
region: z.string().trim().min(1),
|
||||||
awsPath: z.string().trim().optional(),
|
awsPath: z.string().trim().optional(),
|
||||||
permissionBoundaryPolicyArn: z.string().trim().optional(),
|
permissionBoundaryPolicyArn: z.string().trim().optional(),
|
||||||
@@ -265,7 +264,7 @@ export const AwsIamInputForm = ({
|
|||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
{method === DynamicSecretAwsIamAuth.AccessKey ? (
|
{method === DynamicSecretAwsIamAuth.AccessKey && (
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
@@ -298,7 +297,8 @@ export const AwsIamInputForm = ({
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
)}
|
||||||
|
{method === DynamicSecretAwsIamAuth.AssumeRole && (
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
@@ -306,11 +306,7 @@ export const AwsIamInputForm = ({
|
|||||||
defaultValue=""
|
defaultValue=""
|
||||||
render={({ field, fieldState: { error } }) => (
|
render={({ field, fieldState: { error } }) => (
|
||||||
<FormControl
|
<FormControl
|
||||||
label={
|
label="Assume Role ARN"
|
||||||
method === DynamicSecretAwsIamAuth.AssumeRole
|
|
||||||
? "Assume Role ARN"
|
|
||||||
: "Role ARN"
|
|
||||||
}
|
|
||||||
className="flex-grow"
|
className="flex-grow"
|
||||||
isError={Boolean(error?.message)}
|
isError={Boolean(error?.message)}
|
||||||
errorText={error?.message}
|
errorText={error?.message}
|
||||||
|
|||||||
+4
-7
@@ -235,7 +235,7 @@ export const EditDynamicSecretAwsIamForm = ({
|
|||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
{method === DynamicSecretAwsIamAuth.AccessKey ? (
|
{method === DynamicSecretAwsIamAuth.AccessKey && (
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
@@ -268,7 +268,8 @@ export const EditDynamicSecretAwsIamForm = ({
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
)}
|
||||||
|
{method === DynamicSecretAwsIamAuth.AssumeRole && (
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
@@ -276,11 +277,7 @@ export const EditDynamicSecretAwsIamForm = ({
|
|||||||
defaultValue=""
|
defaultValue=""
|
||||||
render={({ field, fieldState: { error } }) => (
|
render={({ field, fieldState: { error } }) => (
|
||||||
<FormControl
|
<FormControl
|
||||||
label={
|
label="Assume Role ARN"
|
||||||
method === DynamicSecretAwsIamAuth.AssumeRole
|
|
||||||
? "Assume Role ARN"
|
|
||||||
: "Role ARN"
|
|
||||||
}
|
|
||||||
className="flex-grow"
|
className="flex-grow"
|
||||||
isError={Boolean(error?.message)}
|
isError={Boolean(error?.message)}
|
||||||
errorText={error?.message}
|
errorText={error?.message}
|
||||||
|
|||||||
Reference in New Issue
Block a user