mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Address PR comments for Azure Client Secret Rotation
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import { AxiosError } from "axios";
|
||||
|
||||
import {
|
||||
AzureAddPasswordResponse,
|
||||
TAzureClientSecretRotationGeneratedCredentials,
|
||||
@@ -11,7 +13,7 @@ import {
|
||||
TRotationFactoryRotateCredentials
|
||||
} from "@app/ee/services/secret-rotation-v2/secret-rotation-v2-types";
|
||||
import { request } from "@app/lib/config/request";
|
||||
import { blockLocalAndPrivateIpAddresses } from "@app/lib/validator";
|
||||
import { BadRequestError } from "@app/lib/errors";
|
||||
import { getAzureConnectionAccessToken } from "@app/services/app-connection/azure-client-secrets";
|
||||
|
||||
const GRAPH_API_BASE = "https://graph.microsoft.com/v1.0";
|
||||
@@ -23,8 +25,7 @@ export const azureClientSecretRotationFactory: TRotationFactory<
|
||||
const {
|
||||
connection,
|
||||
parameters: { appId },
|
||||
secretsMapping,
|
||||
rotationInterval
|
||||
secretsMapping
|
||||
} = secretRotation;
|
||||
|
||||
/**
|
||||
@@ -34,11 +35,6 @@ export const azureClientSecretRotationFactory: TRotationFactory<
|
||||
const accessToken = await getAzureConnectionAccessToken(connection.id, appConnectionDAL, kmsService);
|
||||
const endpoint = `${GRAPH_API_BASE}/applications/${appId}/addPassword`;
|
||||
|
||||
await blockLocalAndPrivateIpAddresses(endpoint);
|
||||
|
||||
const endDateTime = new Date();
|
||||
endDateTime.setDate(endDateTime.getDate() + rotationInterval);
|
||||
|
||||
const now = new Date();
|
||||
const formattedDate = `${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(
|
||||
2,
|
||||
@@ -50,8 +46,7 @@ export const azureClientSecretRotationFactory: TRotationFactory<
|
||||
endpoint,
|
||||
{
|
||||
passwordCredential: {
|
||||
displayName: `Infisical Rotated Secret (${formattedDate})`,
|
||||
endDateTime: endDateTime.toISOString()
|
||||
displayName: `Infisical Rotated Secret (${formattedDate})`
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -70,9 +65,15 @@ export const azureClientSecretRotationFactory: TRotationFactory<
|
||||
clientSecret: data.secretText,
|
||||
clientId: data.keyId
|
||||
};
|
||||
} catch (err: unknown) {
|
||||
const message = err instanceof Error ? err.message : String(err);
|
||||
throw new Error(`Failed to add client secret to Azure app ${appId}: ${message}`);
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof AxiosError) {
|
||||
throw new BadRequestError({
|
||||
message: `Failed to add client secret to Azure app ${appId}: ${error.message || "Unknown error"}`
|
||||
});
|
||||
}
|
||||
throw new BadRequestError({
|
||||
message: "Unable to validate connection: verify credentials"
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -83,8 +84,6 @@ export const azureClientSecretRotationFactory: TRotationFactory<
|
||||
const accessToken = await getAzureConnectionAccessToken(connection.id, appConnectionDAL, kmsService);
|
||||
const endpoint = `${GRAPH_API_BASE}/applications/${appId}/removePassword`;
|
||||
|
||||
await blockLocalAndPrivateIpAddresses(endpoint);
|
||||
|
||||
try {
|
||||
await request.post(
|
||||
endpoint,
|
||||
@@ -96,9 +95,17 @@ export const azureClientSecretRotationFactory: TRotationFactory<
|
||||
}
|
||||
}
|
||||
);
|
||||
} catch (err: unknown) {
|
||||
const message = err instanceof Error ? err.message : String(err);
|
||||
throw new Error(`Failed to remove client secret with keyId ${clientId} from app ${appId}: ${message}`);
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof AxiosError) {
|
||||
throw new BadRequestError({
|
||||
message: `Failed to remove client secret with keyId ${clientId} from app ${appId}: ${
|
||||
error.message || "Unknown error"
|
||||
}`
|
||||
});
|
||||
}
|
||||
throw new BadRequestError({
|
||||
message: "Unable to validate connection: verify credentials"
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -21,11 +21,7 @@ export const AzureClientSecretRotationGeneratedCredentialsSchema = z
|
||||
|
||||
const AzureClientSecretRotationParametersSchema = z.object({
|
||||
appId: z.string().trim().min(1, "App ID Required").describe(SecretRotations.PARAMETERS.AZURE_CLIENT_SECRET.appId),
|
||||
appName: z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1, "App Name Required")
|
||||
.describe(SecretRotations.PARAMETERS.AZURE_CLIENT_SECRET.appName)
|
||||
appName: z.string().trim().describe(SecretRotations.PARAMETERS.AZURE_CLIENT_SECRET.appName).optional()
|
||||
});
|
||||
|
||||
const AzureClientSecretRotationSecretsMappingSchema = z.object({
|
||||
|
||||
@@ -1875,6 +1875,10 @@ export const AppConnections = {
|
||||
TEAMCITY: {
|
||||
instanceUrl: "The TeamCity instance URL to connect with.",
|
||||
accessToken: "The access token to use to connect with TeamCity."
|
||||
},
|
||||
AZURE_CLIENT_SECRETS: {
|
||||
code: "The OAuth code to use to connect with Azure Client Secrets.",
|
||||
tenantId: "The Tenant ID to use to connect with Azure Client Secrets."
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -11,12 +11,16 @@ import {
|
||||
import { AzureClientSecretsConnectionMethod } from "./azure-client-secrets-connection-enums";
|
||||
|
||||
export const AzureClientSecretsConnectionOAuthInputCredentialsSchema = z.object({
|
||||
code: z.string().trim().min(1, "OAuth code required"),
|
||||
tenantId: z.string().trim().optional()
|
||||
code: z.string().trim().min(1, "OAuth code required").describe(AppConnections.CREDENTIALS.AZURE_CLIENT_SECRETS.code),
|
||||
tenantId: z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1, "Tenant ID required")
|
||||
.describe(AppConnections.CREDENTIALS.AZURE_CLIENT_SECRETS.tenantId)
|
||||
});
|
||||
|
||||
export const AzureClientSecretsConnectionOAuthOutputCredentialsSchema = z.object({
|
||||
tenantId: z.string().optional(),
|
||||
tenantId: z.string(),
|
||||
accessToken: z.string(),
|
||||
refreshToken: z.string(),
|
||||
expiresAt: z.number()
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { request } from "@app/lib/config/request";
|
||||
import { OrgServiceActor } from "@app/lib/types";
|
||||
import { blockLocalAndPrivateIpAddresses } from "@app/lib/validator";
|
||||
import { TAppConnectionDALFactory } from "@app/services/app-connection/app-connection-dal";
|
||||
import { AppConnection } from "@app/services/app-connection/app-connection-enums";
|
||||
import { getAzureConnectionAccessToken } from "@app/services/app-connection/azure-client-secrets/azure-client-secrets-connection-fns";
|
||||
@@ -26,7 +25,6 @@ const listAzureRegisteredApps = async (
|
||||
const accessToken = await getAzureConnectionAccessToken(appConnection.id, appConnectionDAL, kmsService);
|
||||
|
||||
const graphEndpoint = `https://graph.microsoft.com/v1.0/applications`;
|
||||
await blockLocalAndPrivateIpAddresses(graphEndpoint);
|
||||
|
||||
const apps: TAzureRegisteredApp[] = [];
|
||||
let nextLink = graphEndpoint;
|
||||
|
||||
Reference in New Issue
Block a user