mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
feat: fips inside (checkpoint)
This commit is contained in:
@@ -26,15 +26,18 @@ export default {
|
|||||||
transformMode: "ssr",
|
transformMode: "ssr",
|
||||||
async setup() {
|
async setup() {
|
||||||
const logger = initLogger();
|
const logger = initLogger();
|
||||||
const envConfig = initEnvConfig(logger);
|
const { envCfg, updateRootEncryptionKey } = initEnvConfig(logger);
|
||||||
const db = initDbConnection({
|
const db = initDbConnection({
|
||||||
dbConnectionUri: envConfig.DB_CONNECTION_URI,
|
dbConnectionUri: envCfg.DB_CONNECTION_URI,
|
||||||
dbRootCert: envConfig.DB_ROOT_CERT
|
dbRootCert: envCfg.DB_ROOT_CERT
|
||||||
});
|
});
|
||||||
const superAdminDAL = superAdminDALFactory(db);
|
const superAdminDAL = superAdminDALFactory(db);
|
||||||
await crypto.initialize(superAdminDAL);
|
const fipsEnabled = await crypto.initialize(superAdminDAL);
|
||||||
|
if (fipsEnabled) {
|
||||||
|
updateRootEncryptionKey(envCfg.ENCRYPTION_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
const redis = buildRedisFromConfig(envConfig);
|
const redis = buildRedisFromConfig(envCfg);
|
||||||
await redis.flushdb("SYNC");
|
await redis.flushdb("SYNC");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -59,10 +62,10 @@ export default {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const smtp = mockSmtpServer();
|
const smtp = mockSmtpServer();
|
||||||
const queue = queueServiceFactory(envConfig, { dbConnectionUrl: envConfig.DB_CONNECTION_URI });
|
const queue = queueServiceFactory(envCfg, { dbConnectionUrl: envCfg.DB_CONNECTION_URI });
|
||||||
const keyStore = keyStoreFactory(envConfig);
|
const keyStore = keyStoreFactory(envCfg);
|
||||||
|
|
||||||
const hsmModule = initializeHsmModule(envConfig);
|
const hsmModule = initializeHsmModule(envCfg);
|
||||||
hsmModule.initialize();
|
hsmModule.initialize();
|
||||||
|
|
||||||
const server = await main({
|
const server = await main({
|
||||||
@@ -74,7 +77,7 @@ export default {
|
|||||||
hsmModule: hsmModule.getModule(),
|
hsmModule: hsmModule.getModule(),
|
||||||
superAdminDAL,
|
superAdminDAL,
|
||||||
redis,
|
redis,
|
||||||
envConfig
|
envConfig: envCfg
|
||||||
});
|
});
|
||||||
|
|
||||||
// @ts-expect-error type
|
// @ts-expect-error type
|
||||||
@@ -91,8 +94,8 @@ export default {
|
|||||||
organizationId: seedData1.organization.id,
|
organizationId: seedData1.organization.id,
|
||||||
accessVersion: 1
|
accessVersion: 1
|
||||||
},
|
},
|
||||||
envConfig.AUTH_SECRET,
|
envCfg.AUTH_SECRET,
|
||||||
{ expiresIn: envConfig.JWT_AUTH_LIFETIME }
|
{ expiresIn: envCfg.JWT_AUTH_LIFETIME }
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
|
|||||||
@@ -353,8 +353,23 @@ export const initEnvConfig = (logger?: CustomLogger) => {
|
|||||||
process.exit(-1);
|
process.exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
envCfg = Object.freeze(parsedEnv.data);
|
const updateRootEncryptionKey = (key?: string) => {
|
||||||
return envCfg;
|
if (!key) {
|
||||||
|
throw new Error("Failed to update root encryption key. Key is unset.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const newEnvCfg = {
|
||||||
|
...envCfg
|
||||||
|
};
|
||||||
|
|
||||||
|
newEnvCfg.ROOT_ENCRYPTION_KEY = key;
|
||||||
|
delete newEnvCfg.ENCRYPTION_KEY;
|
||||||
|
|
||||||
|
envCfg = Object.freeze(newEnvCfg);
|
||||||
|
return envCfg;
|
||||||
|
};
|
||||||
|
|
||||||
|
return { envCfg, updateRootEncryptionKey };
|
||||||
};
|
};
|
||||||
|
|
||||||
export const formatSmtpConfig = () => {
|
export const formatSmtpConfig = () => {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { SymmetricKeyAlgorithm, TSymmetricEncryptionFns } from "./types";
|
|||||||
const IV_LENGTH = 12;
|
const IV_LENGTH = 12;
|
||||||
const TAG_LENGTH = 16;
|
const TAG_LENGTH = 16;
|
||||||
|
|
||||||
|
// todo(daniel): Decide if we should move this into the cryptography module
|
||||||
export const symmetricCipherService = (
|
export const symmetricCipherService = (
|
||||||
type: SymmetricKeyAlgorithm.AES_GCM_128 | SymmetricKeyAlgorithm.AES_GCM_256
|
type: SymmetricKeyAlgorithm.AES_GCM_128 | SymmetricKeyAlgorithm.AES_GCM_256
|
||||||
): TSymmetricEncryptionFns => {
|
): TSymmetricEncryptionFns => {
|
||||||
|
|||||||
@@ -11,7 +11,9 @@ import { SecretEncryptionAlgo, SecretKeyEncoding } from "@app/db/schemas";
|
|||||||
import { TSuperAdminDALFactory } from "@app/services/super-admin/super-admin-dal";
|
import { TSuperAdminDALFactory } from "@app/services/super-admin/super-admin-dal";
|
||||||
import { ADMIN_CONFIG_DB_UUID } from "@app/services/super-admin/super-admin-service";
|
import { ADMIN_CONFIG_DB_UUID } from "@app/services/super-admin/super-admin-service";
|
||||||
|
|
||||||
|
import { isBase64 } from "../base64";
|
||||||
import { getConfig } from "../config/env";
|
import { getConfig } from "../config/env";
|
||||||
|
import { CryptographyError } from "../errors";
|
||||||
import { logger } from "../logger";
|
import { logger } from "../logger";
|
||||||
|
|
||||||
enum DigestType {
|
enum DigestType {
|
||||||
@@ -59,6 +61,8 @@ type TDecryptAsymmetricInput = {
|
|||||||
privateKey: string;
|
privateKey: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const bytesToBits = (bytes: number) => bytes * 8;
|
||||||
|
|
||||||
const IV_BYTES_SIZE = 12;
|
const IV_BYTES_SIZE = 12;
|
||||||
const BLOCK_SIZE_BYTES_16 = 16;
|
const BLOCK_SIZE_BYTES_16 = 16;
|
||||||
|
|
||||||
@@ -294,6 +298,33 @@ const cryptographyFactory = () => {
|
|||||||
return $fipsEnabled;
|
return $fipsEnabled;
|
||||||
};
|
};
|
||||||
const $setFipsModeEnabled = (enabled: boolean) => {
|
const $setFipsModeEnabled = (enabled: boolean) => {
|
||||||
|
// If FIPS is enabled, we need to validate that the ENCRYPTION_KEY is in a base64 format, and is a 256-bit key.
|
||||||
|
if (enabled) {
|
||||||
|
const appCfg = getConfig();
|
||||||
|
|
||||||
|
if (appCfg.ENCRYPTION_KEY) {
|
||||||
|
// we need to validate that the ENCRYPTION_KEY is a base64 encoded 256-bit key
|
||||||
|
|
||||||
|
if (!isBase64(appCfg.ENCRYPTION_KEY)) {
|
||||||
|
throw new CryptographyError({
|
||||||
|
message:
|
||||||
|
"FIPS mode is enabled, but the ENCRYPTION_KEY environment variable is not a base64 encoded 256-bit key.\nYou can generate a 256-bit key using the following command: `openssl rand -base64 32`"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bytesToBits(Buffer.from(appCfg.ENCRYPTION_KEY, "base64").length) !== 256) {
|
||||||
|
throw new CryptographyError({
|
||||||
|
message:
|
||||||
|
"FIPS mode is enabled, but the ENCRYPTION_KEY environment variable is not a 256-bit key.\nYou can generate a 256-bit key using the following command: `openssl rand -base64 32`"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new CryptographyError({
|
||||||
|
message:
|
||||||
|
"FIPS mode is enabled, but the ENCRYPTION_KEY environment variable is not set.\nYou can generate a 256-bit key using the following command: `openssl rand -base64 32`"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
$fipsEnabled = enabled;
|
$fipsEnabled = enabled;
|
||||||
$isInitialized = true;
|
$isInitialized = true;
|
||||||
};
|
};
|
||||||
@@ -337,52 +368,22 @@ const cryptographyFactory = () => {
|
|||||||
const asymmetric = () => {
|
const asymmetric = () => {
|
||||||
const generateKeyPair = () => {
|
const generateKeyPair = () => {
|
||||||
if (isFipsModeEnabled()) {
|
if (isFipsModeEnabled()) {
|
||||||
logger.info("[FIPS]: Generating asymmetric key pair. FIPS mode is enabled.");
|
|
||||||
logger.info("[FIPS]: Generating asymmetric key pair. FIPS mode is enabled.");
|
|
||||||
logger.info("[FIPS]: Generating asymmetric key pair. FIPS mode is enabled.");
|
|
||||||
logger.info("[FIPS]: Generating asymmetric key pair. FIPS mode is enabled.");
|
|
||||||
logger.info("[FIPS]: Generating asymmetric key pair. FIPS mode is enabled.");
|
|
||||||
return generateAsymmetricKeyPairFipsValidated();
|
return generateAsymmetricKeyPairFipsValidated();
|
||||||
}
|
}
|
||||||
logger.info("[FIPS]: Generating asymmetric key pair. FIPS mode is DISABLED.");
|
|
||||||
logger.info("[FIPS]: Generating asymmetric key pair. FIPS mode is DISABLED.");
|
|
||||||
logger.info("[FIPS]: Generating asymmetric key pair. FIPS mode is DISABLED.");
|
|
||||||
logger.info("[FIPS]: Generating asymmetric key pair. FIPS mode is DISABLED.");
|
|
||||||
logger.info("[FIPS]: Generating asymmetric key pair. FIPS mode is DISABLED.");
|
|
||||||
return generateAsymmetricKeyPairNoFipsValidation();
|
return generateAsymmetricKeyPairNoFipsValidation();
|
||||||
};
|
};
|
||||||
|
|
||||||
const encrypt = (data: string, publicKey: string, privateKey: string) => {
|
const encrypt = (data: string, publicKey: string, privateKey: string) => {
|
||||||
if (isFipsModeEnabled()) {
|
if (isFipsModeEnabled()) {
|
||||||
logger.info("[FIPS]: Encrypting asymmetric data. FIPS mode is enabled.");
|
|
||||||
logger.info("[FIPS]: Encrypting asymmetric data. FIPS mode is enabled.");
|
|
||||||
logger.info("[FIPS]: Encrypting asymmetric data. FIPS mode is enabled.");
|
|
||||||
logger.info("[FIPS]: Encrypting asymmetric data. FIPS mode is enabled.");
|
|
||||||
logger.info("[FIPS]: Encrypting asymmetric data. FIPS mode is enabled.");
|
|
||||||
return encryptAsymmetricFipsValidated(data, publicKey, privateKey);
|
return encryptAsymmetricFipsValidated(data, publicKey, privateKey);
|
||||||
}
|
}
|
||||||
logger.info("[FIPS]: Encrypting asymmetric data. FIPS mode is DISABLED.");
|
|
||||||
logger.info("[FIPS]: Encrypting asymmetric data. FIPS mode is DISABLED.");
|
|
||||||
logger.info("[FIPS]: Encrypting asymmetric data. FIPS mode is DISABLED.");
|
|
||||||
logger.info("[FIPS]: Encrypting asymmetric data. FIPS mode is DISABLED.");
|
|
||||||
logger.info("[FIPS]: Encrypting asymmetric data. FIPS mode is DISABLED.");
|
|
||||||
return encryptAsymmetricNoFipsValidation(data, publicKey, privateKey);
|
return encryptAsymmetricNoFipsValidation(data, publicKey, privateKey);
|
||||||
};
|
};
|
||||||
|
|
||||||
const decrypt = ({ ciphertext, nonce, publicKey, privateKey }: TDecryptAsymmetricInput) => {
|
const decrypt = ({ ciphertext, nonce, publicKey, privateKey }: TDecryptAsymmetricInput) => {
|
||||||
if (isFipsModeEnabled()) {
|
if (isFipsModeEnabled()) {
|
||||||
logger.info("[FIPS]: Decrypting asymmetric data. FIPS mode is enabled.");
|
|
||||||
logger.info("[FIPS]: Decrypting asymmetric data. FIPS mode is enabled.");
|
|
||||||
logger.info("[FIPS]: Decrypting asymmetric data. FIPS mode is enabled.");
|
|
||||||
logger.info("[FIPS]: Decrypting asymmetric data. FIPS mode is enabled.");
|
|
||||||
logger.info("[FIPS]: Decrypting asymmetric data. FIPS mode is enabled.");
|
|
||||||
return decryptAsymmetricFipsValidated({ ciphertext, nonce, publicKey, privateKey });
|
return decryptAsymmetricFipsValidated({ ciphertext, nonce, publicKey, privateKey });
|
||||||
}
|
}
|
||||||
logger.info("[FIPS]: Decrypting asymmetric data. FIPS mode is DISABLED.");
|
|
||||||
logger.info("[FIPS]: Decrypting asymmetric data. FIPS mode is DISABLED.");
|
|
||||||
logger.info("[FIPS]: Decrypting asymmetric data. FIPS mode is DISABLED.");
|
|
||||||
logger.info("[FIPS]: Decrypting asymmetric data. FIPS mode is DISABLED.");
|
|
||||||
logger.info("[FIPS]: Decrypting asymmetric data. FIPS mode is DISABLED.");
|
|
||||||
return decryptAsymmetricNoFipsValidation({ ciphertext, nonce, publicKey, privateKey });
|
return decryptAsymmetricNoFipsValidation({ ciphertext, nonce, publicKey, privateKey });
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -397,6 +398,12 @@ const cryptographyFactory = () => {
|
|||||||
let decipher;
|
let decipher;
|
||||||
|
|
||||||
if (keySize === SymmetricKeySize.Bits128) {
|
if (keySize === SymmetricKeySize.Bits128) {
|
||||||
|
if (isFipsModeEnabled()) {
|
||||||
|
throw new CryptographyError({
|
||||||
|
message: "128-bit symmetric key is not supported in FIPS mode of operation."
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Not ideal: 128-bit hex key (32 chars) gets interpreted as 32 UTF-8 bytes (256 bits)
|
// Not ideal: 128-bit hex key (32 chars) gets interpreted as 32 UTF-8 bytes (256 bits)
|
||||||
// This works but reduces effective key entropy from 256 to 128 bits
|
// This works but reduces effective key entropy from 256 to 128 bits
|
||||||
// Note: Never use this for FIPS mode of operation.
|
// Note: Never use this for FIPS mode of operation.
|
||||||
@@ -418,6 +425,12 @@ const cryptographyFactory = () => {
|
|||||||
let cipher;
|
let cipher;
|
||||||
|
|
||||||
if (keySize === SymmetricKeySize.Bits128) {
|
if (keySize === SymmetricKeySize.Bits128) {
|
||||||
|
if (isFipsModeEnabled()) {
|
||||||
|
throw new CryptographyError({
|
||||||
|
message: "128-bit symmetric key is not supported in FIPS mode of operation."
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
iv = crypto.randomBytes(BLOCK_SIZE_BYTES_16);
|
iv = crypto.randomBytes(BLOCK_SIZE_BYTES_16);
|
||||||
cipher = crypto.createCipheriv(SecretEncryptionAlgo.AES_256_GCM, key, iv);
|
cipher = crypto.createCipheriv(SecretEncryptionAlgo.AES_256_GCM, key, iv);
|
||||||
} else {
|
} else {
|
||||||
@@ -478,21 +491,6 @@ const cryptographyFactory = () => {
|
|||||||
}: Omit<TDecryptSymmetricInput, "key" | "keySize"> & {
|
}: Omit<TDecryptSymmetricInput, "key" | "keySize"> & {
|
||||||
keyEncoding: SecretKeyEncoding;
|
keyEncoding: SecretKeyEncoding;
|
||||||
}) => {
|
}) => {
|
||||||
logger.info(
|
|
||||||
`[FIPS]: decryptWithRootEncryptionKey -> Decrypting symmetric data. FIPS mode is: ${isFipsModeEnabled()}`
|
|
||||||
);
|
|
||||||
logger.info(
|
|
||||||
`[FIPS]: decryptWithRootEncryptionKey -> Decrypting symmetric data. FIPS mode is: ${isFipsModeEnabled()}`
|
|
||||||
);
|
|
||||||
logger.info(
|
|
||||||
`[FIPS]: decryptWithRootEncryptionKey -> Decrypting symmetric data. FIPS mode is: ${isFipsModeEnabled()}`
|
|
||||||
);
|
|
||||||
logger.info(
|
|
||||||
`[FIPS]: decryptWithRootEncryptionKey -> Decrypting symmetric data. FIPS mode is: ${isFipsModeEnabled()}`
|
|
||||||
);
|
|
||||||
logger.info(
|
|
||||||
`[FIPS]: decryptWithRootEncryptionKey -> Decrypting symmetric data. FIPS mode is: ${isFipsModeEnabled()}`
|
|
||||||
);
|
|
||||||
const appCfg = getConfig();
|
const appCfg = getConfig();
|
||||||
// the or gate is used used in migration
|
// the or gate is used used in migration
|
||||||
const rootEncryptionKey = appCfg?.ROOT_ENCRYPTION_KEY || process.env.ROOT_ENCRYPTION_KEY;
|
const rootEncryptionKey = appCfg?.ROOT_ENCRYPTION_KEY || process.env.ROOT_ENCRYPTION_KEY;
|
||||||
@@ -530,11 +528,6 @@ const cryptographyFactory = () => {
|
|||||||
* @deprecated Do not use MD5 unless you absolutely have to. It is considered an unsafe hashing algorithm, and should only be used if absolutely necessary.
|
* @deprecated Do not use MD5 unless you absolutely have to. It is considered an unsafe hashing algorithm, and should only be used if absolutely necessary.
|
||||||
*/
|
*/
|
||||||
const md5 = (message: string, digest: DigestType = DigestType.Hex) => {
|
const md5 = (message: string, digest: DigestType = DigestType.Hex) => {
|
||||||
logger.info(`[FIPS]: md5 -> Hashing message. FIPS mode is: ${isFipsModeEnabled()}`);
|
|
||||||
logger.info(`[FIPS]: md5 -> Hashing message. FIPS mode is: ${isFipsModeEnabled()}`);
|
|
||||||
logger.info(`[FIPS]: md5 -> Hashing message. FIPS mode is: ${isFipsModeEnabled()}`);
|
|
||||||
logger.info(`[FIPS]: md5 -> Hashing message. FIPS mode is: ${isFipsModeEnabled()}`);
|
|
||||||
logger.info(`[FIPS]: md5 -> Hashing message. FIPS mode is: ${isFipsModeEnabled()}`);
|
|
||||||
// If FIPS is enabled and we need MD5, we use the crypto-js implementation.
|
// If FIPS is enabled and we need MD5, we use the crypto-js implementation.
|
||||||
// Avoid this at all costs unless strictly necessary, like for mongo atlas digest auth.
|
// Avoid this at all costs unless strictly necessary, like for mongo atlas digest auth.
|
||||||
if (isFipsModeEnabled()) {
|
if (isFipsModeEnabled()) {
|
||||||
@@ -544,12 +537,6 @@ const cryptographyFactory = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const createHash = async (password: string, saltRounds: number) => {
|
const createHash = async (password: string, saltRounds: number) => {
|
||||||
logger.info(`[FIPS]: createHash -> Hashing password. FIPS mode is: ${isFipsModeEnabled()}`);
|
|
||||||
logger.info(`[FIPS]: createHash -> Hashing password. FIPS mode is: ${isFipsModeEnabled()}`);
|
|
||||||
logger.info(`[FIPS]: createHash -> Hashing password. FIPS mode is: ${isFipsModeEnabled()}`);
|
|
||||||
logger.info(`[FIPS]: createHash -> Hashing password. FIPS mode is: ${isFipsModeEnabled()}`);
|
|
||||||
logger.info(`[FIPS]: createHash -> Hashing password. FIPS mode is: ${isFipsModeEnabled()}`);
|
|
||||||
logger.info(`[FIPS]: createHash -> Hashing password. FIPS mode is: ${isFipsModeEnabled()}`);
|
|
||||||
if (isFipsModeEnabled()) {
|
if (isFipsModeEnabled()) {
|
||||||
const hasher = hasherFipsValidated();
|
const hasher = hasherFipsValidated();
|
||||||
|
|
||||||
@@ -566,12 +553,6 @@ const cryptographyFactory = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const compareHash = async (password: string, hash: string) => {
|
const compareHash = async (password: string, hash: string) => {
|
||||||
logger.info(`[FIPS]: compareHash -> Comparing password. FIPS mode is: ${isFipsModeEnabled()}`);
|
|
||||||
logger.info(`[FIPS]: compareHash -> Comparing password. FIPS mode is: ${isFipsModeEnabled()}`);
|
|
||||||
logger.info(`[FIPS]: compareHash -> Comparing password. FIPS mode is: ${isFipsModeEnabled()}`);
|
|
||||||
logger.info(`[FIPS]: compareHash -> Comparing password. FIPS mode is: ${isFipsModeEnabled()}`);
|
|
||||||
logger.info(`[FIPS]: compareHash -> Comparing password. FIPS mode is: ${isFipsModeEnabled()}`);
|
|
||||||
logger.info(`[FIPS]: compareHash -> Comparing password. FIPS mode is: ${isFipsModeEnabled()}`);
|
|
||||||
if (isFipsModeEnabled()) {
|
if (isFipsModeEnabled()) {
|
||||||
const isValid = await hasherFipsValidated().compare(password, hash);
|
const isValid = await hasherFipsValidated().compare(password, hash);
|
||||||
return isValid;
|
return isValid;
|
||||||
|
|||||||
@@ -171,3 +171,15 @@ export class OidcAuthError extends Error {
|
|||||||
this.error = error;
|
this.error = error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class CryptographyError extends Error {
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
error: unknown;
|
||||||
|
|
||||||
|
constructor({ name, error, message }: { message?: string; name?: string; error?: unknown }) {
|
||||||
|
super(message || "Cryptographic operation failed");
|
||||||
|
this.name = name || "CryptographyError";
|
||||||
|
this.error = error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -75,27 +75,29 @@ const initTelemetryInstrumentation = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const setupTelemetry = () => {
|
const setupTelemetry = () => {
|
||||||
const appCfg = initEnvConfig();
|
const { envCfg } = initEnvConfig();
|
||||||
|
|
||||||
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
|
console.log("envCfg", envCfg);
|
||||||
|
|
||||||
|
if (envCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
|
||||||
console.log("Initializing telemetry instrumentation");
|
console.log("Initializing telemetry instrumentation");
|
||||||
initTelemetryInstrumentation({
|
initTelemetryInstrumentation({
|
||||||
otlpURL: appCfg.OTEL_EXPORT_OTLP_ENDPOINT,
|
otlpURL: envCfg.OTEL_EXPORT_OTLP_ENDPOINT,
|
||||||
otlpUser: appCfg.OTEL_COLLECTOR_BASIC_AUTH_USERNAME,
|
otlpUser: envCfg.OTEL_COLLECTOR_BASIC_AUTH_USERNAME,
|
||||||
otlpPassword: appCfg.OTEL_COLLECTOR_BASIC_AUTH_PASSWORD,
|
otlpPassword: envCfg.OTEL_COLLECTOR_BASIC_AUTH_PASSWORD,
|
||||||
otlpPushInterval: appCfg.OTEL_OTLP_PUSH_INTERVAL,
|
otlpPushInterval: envCfg.OTEL_OTLP_PUSH_INTERVAL,
|
||||||
exportType: appCfg.OTEL_EXPORT_TYPE
|
exportType: envCfg.OTEL_EXPORT_TYPE
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appCfg.SHOULD_USE_DATADOG_TRACER) {
|
if (envCfg.SHOULD_USE_DATADOG_TRACER) {
|
||||||
console.log("Initializing Datadog tracer");
|
console.log("Initializing Datadog tracer");
|
||||||
tracer.init({
|
tracer.init({
|
||||||
profiling: appCfg.DATADOG_PROFILING_ENABLED,
|
profiling: envCfg.DATADOG_PROFILING_ENABLED,
|
||||||
version: appCfg.INFISICAL_PLATFORM_VERSION,
|
version: envCfg.INFISICAL_PLATFORM_VERSION,
|
||||||
env: appCfg.DATADOG_ENV,
|
env: envCfg.DATADOG_ENV,
|
||||||
service: appCfg.DATADOG_SERVICE,
|
service: envCfg.DATADOG_SERVICE,
|
||||||
hostname: appCfg.DATADOG_HOSTNAME
|
hostname: envCfg.DATADOG_HOSTNAME
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,26 +22,29 @@ dotenv.config();
|
|||||||
|
|
||||||
const run = async () => {
|
const run = async () => {
|
||||||
const logger = initLogger();
|
const logger = initLogger();
|
||||||
const envConfig = initEnvConfig(logger);
|
const { envCfg, updateRootEncryptionKey } = initEnvConfig(logger);
|
||||||
|
|
||||||
await removeTemporaryBaseDirectory();
|
await removeTemporaryBaseDirectory();
|
||||||
|
|
||||||
const db = initDbConnection({
|
const db = initDbConnection({
|
||||||
dbConnectionUri: envConfig.DB_CONNECTION_URI,
|
dbConnectionUri: envCfg.DB_CONNECTION_URI,
|
||||||
dbRootCert: envConfig.DB_ROOT_CERT,
|
dbRootCert: envCfg.DB_ROOT_CERT,
|
||||||
readReplicas: envConfig.DB_READ_REPLICAS?.map((el) => ({
|
readReplicas: envCfg.DB_READ_REPLICAS?.map((el) => ({
|
||||||
dbRootCert: el.DB_ROOT_CERT,
|
dbRootCert: el.DB_ROOT_CERT,
|
||||||
dbConnectionUri: el.DB_CONNECTION_URI
|
dbConnectionUri: el.DB_CONNECTION_URI
|
||||||
}))
|
}))
|
||||||
});
|
});
|
||||||
|
|
||||||
const superAdminDAL = superAdminDALFactory(db);
|
const superAdminDAL = superAdminDALFactory(db);
|
||||||
await crypto.initialize(superAdminDAL);
|
const fipsEnabled = await crypto.initialize(superAdminDAL);
|
||||||
|
if (fipsEnabled) {
|
||||||
|
updateRootEncryptionKey(envCfg.ENCRYPTION_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
const auditLogDb = envConfig.AUDIT_LOGS_DB_CONNECTION_URI
|
const auditLogDb = envCfg.AUDIT_LOGS_DB_CONNECTION_URI
|
||||||
? initAuditLogDbConnection({
|
? initAuditLogDbConnection({
|
||||||
dbConnectionUri: envConfig.AUDIT_LOGS_DB_CONNECTION_URI,
|
dbConnectionUri: envCfg.AUDIT_LOGS_DB_CONNECTION_URI,
|
||||||
dbRootCert: envConfig.AUDIT_LOGS_DB_ROOT_CERT
|
dbRootCert: envCfg.AUDIT_LOGS_DB_ROOT_CERT
|
||||||
})
|
})
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
@@ -49,17 +52,17 @@ const run = async () => {
|
|||||||
|
|
||||||
const smtp = smtpServiceFactory(formatSmtpConfig());
|
const smtp = smtpServiceFactory(formatSmtpConfig());
|
||||||
|
|
||||||
const queue = queueServiceFactory(envConfig, {
|
const queue = queueServiceFactory(envCfg, {
|
||||||
dbConnectionUrl: envConfig.DB_CONNECTION_URI,
|
dbConnectionUrl: envCfg.DB_CONNECTION_URI,
|
||||||
dbRootCert: envConfig.DB_ROOT_CERT
|
dbRootCert: envCfg.DB_ROOT_CERT
|
||||||
});
|
});
|
||||||
|
|
||||||
await queue.initialize();
|
await queue.initialize();
|
||||||
|
|
||||||
const keyStore = keyStoreFactory(envConfig);
|
const keyStore = keyStoreFactory(envCfg);
|
||||||
const redis = buildRedisFromConfig(envConfig);
|
const redis = buildRedisFromConfig(envCfg);
|
||||||
|
|
||||||
const hsmModule = initializeHsmModule(envConfig);
|
const hsmModule = initializeHsmModule(envCfg);
|
||||||
hsmModule.initialize();
|
hsmModule.initialize();
|
||||||
|
|
||||||
const server = await main({
|
const server = await main({
|
||||||
@@ -72,7 +75,7 @@ const run = async () => {
|
|||||||
queue,
|
queue,
|
||||||
keyStore,
|
keyStore,
|
||||||
redis,
|
redis,
|
||||||
envConfig
|
envConfig: envCfg
|
||||||
});
|
});
|
||||||
const bootstrap = await bootstrapCheck({ db });
|
const bootstrap = await bootstrapCheck({ db });
|
||||||
|
|
||||||
@@ -96,7 +99,7 @@ const run = async () => {
|
|||||||
process.exit(0);
|
process.exit(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!envConfig.isDevelopmentMode) {
|
if (!envCfg.isDevelopmentMode) {
|
||||||
process.on("uncaughtException", (error) => {
|
process.on("uncaughtException", (error) => {
|
||||||
logger.error(error, "CRITICAL ERROR: Uncaught Exception");
|
logger.error(error, "CRITICAL ERROR: Uncaught Exception");
|
||||||
});
|
});
|
||||||
@@ -107,8 +110,8 @@ const run = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await server.listen({
|
await server.listen({
|
||||||
port: envConfig.PORT,
|
port: envCfg.PORT,
|
||||||
host: envConfig.HOST,
|
host: envCfg.HOST,
|
||||||
listenTextResolver: (address) => {
|
listenTextResolver: (address) => {
|
||||||
void bootstrap();
|
void bootstrap();
|
||||||
return address;
|
return address;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { ZodError } from "zod";
|
|||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
import {
|
import {
|
||||||
BadRequestError,
|
BadRequestError,
|
||||||
|
CryptographyError,
|
||||||
DatabaseError,
|
DatabaseError,
|
||||||
ForbiddenRequestError,
|
ForbiddenRequestError,
|
||||||
GatewayTimeoutError,
|
GatewayTimeoutError,
|
||||||
@@ -147,6 +148,13 @@ export const fastifyErrHandler = fastifyPlugin(async (server: FastifyZodProvider
|
|||||||
message: error.message,
|
message: error.message,
|
||||||
error: error.name
|
error: error.name
|
||||||
});
|
});
|
||||||
|
} else if (error instanceof CryptographyError) {
|
||||||
|
void res.status(HttpStatusCodes.BadRequest).send({
|
||||||
|
reqId: req.id,
|
||||||
|
statusCode: HttpStatusCodes.BadRequest,
|
||||||
|
message: error.message,
|
||||||
|
error: error.name
|
||||||
|
});
|
||||||
} else if (error instanceof jwt.JsonWebTokenError) {
|
} else if (error instanceof jwt.JsonWebTokenError) {
|
||||||
let errorMessage = error.message;
|
let errorMessage = error.message;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user