improvements: final feedback and ssl enforcement

This commit is contained in:
Scott Wilson
2025-04-04 13:28:01 -07:00
parent cd333a7923
commit 06fc4e955d
9 changed files with 52 additions and 24 deletions
@@ -28,6 +28,7 @@ export async function up(knex: Knex): Promise<void> {
t.binary("encryptedLastRotationMessage"); // we encrypt this because it may contain sensitive info (SQL errors showing credentials) t.binary("encryptedLastRotationMessage"); // we encrypt this because it may contain sensitive info (SQL errors showing credentials)
t.string("lastRotationJobId"); t.string("lastRotationJobId");
t.datetime("nextRotationAt"); t.datetime("nextRotationAt");
t.boolean("isLastRotationManual").notNullable().defaultTo(true); // creation is considered a "manual" rotation
}); });
await createOnUpdateTrigger(knex, TableName.SecretRotationV2); await createOnUpdateTrigger(knex, TableName.SecretRotationV2);
+2 -2
View File
@@ -23,10 +23,10 @@ export const OrganizationsSchema = z.object({
defaultMembershipRole: z.string().default("member"), defaultMembershipRole: z.string().default("member"),
enforceMfa: z.boolean().default(false), enforceMfa: z.boolean().default(false),
selectedMfaMethod: z.string().nullable().optional(), selectedMfaMethod: z.string().nullable().optional(),
allowSecretSharingOutsideOrganization: z.boolean().default(true).nullable().optional(),
shouldUseNewPrivilegeSystem: z.boolean().default(true), shouldUseNewPrivilegeSystem: z.boolean().default(true),
privilegeUpgradeInitiatedByUsername: z.string().nullable().optional(), privilegeUpgradeInitiatedByUsername: z.string().nullable().optional(),
privilegeUpgradeInitiatedAt: z.date().nullable().optional(), privilegeUpgradeInitiatedAt: z.date().nullable().optional()
allowSecretSharingOutsideOrganization: z.boolean().default(true).nullable().optional()
}); });
export type TOrganizations = z.infer<typeof OrganizationsSchema>; export type TOrganizations = z.infer<typeof OrganizationsSchema>;
@@ -30,7 +30,8 @@ export const SecretRotationsV2Schema = z.object({
lastRotatedAt: z.date(), lastRotatedAt: z.date(),
encryptedLastRotationMessage: zodBuffer.nullable().optional(), encryptedLastRotationMessage: zodBuffer.nullable().optional(),
lastRotationJobId: z.string().nullable().optional(), lastRotationJobId: z.string().nullable().optional(),
nextRotationAt: z.date().nullable().optional() nextRotationAt: z.date().nullable().optional(),
isLastRotationManual: z.boolean().default(true)
}); });
export type TSecretRotationsV2 = z.infer<typeof SecretRotationsV2Schema>; export type TSecretRotationsV2 = z.infer<typeof SecretRotationsV2Schema>;
@@ -597,7 +597,7 @@ export const secretRotationV2ServiceFactory = ({
const nextRotationAt = calculateNextRotationAt({ const nextRotationAt = calculateNextRotationAt({
...(secretRotation as TSecretRotationV2), ...(secretRotation as TSecretRotationV2),
...payload, ...payload,
isManualRotation: false isManualRotation: secretRotation.isLastRotationManual
}); });
let secretsMappingUpdated = false; let secretsMappingUpdated = false;
@@ -892,6 +892,7 @@ export const secretRotationV2ServiceFactory = ({
{ {
encryptedGeneratedCredentials: encryptedUpdatedCredentials, encryptedGeneratedCredentials: encryptedUpdatedCredentials,
activeIndex: inactiveIndex, activeIndex: inactiveIndex,
isLastRotationManual: isManualRotation,
lastRotatedAt: currentTime, lastRotatedAt: currentTime,
lastRotationAttemptedAt: currentTime, lastRotationAttemptedAt: currentTime,
nextRotationAt: calculateNextRotationAt({ nextRotationAt: calculateNextRotationAt({
+1
View File
@@ -60,6 +60,7 @@ const envSchema = z
HTTPS_ENABLED: zodStrBool, HTTPS_ENABLED: zodStrBool,
ROTATION_DEVELOPMENT_MODE: zodStrBool.default("false").optional(), ROTATION_DEVELOPMENT_MODE: zodStrBool.default("false").optional(),
DB_SSL_REJECT_UNAUTHORIZED: zodStrBool.default("true"), DB_SSL_REJECT_UNAUTHORIZED: zodStrBool.default("true"),
DB_SSL_REQUIRED: zodStrBool.default("true"),
// smtp options // smtp options
SMTP_HOST: zpStr(z.string().optional()), SMTP_HOST: zpStr(z.string().optional()),
SMTP_IGNORE_TLS: zodStrBool.default("false"), SMTP_IGNORE_TLS: zodStrBool.default("false"),
@@ -19,18 +19,46 @@ const SQL_CONNECTION_CLIENT_MAP = {
[AppConnection.MsSql]: "mssql" [AppConnection.MsSql]: "mssql"
}; };
export const getSqlConnectionClient = async (appConnection: Pick<TSqlConnection, "credentials" | "app">) => { const getConnectionConfig = ({
app,
credentials: { sslCertificate, host }
}: Pick<TSqlConnection, "credentials" | "app">) => {
const appCfg = getConfig(); const appCfg = getConfig();
switch (app) {
case AppConnection.Postgres: {
return {
ssl: appCfg.DB_SSL_REQUIRED
? {
rejectUnauthorized: appCfg.DB_SSL_REJECT_UNAUTHORIZED,
ca: sslCertificate,
servername: host
}
: false
};
}
case AppConnection.MsSql: {
return {
options: appCfg.DB_SSL_REQUIRED
? {
trustServerCertificate: !appCfg.DB_SSL_REJECT_UNAUTHORIZED,
encrypt: true,
cryptoCredentialsDetails: sslCertificate ? { ca: sslCertificate } : {}
}
: undefined
};
}
default:
throw new Error(`Unhandled SQL Connection Config: ${app as AppConnection}`);
}
};
export const getSqlConnectionClient = async (appConnection: Pick<TSqlConnection, "credentials" | "app">) => {
const { const {
app, app,
credentials: { host: baseHost, database, port, sslCertificate, password, username } credentials: { host: baseHost, database, port, password, username }
} = appConnection; } = appConnection;
const ssl = sslCertificate
? { rejectUnauthorized: appCfg.DB_SSL_REJECT_UNAUTHORIZED, ca: sslCertificate, servername: baseHost }
: undefined;
const [host] = await verifyHostInputValidity(baseHost); const [host] = await verifyHostInputValidity(baseHost);
const client = knex({ const client = knex({
@@ -42,16 +70,7 @@ export const getSqlConnectionClient = async (appConnection: Pick<TSqlConnection,
user: username, user: username,
password, password,
connectionTimeoutMillis: EXTERNAL_REQUEST_TIMEOUT, connectionTimeoutMillis: EXTERNAL_REQUEST_TIMEOUT,
ssl, ...getConnectionConfig(appConnection)
// following dynamic secret mssql driver requirements (see sql-database.ts)
// @ts-expect-error this is because of knexjs type signature issue. This is directly passed to driver
options:
app === AppConnection.MsSql
? {
trustServerCertificate: !appCfg.DB_SSL_REJECT_UNAUTHORIZED,
cryptoCredentialsDetails: sslCertificate ? { ca: sslCertificate } : {}
}
: undefined
} }
}); });
@@ -49,7 +49,7 @@ An example creation statement might look like:
- **Rotate At** - the local time of day when rotation should occur once the interval has elapsed. - **Rotate At** - the local time of day when rotation should occur once the interval has elapsed.
- **Auto-Rotation Enabled** - whether secrets should automatically be rotated once the rotation interval has elapsed. Disable this option to manually rotate secrets or pause secret rotation. - **Auto-Rotation Enabled** - whether secrets should automatically be rotated once the rotation interval has elapsed. Disable this option to manually rotate secrets or pause secret rotation.
4. Input the the usernames of the database roles created above that will be used for rotation. The click **Next**. 4. Input the usernames of the database users created above that will be used for rotation. Then click **Next**.
![Rotation Parameters](/images/secret-rotations-v2/mssql-credentials/mssql-credentials-parameters.png) ![Rotation Parameters](/images/secret-rotations-v2/mssql-credentials/mssql-credentials-parameters.png)
- **Database Username 1** - the username of the first user that will be used for rotation. - **Database Username 1** - the username of the first user that will be used for rotation.
@@ -44,7 +44,7 @@ description: "Learn how to automatically rotate PostgreSQL credentials."
- **Rotate At** - the local time of day when rotation should occur once the interval has elapsed. - **Rotate At** - the local time of day when rotation should occur once the interval has elapsed.
- **Auto-Rotation Enabled** - whether secrets should automatically be rotated once the rotation interval has elapsed. Disable this option to manually rotate secrets or pause secret rotation. - **Auto-Rotation Enabled** - whether secrets should automatically be rotated once the rotation interval has elapsed. Disable this option to manually rotate secrets or pause secret rotation.
4. Input the the usernames of the database roles created above that will be used for rotation. The click **Next**. 4. Input the usernames of the database users created above that will be used for rotation. Then click **Next**.
![Rotation Parameters](/images/secret-rotations-v2/postgres-credentials/postgres-credentials-parameters.png) ![Rotation Parameters](/images/secret-rotations-v2/postgres-credentials/postgres-credentials-parameters.png)
- **Database Username 1** - the username of the first user that will be used for rotation. - **Database Username 1** - the username of the first user that will be used for rotation.
+7 -2
View File
@@ -442,8 +442,13 @@ When set, all visits to the Infisical login page will automatically redirect use
## External Database Connections ## External Database Connections
<ParamField query="DB_SSL_REJECT_UNAUTHORIZED" type="boolean" default="true" optional> <ParamField query="DB_SSL_REJECT_UNAUTHORIZED" type="boolean" default="true" optional>
Whether external database connections should reject unauthorized SSL certificates. Only set this to `false` if Specify whether external database connections should reject unauthorized SSL certificates.
the database you are connecting to is within your internal network. We highly recommend keeping this value set to `true` for production use-cases.
</ParamField>
<ParamField query="DB_SSL_REQUIRED" type="boolean" default="true" optional>
Specify whether external database connections should require SSL.
We highly recommend keeping this value set to `true` for production use-cases.
</ParamField> </ParamField>