Compare commits

...

5 Commits

Author SHA1 Message Date
Carlos Monastyrski
b560cdb0f8 Improve reference error message 2025-07-17 11:56:27 -03:00
Carlos Monastyrski
0174d36136 Throw a meaningful error message when secret reference process fails 2025-07-16 22:41:08 -03:00
Carlos Monastyrski
59c0f1ff08 List secrets, throw when user does not have permission to read the referenced secret value 2025-07-16 09:14:06 -03:00
Daniel Hougaard
0e07ebae7b fix: oci auth for go sdk (#4152) 2025-07-16 16:36:28 +05:30
carlosmonastyrski
a94a26263a Merge pull request #4115 from Infisical/fix/postgresAppConnectionDocTip
Minor improvement on the Postgres docs changing a warning to a tip
2025-07-15 21:47:42 -03:00
7 changed files with 62 additions and 11 deletions

View File

@@ -28,7 +28,17 @@ export const registerIdentityOciAuthRouter = async (server: FastifyZodProvider)
.object({ .object({
authorization: z.string(), authorization: z.string(),
host: z.string(), host: z.string(),
"x-date": z.string() "x-date": z.string().optional(),
date: z.string().optional()
})
.superRefine((val, ctx) => {
if (!val.date && !val["x-date"]) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "Either date or x-date must be provided",
path: ["headers", "date"]
});
}
}) })
.describe(OCI_AUTH.LOGIN.headers) .describe(OCI_AUTH.LOGIN.headers)
}), }),

View File

@@ -6,7 +6,8 @@ export type TLoginOciAuthDTO = {
headers: { headers: {
authorization: string; authorization: string;
host: string; host: string;
"x-date": string; "x-date"?: string;
date?: string;
}; };
}; };

View File

@@ -174,6 +174,7 @@ export const fnSecretsV2FromImports = async ({
skipMultilineEncoding?: boolean | null; skipMultilineEncoding?: boolean | null;
secretPath: string; secretPath: string;
environment: string; environment: string;
secretKey: string;
}) => Promise<string | undefined>; }) => Promise<string | undefined>;
hasSecretAccess: (environment: string, secretPath: string, secretName: string, secretTagSlugs: string[]) => boolean; hasSecretAccess: (environment: string, secretPath: string, secretName: string, secretTagSlugs: string[]) => boolean;
}) => { }) => {
@@ -293,7 +294,8 @@ export const fnSecretsV2FromImports = async ({
value: decryptedSecret.secretValue, value: decryptedSecret.secretValue,
secretPath: processedImport.secretPath, secretPath: processedImport.secretPath,
environment: processedImport.environment, environment: processedImport.environment,
skipMultilineEncoding: decryptedSecret.skipMultilineEncoding skipMultilineEncoding: decryptedSecret.skipMultilineEncoding,
secretKey: decryptedSecret.secretKey
}); });
// eslint-disable-next-line no-param-reassign // eslint-disable-next-line no-param-reassign
processedImport.secrets[index].secretValue = expandedSecretValue || ""; processedImport.secrets[index].secretValue = expandedSecretValue || "";

View File

@@ -231,7 +231,8 @@ export const secretSyncQueueFactory = ({
environment: environment.slug, environment: environment.slug,
secretPath: folder.path, secretPath: folder.path,
skipMultilineEncoding: secret.skipMultilineEncoding, skipMultilineEncoding: secret.skipMultilineEncoding,
value: secretValue value: secretValue,
secretKey
}); });
secretMap[secretKey] = { value: expandedSecretValue || "" }; secretMap[secretKey] = { value: expandedSecretValue || "" };

View File

