mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 08:27:36 +00:00
misc: addressed comments
This commit is contained in:
+4
-4
@@ -3,17 +3,17 @@ import { Knex } from "knex";
|
||||
import { TableName } from "../schemas";
|
||||
|
||||
export async function up(knex: Knex): Promise<void> {
|
||||
if (!(await knex.schema.hasColumn(TableName.Project, "secretDetectionIgnoreKeys"))) {
|
||||
if (!(await knex.schema.hasColumn(TableName.Project, "secretDetectionIgnoreValues"))) {
|
||||
await knex.schema.alterTable(TableName.Project, (t) => {
|
||||
t.specificType("secretDetectionIgnoreKeys", "text[]");
|
||||
t.specificType("secretDetectionIgnoreValues", "text[]");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export async function down(knex: Knex): Promise<void> {
|
||||
if (await knex.schema.hasColumn(TableName.Project, "secretDetectionIgnoreKeys")) {
|
||||
if (await knex.schema.hasColumn(TableName.Project, "secretDetectionIgnoreValues")) {
|
||||
await knex.schema.alterTable(TableName.Project, (t) => {
|
||||
t.dropColumn("secretDetectionIgnoreKeys");
|
||||
t.dropColumn("secretDetectionIgnoreValues");
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,7 @@ export const ProjectsSchema = z.object({
|
||||
secretSharing: z.boolean().default(true),
|
||||
showSnapshotsLegacy: z.boolean().default(false),
|
||||
defaultProduct: z.string().nullable().optional(),
|
||||
secretDetectionIgnoreKeys: z.string().array().nullable().optional()
|
||||
secretDetectionIgnoreValues: z.string().array().nullable().optional()
|
||||
});
|
||||
|
||||
export type TProjects = z.infer<typeof ProjectsSchema>;
|
||||
|
||||
@@ -1410,6 +1410,7 @@ export const secretApprovalRequestServiceFactory = ({
|
||||
|
||||
const project = await projectDAL.findById(projectId);
|
||||
await scanSecretPolicyViolations(
|
||||
projectId,
|
||||
secretPath,
|
||||
[
|
||||
...(data[SecretOperations.Create] || []),
|
||||
@@ -1418,7 +1419,7 @@ export const secretApprovalRequestServiceFactory = ({
|
||||
secretKey: el.secretKey,
|
||||
secretValue: el.secretValue as string
|
||||
})),
|
||||
project.secretDetectionIgnoreKeys || []
|
||||
project.secretDetectionIgnoreValues || []
|
||||
);
|
||||
|
||||
// for created secret approval change
|
||||
|
||||
@@ -165,28 +165,29 @@ export const parseScanErrorMessage = (err: unknown): string => {
|
||||
};
|
||||
|
||||
export const scanSecretPolicyViolations = async (
|
||||
projectId: string,
|
||||
secretPath: string,
|
||||
secrets: { secretKey: string; secretValue: string }[],
|
||||
ignoreKeys: string[]
|
||||
ignoreValues: string[]
|
||||
) => {
|
||||
const appCfg = getConfig();
|
||||
|
||||
if (!appCfg.PARAMS_FOLDER_SECRET_DETECTION_ENABLED) {
|
||||
return;
|
||||
}
|
||||
const paramFolderSecretDetectionPaths = appCfg.PARAMS_FOLDER_SECRET_DETECTION_PATHS?.map((el) => el.secretPath) ?? [];
|
||||
const isPathMatched = paramFolderSecretDetectionPaths.some((pattern) =>
|
||||
picomatch.isMatch(secretPath, pattern, { strictSlashes: false })
|
||||
|
||||
const match = appCfg.PARAMS_FOLDER_SECRET_DETECTION_PATHS?.find(
|
||||
(el) => el.projectId === projectId && picomatch.isMatch(secretPath, el.secretPath, { strictSlashes: false })
|
||||
);
|
||||
|
||||
if (!isPathMatched) {
|
||||
if (!match) {
|
||||
return;
|
||||
}
|
||||
|
||||
const tempFolder = await createTempFolder();
|
||||
try {
|
||||
const scanPromises = secrets
|
||||
.filter((secret) => !ignoreKeys.includes(secret.secretKey))
|
||||
.filter((secret) => !ignoreValues.includes(secret.secretValue))
|
||||
.map(async (secret) => {
|
||||
const secretFilePath = join(tempFolder, `${crypto.nativeCrypto.randomUUID()}.txt`);
|
||||
await writeTextToFile(secretFilePath, `${secret.secretKey}=${secret.secretValue}`);
|
||||
|
||||
@@ -705,7 +705,7 @@ export const PROJECTS = {
|
||||
secretSharing: "Enable or disable secret sharing for the project.",
|
||||
showSnapshotsLegacy: "Enable or disable legacy snapshots for the project.",
|
||||
defaultProduct: "The default product in which the project will open",
|
||||
secretDetectionIgnoreKeys: "The list of secret keys to ignore for secret detection."
|
||||
secretDetectionIgnoreValues: "The list of secret values to ignore for secret detection."
|
||||
},
|
||||
GET_KEY: {
|
||||
workspaceId: "The ID of the project to get the key from."
|
||||
|
||||
@@ -211,10 +211,9 @@ const envSchema = z
|
||||
.optional()
|
||||
.transform((val) => {
|
||||
if (!val) return undefined;
|
||||
return JSON.parse(val) as { secretPath: string }[];
|
||||
return JSON.parse(val) as { secretPath: string; projectId: string }[];
|
||||
})
|
||||
),
|
||||
PARAMS_FOLDER_SECRET_DETECTION_ENABLED: zodStrBool.default("false"),
|
||||
|
||||
// HSM
|
||||
HSM_LIB_PATH: zpStr(z.string().optional()),
|
||||
@@ -353,7 +352,8 @@ const envSchema = z
|
||||
isHsmConfigured:
|
||||
Boolean(data.HSM_LIB_PATH) && Boolean(data.HSM_PIN) && Boolean(data.HSM_KEY_LABEL) && data.HSM_SLOT !== undefined,
|
||||
samlDefaultOrgSlug: data.DEFAULT_SAML_ORG_SLUG,
|
||||
SECRET_SCANNING_ORG_WHITELIST: data.SECRET_SCANNING_ORG_WHITELIST?.split(",")
|
||||
SECRET_SCANNING_ORG_WHITELIST: data.SECRET_SCANNING_ORG_WHITELIST?.split(","),
|
||||
PARAMS_FOLDER_SECRET_DETECTION_ENABLED: (data.PARAMS_FOLDER_SECRET_DETECTION_PATHS?.length ?? 0) > 0
|
||||
}));
|
||||
|
||||
export type TEnvConfig = Readonly<z.infer<typeof envSchema>>;
|
||||
|
||||
@@ -265,7 +265,7 @@ export const SanitizedProjectSchema = ProjectsSchema.pick({
|
||||
hasDeleteProtection: true,
|
||||
secretSharing: true,
|
||||
showSnapshotsLegacy: true,
|
||||
secretDetectionIgnoreKeys: true
|
||||
secretDetectionIgnoreValues: true
|
||||
});
|
||||
|
||||
export const SanitizedTagSchema = SecretTagsSchema.pick({
|
||||
|
||||
@@ -370,7 +370,10 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
|
||||
secretSharing: z.boolean().optional().describe(PROJECTS.UPDATE.secretSharing),
|
||||
showSnapshotsLegacy: z.boolean().optional().describe(PROJECTS.UPDATE.showSnapshotsLegacy),
|
||||
defaultProduct: z.nativeEnum(ProjectType).optional().describe(PROJECTS.UPDATE.defaultProduct),
|
||||
secretDetectionIgnoreKeys: z.array(z.string()).optional().describe(PROJECTS.UPDATE.secretDetectionIgnoreKeys)
|
||||
secretDetectionIgnoreValues: z
|
||||
.array(z.string())
|
||||
.optional()
|
||||
.describe(PROJECTS.UPDATE.secretDetectionIgnoreValues)
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
@@ -394,7 +397,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
|
||||
slug: req.body.slug,
|
||||
secretSharing: req.body.secretSharing,
|
||||
showSnapshotsLegacy: req.body.showSnapshotsLegacy,
|
||||
secretDetectionIgnoreKeys: req.body.secretDetectionIgnoreKeys
|
||||
secretDetectionIgnoreValues: req.body.secretDetectionIgnoreValues
|
||||
},
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorId: req.permission.id,
|
||||
|
||||
@@ -667,9 +667,9 @@ export const projectServiceFactory = ({
|
||||
}
|
||||
}
|
||||
|
||||
if (update.secretDetectionIgnoreKeys && !hasRole(ProjectMembershipRole.Admin)) {
|
||||
if (update.secretDetectionIgnoreValues && !hasRole(ProjectMembershipRole.Admin)) {
|
||||
throw new ForbiddenRequestError({
|
||||
message: "Only admins can update secret detection ignore keys"
|
||||
message: "Only admins can update secret detection ignore values"
|
||||
});
|
||||
}
|
||||
|
||||
@@ -683,7 +683,7 @@ export const projectServiceFactory = ({
|
||||
secretSharing: update.secretSharing,
|
||||
defaultProduct: update.defaultProduct,
|
||||
showSnapshotsLegacy: update.showSnapshotsLegacy,
|
||||
secretDetectionIgnoreKeys: update.secretDetectionIgnoreKeys
|
||||
secretDetectionIgnoreValues: update.secretDetectionIgnoreValues
|
||||
});
|
||||
|
||||
return updatedProject;
|
||||
|
||||
@@ -96,7 +96,7 @@ export type TUpdateProjectDTO = {
|
||||
slug?: string;
|
||||
secretSharing?: boolean;
|
||||
showSnapshotsLegacy?: boolean;
|
||||
secretDetectionIgnoreKeys?: string[];
|
||||
secretDetectionIgnoreValues?: string[];
|
||||
};
|
||||
} & Omit<TProjectPermission, "projectId">;
|
||||
|
||||
|
||||
@@ -301,6 +301,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
|
||||
const project = await projectDAL.findById(projectId);
|
||||
await scanSecretPolicyViolations(
|
||||
projectId,
|
||||
secretPath,
|
||||
[
|
||||
{
|
||||
@@ -308,7 +309,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
secretValue: inputSecret.secretValue
|
||||
}
|
||||
],
|
||||
project.secretDetectionIgnoreKeys || []
|
||||
project.secretDetectionIgnoreValues || []
|
||||
);
|
||||
|
||||
const { nestedReferences, localReferences } = getAllSecretReferences(inputSecret.secretValue);
|
||||
@@ -525,6 +526,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
if (secretValue) {
|
||||
const project = await projectDAL.findById(projectId);
|
||||
await scanSecretPolicyViolations(
|
||||
projectId,
|
||||
secretPath,
|
||||
[
|
||||
{
|
||||
@@ -532,7 +534,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
secretValue
|
||||
}
|
||||
],
|
||||
project.secretDetectionIgnoreKeys || []
|
||||
project.secretDetectionIgnoreValues || []
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1616,7 +1618,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
throw new BadRequestError({ message: `Secret already exist: ${secrets.map((el) => el.key).join(",")}` });
|
||||
|
||||
const project = await projectDAL.findById(projectId);
|
||||
await scanSecretPolicyViolations(secretPath, inputSecrets, project.secretDetectionIgnoreKeys || []);
|
||||
await scanSecretPolicyViolations(projectId, secretPath, inputSecrets, project.secretDetectionIgnoreValues || []);
|
||||
|
||||
// get all tags
|
||||
const sanitizedTagIds = inputSecrets.flatMap(({ tagIds = [] }) => tagIds);
|
||||
@@ -1960,6 +1962,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
|
||||
const project = await projectDAL.findById(projectId);
|
||||
await scanSecretPolicyViolations(
|
||||
projectId,
|
||||
secretPath,
|
||||
secretsToUpdate
|
||||
.filter((el) => el.secretValue)
|
||||
@@ -1967,7 +1970,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
secretKey: el.newSecretName || el.secretKey,
|
||||
secretValue: el.secretValue as string
|
||||
})),
|
||||
project.secretDetectionIgnoreKeys || []
|
||||
project.secretDetectionIgnoreValues || []
|
||||
);
|
||||
|
||||
const bulkUpdatedSecrets = await fnSecretBulkUpdate({
|
||||
|
||||
Reference in New Issue
Block a user