feat: update AWS IAM session duration handling and improve account access functionality

- Changed session duration parameter from maxSessionDuration to defaultSessionDuration for consistency.
- Refactored AWS STS client creation to use a hardcoded default region, simplifying the configuration.
- Enhanced PAM account access modal to include account path and project ID in the access request.
- Updated various components and schemas to reflect the new session duration naming and improve type safety.
This commit is contained in:
Victor Santos
2025-12-05 16:56:55 -03:00
parent feb1d9b854
commit 6db5188b36
11 changed files with 207 additions and 308 deletions
@@ -591,7 +591,7 @@ export const pamAccountServiceFactory = ({
targetRoleArn: awsCredentials.targetRoleArn,
roleSessionName: actorEmail,
projectId: account.projectId, // Use project ID as External ID for security
sessionDuration: awsCredentials.maxSessionDuration
sessionDuration: awsCredentials.defaultSessionDuration
});
const session = await pamSessionDAL.create({
@@ -8,11 +8,17 @@ import { TAwsIamResourceConnectionDetails } from "./aws-iam-resource-types";
const AWS_STS_MIN_DURATION_SECONDS = 900;
const createStsClient = (region: string): STSClient => {
// We hardcode us-east-1 because:
// 1. IAM is global - roles can be assumed from any STS regional endpoint
// 2. The temporary credentials returned work globally across all AWS regions
// 3. The target account's resources can be in any region - it doesn't affect STS calls
const AWS_STS_DEFAULT_REGION = "us-east-1";
const createStsClient = (): STSClient => {
const appCfg = getConfig();
const config: STSClientConfig = {
region,
region: AWS_STS_DEFAULT_REGION,
useFipsEndpoint: crypto.isFipsModeEnabled(),
sha256: CustomAWSHasher,
credentials:
@@ -31,7 +37,7 @@ export const validatePamRoleConnection = async (
connectionDetails: TAwsIamResourceConnectionDetails,
projectId: string
): Promise<boolean> => {
const stsClient = createStsClient(connectionDetails.region);
const stsClient = createStsClient();
try {
await stsClient.send(
@@ -58,7 +64,7 @@ export const validateTargetRoleAssumption = async ({
targetRoleArn: string;
projectId: string;
}): Promise<boolean> => {
const stsClient = createStsClient(connectionDetails.region);
const stsClient = createStsClient();
try {
// First assume the PAM role
@@ -77,7 +83,7 @@ export const validateTargetRoleAssumption = async ({
// Then use the PAM role credentials to assume the target role
const pamStsClient = new STSClient({
region: connectionDetails.region,
region: AWS_STS_DEFAULT_REGION,
useFipsEndpoint: crypto.isFipsModeEnabled(),
sha256: CustomAWSHasher,
credentials: {
@@ -118,7 +124,7 @@ export const generateConsoleFederationUrl = async ({
projectId: string;
sessionDuration: number;
}): Promise<{ consoleUrl: string; expiresAt: Date }> => {
const stsClient = createStsClient(connectionDetails.region);
const stsClient = createStsClient();
// First assume the PAM role
const pamRoleCredentials = await stsClient.send(
@@ -136,7 +142,7 @@ export const generateConsoleFederationUrl = async ({
// Role chaining: use PAM role credentials to assume the target role
const pamStsClient = new STSClient({
region: connectionDetails.region,
region: AWS_STS_DEFAULT_REGION,
useFipsEndpoint: crypto.isFipsModeEnabled(),
sha256: CustomAWSHasher,
credentials: {
@@ -32,7 +32,7 @@ export const awsIamResourceFactory: TPamResourceFactory<TAwsIamResourceConnectio
}
logger.info(
{ roleArn: connectionDetails.roleArn, region: connectionDetails.region },
{ roleArn: connectionDetails.roleArn },
"[AWS IAM Resource Factory] PAM role connection validated successfully"
);
@@ -18,13 +18,12 @@ const AWS_STS_MIN_SESSION_DURATION = 900; // 15 minutes
const AWS_STS_MAX_SESSION_DURATION_ROLE_CHAINING = 3600; // 1 hour
export const AwsIamResourceConnectionDetailsSchema = z.object({
region: z.string().trim().min(1),
roleArn: z.string().trim().min(1)
});
export const AwsIamAccountCredentialsSchema = z.object({
targetRoleArn: z.string().trim().min(1).max(2048),
maxSessionDuration: z.coerce
defaultSessionDuration: z.coerce
.number()
.min(AWS_STS_MIN_SESSION_DURATION)
.max(AWS_STS_MAX_SESSION_DURATION_ROLE_CHAINING)
@@ -79,6 +78,6 @@ export const UpdateAwsIamAccountSchema = BaseUpdatePamAccountSchema.extend({
export const SanitizedAwsIamAccountWithResourceSchema = BasePamAccountSchemaWithResource.extend({
credentials: AwsIamAccountCredentialsSchema.pick({
targetRoleArn: true,
maxSessionDuration: true
defaultSessionDuration: true
})
});