@@ -614,6 +614,7 @@ export const expandSecretReferencesFactory = ({
secretPath: string; secretPath: string;
environment: string; environment: string;
shouldStackTrace?: boolean; shouldStackTrace?: boolean;
secretKey: string;
}) => { }) => {
const stackTrace = { ...dto, key: "root", children: [] } as TSecretReferenceTraceNode; const stackTrace = { ...dto, key: "root", children: [] } as TSecretReferenceTraceNode;
@@ -656,7 +657,7 @@ export const expandSecretReferencesFactory = ({
const referredValue = await fetchSecret(environment, secretPath, secretKey); const referredValue = await fetchSecret(environment, secretPath, secretKey);
if (!canExpandValue(environment, secretPath, secretKey, referredValue.tags)) if (!canExpandValue(environment, secretPath, secretKey, referredValue.tags))
throw new ForbiddenRequestError({ throw new ForbiddenRequestError({
message: `You are attempting to reference secret named ${secretKey} from environment ${environment} in path ${secretPath} which you do not have access to read value on.` message: `You do not have permission to read secret '${secretKey}' in environment '${environment}' at path '${secretPath}', which is referenced by secret '${dto.secretKey}' in environment '${dto.environment}' at path '${dto.secretPath}'.`
}); });
const cacheKey = getCacheUniqueKey(environment, secretPath); const cacheKey = getCacheUniqueKey(environment, secretPath);
@@ -675,7 +676,7 @@ export const expandSecretReferencesFactory = ({
const referedValue = await fetchSecret(secretReferenceEnvironment, secretReferencePath, secretReferenceKey); const referedValue = await fetchSecret(secretReferenceEnvironment, secretReferencePath, secretReferenceKey);
if (!canExpandValue(secretReferenceEnvironment, secretReferencePath, secretReferenceKey, referedValue.tags)) if (!canExpandValue(secretReferenceEnvironment, secretReferencePath, secretReferenceKey, referedValue.tags))
throw new ForbiddenRequestError({ throw new ForbiddenRequestError({
message: `You are attempting to reference secret named ${secretReferenceKey} from environment ${secretReferenceEnvironment} in path ${secretReferencePath} which you do not have access to read value on.` message: `You do not have permission to read secret '${secretReferenceKey}' in environment '${secretReferenceEnvironment}' at path '${secretReferencePath}', which is referenced by secret '${dto.secretKey}' in environment '${dto.environment}' at path '${dto.secretPath}'.`
}); });
const cacheKey = getCacheUniqueKey(secretReferenceEnvironment, secretReferencePath); const cacheKey = getCacheUniqueKey(secretReferenceEnvironment, secretReferencePath);
@@ -692,6 +693,7 @@ export const expandSecretReferencesFactory = ({
secretPath: referencedSecretPath, secretPath: referencedSecretPath,
environment: referencedSecretEnvironmentSlug, environment: referencedSecretEnvironmentSlug,
depth: depth + 1, depth: depth + 1,
secretKey: referencedSecretKey,
trace trace
}; };
@@ -726,6 +728,7 @@ export const expandSecretReferencesFactory = ({
skipMultilineEncoding?: boolean | null; skipMultilineEncoding?: boolean | null;
secretPath: string; secretPath: string;
environment: string; environment: string;
secretKey: string;
}) => { }) => {
if (!inputSecret.value) return inputSecret.value; if (!inputSecret.value) return inputSecret.value;
@@ -741,6 +744,7 @@ export const expandSecretReferencesFactory = ({
value?: string; value?: string;
secretPath: string; secretPath: string;
environment: string; environment: string;
secretKey: string;
}) => { }) => {
const { stackTrace, expandedValue } = await recursivelyExpandSecret({ ...inputSecret, shouldStackTrace: true }); const { stackTrace, expandedValue } = await recursivelyExpandSecret({ ...inputSecret, shouldStackTrace: true });
return { stackTrace, expandedValue }; return { stackTrace, expandedValue };

View File

@@ -1105,7 +1105,7 @@ export const secretV2BridgeServiceFactory = ({
if (shouldExpandSecretReferences) { if (shouldExpandSecretReferences) {
const secretsGroupByPath = groupBy(decryptedSecrets, (i) => i.secretPath); const secretsGroupByPath = groupBy(decryptedSecrets, (i) => i.secretPath);
await Promise.allSettled( const settledPromises = await Promise.allSettled(
Object.keys(secretsGroupByPath).map((groupedPath) => Object.keys(secretsGroupByPath).map((groupedPath) =>
Promise.allSettled( Promise.allSettled(
secretsGroupByPath[groupedPath].map(async (decryptedSecret, index) => { secretsGroupByPath[groupedPath].map(async (decryptedSecret, index) => {
@@ -1113,7 +1113,8 @@ export const secretV2BridgeServiceFactory = ({
value: decryptedSecret.secretValue, value: decryptedSecret.secretValue,
secretPath: groupedPath, secretPath: groupedPath,
environment, environment,
skipMultilineEncoding: decryptedSecret.skipMultilineEncoding skipMultilineEncoding: decryptedSecret.skipMultilineEncoding,
secretKey: decryptedSecret.secretKey
}); });
// eslint-disable-next-line no-param-reassign // eslint-disable-next-line no-param-reassign
secretsGroupByPath[groupedPath][index].secretValue = expandedSecretValue || ""; secretsGroupByPath[groupedPath][index].secretValue = expandedSecretValue || "";
@@ -1121,6 +1122,35 @@ export const secretV2BridgeServiceFactory = ({
) )
) )
); );
const errors: { path: string; error: string }[] = [];
settledPromises.forEach((outerResult: PromiseSettledResult<PromiseSettledResult<void>[]>, outerIndex) => {
const groupedPath = Object.keys(secretsGroupByPath)[outerIndex];
if (outerResult.status === "rejected") {
errors.push({
path: groupedPath,
error: `Failed to process secret group: ${outerResult.reason}`
});
} else {
// Check inner promise results
outerResult.value.forEach((innerResult: PromiseSettledResult<void>) => {
if (innerResult.status === "rejected") {
const reason = innerResult.reason as ForbiddenRequestError;
errors.push({
path: groupedPath,
error: reason.message
});
}
});
}
});
if (errors.length > 0) {
throw new ForbiddenRequestError({
message: "Failed to expand one or more secret references",
details: errors.map((err) => err.error)
});
}
} }
if (!includeImports) { if (!includeImports) {
@@ -1424,7 +1454,8 @@ export const secretV2BridgeServiceFactory = ({
environment, environment,
secretPath: path, secretPath: path,
value: secretValue, value: secretValue,
skipMultilineEncoding: secret.skipMultilineEncoding skipMultilineEncoding: secret.skipMultilineEncoding,
secretKey: secret.key
}); });
secretValue = expandedSecretValue || ""; secretValue = expandedSecretValue || "";
@@ -2722,7 +2753,8 @@ export const secretV2BridgeServiceFactory = ({
const { expandedValue, stackTrace } = await getExpandedSecretStackTrace({ const { expandedValue, stackTrace } = await getExpandedSecretStackTrace({
environment, environment,
secretPath, secretPath,
value: decryptedSecretValue value: decryptedSecretValue,
secretKey: secretName
}); });
return { tree: stackTrace, value: expandedValue }; return { tree: stackTrace, value: expandedValue };

View File

@@ -426,7 +426,8 @@ export const secretQueueFactory = ({
environment: dto.environment, environment: dto.environment,
secretPath: dto.secretPath, secretPath: dto.secretPath,
skipMultilineEncoding: secret.skipMultilineEncoding, skipMultilineEncoding: secret.skipMultilineEncoding,
value: secretValue value: secretValue,
secretKey
}); });
content[secretKey] = { value: expandedSecretValue || "" }; content[secretKey] = { value: expandedSecretValue || "" };