feat: fips inside support (checkpoint)

This commit is contained in:
Daniel Hougaard
2025-07-06 15:44:07 +04:00
parent 83f0a500bd
commit 9aa3c14bf2
121 changed files with 1766 additions and 1277 deletions
@@ -15,7 +15,7 @@ import { TPermissionServiceFactory } from "@app/ee/services/permission/permissio
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
import { getConfig } from "@app/lib/config/env";
import { request } from "@app/lib/config/request";
import { decryptSymmetric128BitHexKeyUTF8, encryptSymmetric128BitHexKeyUTF8 } from "@app/lib/crypto";
import { crypto, SymmetricKeySize } from "@app/lib/crypto/cryptography";
import { BadRequestError, InternalServerError, NotFoundError } from "@app/lib/errors";
import { groupBy } from "@app/lib/fn";
import { logger } from "@app/lib/logger";
@@ -228,13 +228,22 @@ export const integrationAuthServiceFactory = ({
} else {
if (!botKey) throw new NotFoundError({ message: `Project bot key for project with ID '${projectId}' not found` });
if (tokenExchange.refreshToken) {
const refreshEncToken = encryptSymmetric128BitHexKeyUTF8(tokenExchange.refreshToken, botKey);
const refreshEncToken = crypto.encryption().encryptSymmetric({
plaintext: tokenExchange.refreshToken,
key: botKey,
keySize: SymmetricKeySize.Bits128
});
updateDoc.refreshIV = refreshEncToken.iv;
updateDoc.refreshTag = refreshEncToken.tag;
updateDoc.refreshCiphertext = refreshEncToken.ciphertext;
}
if (tokenExchange.accessToken) {
const accessEncToken = encryptSymmetric128BitHexKeyUTF8(tokenExchange.accessToken, botKey);
const accessEncToken = crypto.encryption().encryptSymmetric({
plaintext: tokenExchange.accessToken,
key: botKey,
keySize: SymmetricKeySize.Bits128
});
updateDoc.accessIV = accessEncToken.iv;
updateDoc.accessTag = accessEncToken.tag;
updateDoc.accessCiphertext = accessEncToken.ciphertext;
@@ -357,11 +366,19 @@ export const integrationAuthServiceFactory = ({
url,
updateDoc.metadata as Record<string, string>
);
const refreshEncToken = encryptSymmetric128BitHexKeyUTF8(tokenDetails.refreshToken, botKey);
const refreshEncToken = crypto.encryption().encryptSymmetric({
plaintext: tokenDetails.refreshToken,
key: botKey,
keySize: SymmetricKeySize.Bits128
});
updateDoc.refreshIV = refreshEncToken.iv;
updateDoc.refreshTag = refreshEncToken.tag;
updateDoc.refreshCiphertext = refreshEncToken.ciphertext;
const accessEncToken = encryptSymmetric128BitHexKeyUTF8(tokenDetails.accessToken, botKey);
const accessEncToken = crypto.encryption().encryptSymmetric({
plaintext: tokenDetails.accessToken,
key: botKey,
keySize: SymmetricKeySize.Bits128
});
updateDoc.accessIV = accessEncToken.iv;
updateDoc.accessTag = accessEncToken.tag;
updateDoc.accessCiphertext = accessEncToken.ciphertext;
@@ -371,19 +388,31 @@ export const integrationAuthServiceFactory = ({
if (!refreshToken && (accessId || accessToken || awsAssumeIamRoleArn)) {
if (accessToken) {
const accessEncToken = encryptSymmetric128BitHexKeyUTF8(accessToken, botKey);
const accessEncToken = crypto.encryption().encryptSymmetric({
plaintext: accessToken,
key: botKey,
keySize: SymmetricKeySize.Bits128
});
updateDoc.accessIV = accessEncToken.iv;
updateDoc.accessTag = accessEncToken.tag;
updateDoc.accessCiphertext = accessEncToken.ciphertext;
}
if (accessId) {
const accessEncToken = encryptSymmetric128BitHexKeyUTF8(accessId, botKey);
const accessEncToken = crypto.encryption().encryptSymmetric({
plaintext: accessId,
key: botKey,
keySize: SymmetricKeySize.Bits128
});
updateDoc.accessIdIV = accessEncToken.iv;
updateDoc.accessIdTag = accessEncToken.tag;
updateDoc.accessIdCiphertext = accessEncToken.ciphertext;
}
if (awsAssumeIamRoleArn) {
const awsAssumeIamRoleArnEnc = encryptSymmetric128BitHexKeyUTF8(awsAssumeIamRoleArn, botKey);
const awsAssumeIamRoleArnEnc = crypto.encryption().encryptSymmetric({
plaintext: awsAssumeIamRoleArn,
key: botKey,
keySize: SymmetricKeySize.Bits128
});
updateDoc.awsAssumeIamRoleArnCipherText = awsAssumeIamRoleArnEnc.ciphertext;
updateDoc.awsAssumeIamRoleArnIV = awsAssumeIamRoleArnEnc.iv;
updateDoc.awsAssumeIamRoleArnTag = awsAssumeIamRoleArnEnc.tag;
@@ -499,11 +528,21 @@ export const integrationAuthServiceFactory = ({
url,
updateDoc.metadata as Record<string, string>
);
const refreshEncToken = encryptSymmetric128BitHexKeyUTF8(tokenDetails.refreshToken, botKey);
const refreshEncToken = crypto.encryption().encryptSymmetric({
plaintext: tokenDetails.refreshToken,
key: botKey,
keySize: SymmetricKeySize.Bits128
});
updateDoc.refreshIV = refreshEncToken.iv;
updateDoc.refreshTag = refreshEncToken.tag;
updateDoc.refreshCiphertext = refreshEncToken.ciphertext;
const accessEncToken = encryptSymmetric128BitHexKeyUTF8(tokenDetails.accessToken, botKey);
const accessEncToken = crypto.encryption().encryptSymmetric({
plaintext: tokenDetails.accessToken,
key: botKey,
keySize: SymmetricKeySize.Bits128
});
updateDoc.accessIV = accessEncToken.iv;
updateDoc.accessTag = accessEncToken.tag;
updateDoc.accessCiphertext = accessEncToken.ciphertext;
@@ -513,19 +552,32 @@ export const integrationAuthServiceFactory = ({
if (!refreshToken && (accessId || accessToken || awsAssumeIamRoleArn)) {
if (accessToken) {
const accessEncToken = encryptSymmetric128BitHexKeyUTF8(accessToken, botKey);
const accessEncToken = crypto.encryption().encryptSymmetric({
plaintext: accessToken,
key: botKey,
keySize: SymmetricKeySize.Bits128
});
updateDoc.accessIV = accessEncToken.iv;
updateDoc.accessTag = accessEncToken.tag;
updateDoc.accessCiphertext = accessEncToken.ciphertext;
}
if (accessId) {
const accessEncToken = encryptSymmetric128BitHexKeyUTF8(accessId, botKey);
const accessEncToken = crypto.encryption().encryptSymmetric({
plaintext: accessId,
key: botKey,
keySize: SymmetricKeySize.Bits128
});
updateDoc.accessIdIV = accessEncToken.iv;
updateDoc.accessIdTag = accessEncToken.tag;
updateDoc.accessIdCiphertext = accessEncToken.ciphertext;
}
if (awsAssumeIamRoleArn) {
const awsAssumeIamRoleArnEnc = encryptSymmetric128BitHexKeyUTF8(awsAssumeIamRoleArn, botKey);
const awsAssumeIamRoleArnEnc = crypto.encryption().encryptSymmetric({
plaintext: awsAssumeIamRoleArn,
key: botKey,
keySize: SymmetricKeySize.Bits128
});
updateDoc.awsAssumeIamRoleArnCipherText = awsAssumeIamRoleArnEnc.ciphertext;
updateDoc.awsAssumeIamRoleArnIV = awsAssumeIamRoleArnEnc.iv;
updateDoc.awsAssumeIamRoleArnTag = awsAssumeIamRoleArnEnc.tag;
@@ -608,20 +660,22 @@ export const integrationAuthServiceFactory = ({
} else {
if (!botKey) throw new NotFoundError({ message: "Project bot key not found" });
if (integrationAuth.accessTag && integrationAuth.accessIV && integrationAuth.accessCiphertext) {
accessToken = decryptSymmetric128BitHexKeyUTF8({
accessToken = crypto.encryption().decryptSymmetric({
ciphertext: integrationAuth.accessCiphertext,
iv: integrationAuth.accessIV,
tag: integrationAuth.accessTag,
key: botKey
key: botKey,
keySize: SymmetricKeySize.Bits128
});
}
if (integrationAuth.refreshCiphertext && integrationAuth.refreshIV && integrationAuth.refreshTag) {
const refreshToken = decryptSymmetric128BitHexKeyUTF8({
const refreshToken = crypto.encryption().decryptSymmetric({
key: botKey,
ciphertext: integrationAuth.refreshCiphertext,
iv: integrationAuth.refreshIV,
tag: integrationAuth.refreshTag
tag: integrationAuth.refreshTag,
keySize: SymmetricKeySize.Bits128
});
if (integrationAuth.accessExpiresAt && integrationAuth.accessExpiresAt < new Date()) {
@@ -632,8 +686,18 @@ export const integrationAuthServiceFactory = ({
integrationAuth?.url,
integrationAuth.metadata as Record<string, string>
);
const refreshEncToken = encryptSymmetric128BitHexKeyUTF8(tokenDetails.refreshToken, botKey);
const accessEncToken = encryptSymmetric128BitHexKeyUTF8(tokenDetails.accessToken, botKey);
const refreshEncToken = crypto.encryption().encryptSymmetric({
plaintext: tokenDetails.refreshToken,
key: botKey,
keySize: SymmetricKeySize.Bits128
});
const accessEncToken = crypto.encryption().encryptSymmetric({
plaintext: tokenDetails.accessToken,
key: botKey,
keySize: SymmetricKeySize.Bits128
});
accessToken = tokenDetails.accessToken;
await integrationAuthDAL.updateById(integrationAuth.id, {
refreshIV: refreshEncToken.iv,
@@ -649,11 +713,12 @@ export const integrationAuthServiceFactory = ({
if (!accessToken) throw new BadRequestError({ message: "Missing access token" });
if (integrationAuth.accessIdTag && integrationAuth.accessIdIV && integrationAuth.accessIdCiphertext) {
accessId = decryptSymmetric128BitHexKeyUTF8({
accessId = crypto.encryption().decryptSymmetric({
key: botKey,
ciphertext: integrationAuth.accessIdCiphertext,
iv: integrationAuth.accessIdIV,
tag: integrationAuth.accessIdTag
tag: integrationAuth.accessIdTag,
keySize: SymmetricKeySize.Bits128
});
}
}
@@ -5,7 +5,7 @@ import { Octokit } from "@octokit/rest";
import { TIntegrationAuths, TIntegrations } from "@app/db/schemas";
import { getConfig } from "@app/lib/config/env";
import { decryptSymmetric128BitHexKeyUTF8 } from "@app/lib/crypto";
import { crypto, SymmetricKeySize } from "@app/lib/crypto/cryptography";
import { BadRequestError, NotFoundError } from "@app/lib/errors";
import { logger } from "@app/lib/logger";
@@ -109,12 +109,14 @@ const getIntegrationSecretsV1 = async (
// process secrets in current folder
const secrets = await secretDAL.findByFolderId(dto.folderId);
secrets.forEach((secret) => {
const secretKey = decryptSymmetric128BitHexKeyUTF8({
const secretKey = crypto.encryption().decryptSymmetric({
ciphertext: secret.secretKeyCiphertext,
iv: secret.secretKeyIV,
tag: secret.secretKeyTag,
key: dto.key
key: dto.key,
keySize: SymmetricKeySize.Bits128
});
content[secretKey] = true;
@@ -23,7 +23,6 @@ import { createAppAuth } from "@octokit/auth-app";
import { Octokit } from "@octokit/rest";
import AWS, { AWSError } from "aws-sdk";
import { AxiosError } from "axios";
import { randomUUID } from "crypto";
import https from "https";
import sodium from "libsodium-wrappers";
import isEqual from "lodash.isequal";
@@ -33,6 +32,7 @@ import { z } from "zod";
import { SecretType, TIntegrationAuths, TIntegrations } from "@app/db/schemas";
import { getConfig } from "@app/lib/config/env";
import { request } from "@app/lib/config/request";
import { crypto } from "@app/lib/crypto/cryptography";
import { BadRequestError, InternalServerError } from "@app/lib/errors";
import { logger } from "@app/lib/logger";
import { TCreateManySecretsRawFn, TUpdateManySecretsRawFn } from "@app/services/secret/secret-types";
@@ -806,7 +806,7 @@ const syncSecretsAWSParameterStore = async ({
});
const command = new AssumeRoleCommand({
RoleArn: awsAssumeRoleArn,
RoleSessionName: `infisical-parameter-store-${randomUUID()}`,
RoleSessionName: `infisical-parameter-store-${crypto.rawCrypto.randomUUID()}`,
DurationSeconds: 900, // 15mins
ExternalId: projectId
});
@@ -1126,7 +1126,7 @@ const syncSecretsAWSSecretManager = async ({
});
const command = new AssumeRoleCommand({
RoleArn: awsAssumeRoleArn,
RoleSessionName: `infisical-sm-${randomUUID()}`,
RoleSessionName: `infisical-sm-${crypto.rawCrypto.randomUUID()}`,
DurationSeconds: 900, // 15mins
ExternalId: projectId
});