Merge pull request #3973 from Infisical/daniel/fips-initative

feat(fips): native FIPS support
This commit is contained in:
Daniel Hougaard
2025-07-15 19:03:51 +04:00
committed by GitHub
167 changed files with 3503 additions and 1619 deletions
@@ -3,35 +3,8 @@ import crypto from "crypto";
import { NavigateFn } from "@tanstack/react-router";
import { createNotification } from "@app/components/notifications";
import {
decryptAssymmetric,
encryptAssymmetric
} from "@app/components/utilities/cryptography/crypto";
import { localStorageService } from "@app/helpers/localStorage";
import { TCloudIntegration, UserWsKeyPair } from "@app/hooks/api/types";
export const generateBotKey = (botPublicKey: string, latestKey: UserWsKeyPair) => {
const PRIVATE_KEY = localStorage.getItem("PRIVATE_KEY");
if (!PRIVATE_KEY) {
throw new Error("Private Key missing");
}
const WORKSPACE_KEY = decryptAssymmetric({
ciphertext: latestKey.encryptedKey,
nonce: latestKey.nonce,
publicKey: latestKey.sender.publicKey,
privateKey: PRIVATE_KEY
});
const { ciphertext, nonce } = encryptAssymmetric({
plaintext: WORKSPACE_KEY,
publicKey: botPublicKey,
privateKey: PRIVATE_KEY
});
return { encryptedKey: ciphertext, nonce };
};
import { TCloudIntegration } from "@app/hooks/api/types";
export const createIntegrationMissingEnvVarsNotification = (
slug: string,
@@ -1,18 +1,12 @@
import { useWorkspace } from "@app/context";
import { ProjectVersion } from "@app/hooks/api/workspace/types";
import { AutoCapitalizationSection } from "../AutoCapitalizationSection";
import { BackfillSecretReferenceSecretion } from "../BackfillSecretReferenceSection";
import { EnvironmentSection } from "../EnvironmentSection";
import { PointInTimeVersionLimitSection } from "../PointInTimeVersionLimitSection";
import { RebuildSecretIndicesSection } from "../RebuildSecretIndicesSection/RebuildSecretIndicesSection";
import { SecretSharingSection } from "../SecretSharingSection";
import { SecretSnapshotsLegacySection } from "../SecretSnapshotsLegacySection";
import { SecretTagsSection } from "../SecretTagsSection";
export const ProjectGeneralTab = () => {
const { currentWorkspace } = useWorkspace();
return (
<div>
<EnvironmentSection />
@@ -22,7 +16,6 @@ export const ProjectGeneralTab = () => {
<SecretSnapshotsLegacySection />
<PointInTimeVersionLimitSection />
<BackfillSecretReferenceSecretion />
{currentWorkspace?.version !== ProjectVersion.V3 && <RebuildSecretIndicesSection />}
</div>
);
};
@@ -1,93 +0,0 @@
import { createNotification } from "@app/components/notifications";
import {
decryptAssymmetric,
decryptSymmetric
} from "@app/components/utilities/cryptography/crypto";
import { Button } from "@app/components/v2";
import { useProjectPermission, useWorkspace } from "@app/context";
import { useToggle } from "@app/hooks";
import { useGetUserWsKey, useNameWorkspaceSecrets } from "@app/hooks/api";
import { ProjectMembershipRole } from "@app/hooks/api/roles/types";
import { fetchWorkspaceSecrets } from "@app/hooks/api/workspace/queries";
export const RebuildSecretIndicesSection = () => {
const { currentWorkspace } = useWorkspace();
const { membership } = useProjectPermission();
const nameWorkspaceSecrets = useNameWorkspaceSecrets();
const [isIndexing, setIsIndexing] = useToggle();
const { data: decryptFileKey } = useGetUserWsKey(currentWorkspace.id);
if (!currentWorkspace) return null;
const onRebuildIndices = async () => {
if (!currentWorkspace?.id) return;
setIsIndexing.on();
try {
const encryptedSecrets = await fetchWorkspaceSecrets(currentWorkspace.id);
if (!currentWorkspace || !decryptFileKey) {
return;
}
const key = decryptAssymmetric({
ciphertext: decryptFileKey.encryptedKey,
nonce: decryptFileKey.nonce,
publicKey: decryptFileKey.sender.publicKey,
privateKey: localStorage.getItem("PRIVATE_KEY") as string
});
const secretsToUpdate = encryptedSecrets.map((encryptedSecret) => {
const secretName = decryptSymmetric({
ciphertext: encryptedSecret.secretKeyCiphertext,
iv: encryptedSecret.secretKeyIV,
tag: encryptedSecret.secretKeyTag,
key
});
return {
secretName,
secretId: encryptedSecret.id
};
});
await nameWorkspaceSecrets.mutateAsync({
workspaceId: currentWorkspace.id,
secretsToUpdate
});
createNotification({
text: "Successfully rebuilt secret indices",
type: "success"
});
} catch (err) {
console.log(err);
} finally {
setIsIndexing.off();
}
};
const isAdmin = membership.roles.includes(ProjectMembershipRole.Admin);
if (!isAdmin) {
return null;
}
return (
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
<div className="flex w-full items-center justify-between">
<p className="text-xl font-semibold">Rebuild Secret Indices</p>
</div>
<p className="mb-4 mt-2 max-w-2xl text-sm text-gray-400">
This will rebuild indices of all secrets in the project.
</p>
<Button
variant="outline_bg"
isLoading={isIndexing}
onClick={onRebuildIndices}
isDisabled={!isAdmin}
>
Rebuild Secret Indices
</Button>
</div>
);
};