mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-14 15:40:47 +00:00
Merge pull request #3657 from Infisical/ENG-2608
feat(secret-rotation): MySQL Secret Rotation v2
This commit is contained in:
@@ -11,6 +11,7 @@ export enum AppConnection {
|
||||
Vercel = "vercel",
|
||||
Postgres = "postgres",
|
||||
MsSql = "mssql",
|
||||
MySql = "mysql",
|
||||
Camunda = "camunda",
|
||||
Windmill = "windmill",
|
||||
Auth0 = "auth0",
|
||||
|
||||
@@ -64,6 +64,8 @@ import {
|
||||
} from "./humanitec";
|
||||
import { getLdapConnectionListItem, LdapConnectionMethod, validateLdapConnectionCredentials } from "./ldap";
|
||||
import { getMsSqlConnectionListItem, MsSqlConnectionMethod } from "./mssql";
|
||||
import { MySqlConnectionMethod } from "./mysql/mysql-connection-enums";
|
||||
import { getMySqlConnectionListItem } from "./mysql/mysql-connection-fns";
|
||||
import { getPostgresConnectionListItem, PostgresConnectionMethod } from "./postgres";
|
||||
import {
|
||||
getTeamCityConnectionListItem,
|
||||
@@ -96,6 +98,7 @@ export const listAppConnectionOptions = () => {
|
||||
getVercelConnectionListItem(),
|
||||
getPostgresConnectionListItem(),
|
||||
getMsSqlConnectionListItem(),
|
||||
getMySqlConnectionListItem(),
|
||||
getCamundaConnectionListItem(),
|
||||
getAzureClientSecretsConnectionListItem(),
|
||||
getWindmillConnectionListItem(),
|
||||
@@ -166,6 +169,7 @@ export const validateAppConnectionCredentials = async (
|
||||
[AppConnection.Humanitec]: validateHumanitecConnectionCredentials as TAppConnectionCredentialsValidator,
|
||||
[AppConnection.Postgres]: validateSqlConnectionCredentials as TAppConnectionCredentialsValidator,
|
||||
[AppConnection.MsSql]: validateSqlConnectionCredentials as TAppConnectionCredentialsValidator,
|
||||
[AppConnection.MySql]: validateSqlConnectionCredentials as TAppConnectionCredentialsValidator,
|
||||
[AppConnection.Camunda]: validateCamundaConnectionCredentials as TAppConnectionCredentialsValidator,
|
||||
[AppConnection.Vercel]: validateVercelConnectionCredentials as TAppConnectionCredentialsValidator,
|
||||
[AppConnection.TerraformCloud]: validateTerraformCloudConnectionCredentials as TAppConnectionCredentialsValidator,
|
||||
@@ -208,6 +212,7 @@ export const getAppConnectionMethodName = (method: TAppConnection["method"]) =>
|
||||
return "API Token";
|
||||
case PostgresConnectionMethod.UsernameAndPassword:
|
||||
case MsSqlConnectionMethod.UsernameAndPassword:
|
||||
case MySqlConnectionMethod.UsernameAndPassword:
|
||||
return "Username & Password";
|
||||
case WindmillConnectionMethod.AccessToken:
|
||||
case HCVaultConnectionMethod.AccessToken:
|
||||
@@ -259,6 +264,7 @@ export const TRANSITION_CONNECTION_CREDENTIALS_TO_PLATFORM: Record<
|
||||
[AppConnection.Humanitec]: platformManagedCredentialsNotSupported,
|
||||
[AppConnection.Postgres]: transferSqlConnectionCredentialsToPlatform as TAppConnectionTransitionCredentialsToPlatform,
|
||||
[AppConnection.MsSql]: transferSqlConnectionCredentialsToPlatform as TAppConnectionTransitionCredentialsToPlatform,
|
||||
[AppConnection.MySql]: transferSqlConnectionCredentialsToPlatform as TAppConnectionTransitionCredentialsToPlatform,
|
||||
[AppConnection.TerraformCloud]: platformManagedCredentialsNotSupported,
|
||||
[AppConnection.Camunda]: platformManagedCredentialsNotSupported,
|
||||
[AppConnection.Vercel]: platformManagedCredentialsNotSupported,
|
||||
|
||||
@@ -13,6 +13,7 @@ export const APP_CONNECTION_NAME_MAP: Record<AppConnection, string> = {
|
||||
[AppConnection.Vercel]: "Vercel",
|
||||
[AppConnection.Postgres]: "PostgreSQL",
|
||||
[AppConnection.MsSql]: "Microsoft SQL Server",
|
||||
[AppConnection.MySql]: "MySQL",
|
||||
[AppConnection.Camunda]: "Camunda",
|
||||
[AppConnection.Windmill]: "Windmill",
|
||||
[AppConnection.Auth0]: "Auth0",
|
||||
@@ -43,5 +44,6 @@ export const APP_CONNECTION_PLAN_MAP: Record<AppConnection, AppConnectionPlanTyp
|
||||
[AppConnection.LDAP]: AppConnectionPlanType.Regular,
|
||||
[AppConnection.TeamCity]: AppConnectionPlanType.Regular,
|
||||
[AppConnection.OCI]: AppConnectionPlanType.Enterprise,
|
||||
[AppConnection.OnePass]: AppConnectionPlanType.Regular
|
||||
[AppConnection.OnePass]: AppConnectionPlanType.Regular,
|
||||
[AppConnection.MySql]: AppConnectionPlanType.Regular
|
||||
};
|
||||
|
||||
@@ -55,6 +55,7 @@ import { ValidateHumanitecConnectionCredentialsSchema } from "./humanitec";
|
||||
import { humanitecConnectionService } from "./humanitec/humanitec-connection-service";
|
||||
import { ValidateLdapConnectionCredentialsSchema } from "./ldap";
|
||||
import { ValidateMsSqlConnectionCredentialsSchema } from "./mssql";
|
||||
import { ValidateMySqlConnectionCredentialsSchema } from "./mysql";
|
||||
import { ValidatePostgresConnectionCredentialsSchema } from "./postgres";
|
||||
import { ValidateTeamCityConnectionCredentialsSchema } from "./teamcity";
|
||||
import { teamcityConnectionService } from "./teamcity/teamcity-connection-service";
|
||||
@@ -86,6 +87,7 @@ const VALIDATE_APP_CONNECTION_CREDENTIALS_MAP: Record<AppConnection, TValidateAp
|
||||
[AppConnection.Vercel]: ValidateVercelConnectionCredentialsSchema,
|
||||
[AppConnection.Postgres]: ValidatePostgresConnectionCredentialsSchema,
|
||||
[AppConnection.MsSql]: ValidateMsSqlConnectionCredentialsSchema,
|
||||
[AppConnection.MySql]: ValidateMySqlConnectionCredentialsSchema,
|
||||
[AppConnection.Camunda]: ValidateCamundaConnectionCredentialsSchema,
|
||||
[AppConnection.AzureClientSecrets]: ValidateAzureClientSecretsConnectionCredentialsSchema,
|
||||
[AppConnection.Windmill]: ValidateWindmillConnectionCredentialsSchema,
|
||||
|
||||
@@ -88,6 +88,7 @@ import {
|
||||
TValidateLdapConnectionCredentialsSchema
|
||||
} from "./ldap";
|
||||
import { TMsSqlConnection, TMsSqlConnectionInput, TValidateMsSqlConnectionCredentialsSchema } from "./mssql";
|
||||
import { TMySqlConnection, TMySqlConnectionInput, TValidateMySqlConnectionCredentialsSchema } from "./mysql";
|
||||
import {
|
||||
TPostgresConnection,
|
||||
TPostgresConnectionInput,
|
||||
@@ -130,6 +131,7 @@ export type TAppConnection = { id: string } & (
|
||||
| TVercelConnection
|
||||
| TPostgresConnection
|
||||
| TMsSqlConnection
|
||||
| TMySqlConnection
|
||||
| TCamundaConnection
|
||||
| TAzureClientSecretsConnection
|
||||
| TWindmillConnection
|
||||
@@ -143,7 +145,7 @@ export type TAppConnection = { id: string } & (
|
||||
|
||||
export type TAppConnectionRaw = NonNullable<Awaited<ReturnType<TAppConnectionDALFactory["findById"]>>>;
|
||||
|
||||
export type TSqlConnection = TPostgresConnection | TMsSqlConnection;
|
||||
export type TSqlConnection = TPostgresConnection | TMsSqlConnection | TMySqlConnection;
|
||||
|
||||
export type TAppConnectionInput = { id: string } & (
|
||||
| TAwsConnectionInput
|
||||
@@ -157,6 +159,7 @@ export type TAppConnectionInput = { id: string } & (
|
||||
| TVercelConnectionInput
|
||||
| TPostgresConnectionInput
|
||||
| TMsSqlConnectionInput
|
||||
| TMySqlConnectionInput
|
||||
| TCamundaConnectionInput
|
||||
| TAzureClientSecretsConnectionInput
|
||||
| TWindmillConnectionInput
|
||||
@@ -168,7 +171,7 @@ export type TAppConnectionInput = { id: string } & (
|
||||
| TOnePassConnectionInput
|
||||
);
|
||||
|
||||
export type TSqlConnectionInput = TPostgresConnectionInput | TMsSqlConnectionInput;
|
||||
export type TSqlConnectionInput = TPostgresConnectionInput | TMsSqlConnectionInput | TMySqlConnectionInput;
|
||||
|
||||
export type TCreateAppConnectionDTO = Pick<
|
||||
TAppConnectionInput,
|
||||
@@ -211,6 +214,7 @@ export type TValidateAppConnectionCredentialsSchema =
|
||||
| TValidateHumanitecConnectionCredentialsSchema
|
||||
| TValidatePostgresConnectionCredentialsSchema
|
||||
| TValidateMsSqlConnectionCredentialsSchema
|
||||
| TValidateMySqlConnectionCredentialsSchema
|
||||
| TValidateCamundaConnectionCredentialsSchema
|
||||
| TValidateVercelConnectionCredentialsSchema
|
||||
| TValidateTerraformCloudConnectionCredentialsSchema
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
export * from "./mysql-connection-enums";
|
||||
export * from "./mysql-connection-fns";
|
||||
export * from "./mysql-connection-schemas";
|
||||
export * from "./mysql-connection-types";
|
||||
@@ -0,0 +1,3 @@
|
||||
export enum MySqlConnectionMethod {
|
||||
UsernameAndPassword = "username-and-password"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { AppConnection } from "@app/services/app-connection/app-connection-enums";
|
||||
|
||||
import { MySqlConnectionMethod } from "./mysql-connection-enums";
|
||||
|
||||
export const getMySqlConnectionListItem = () => {
|
||||
return {
|
||||
name: "MySQL" as const,
|
||||
app: AppConnection.MySql as const,
|
||||
methods: Object.values(MySqlConnectionMethod) as [MySqlConnectionMethod.UsernameAndPassword],
|
||||
supportsPlatformManagement: true as const
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,66 @@
|
||||
import z from "zod";
|
||||
|
||||
import { AppConnections } from "@app/lib/api-docs";
|
||||
import {
|
||||
BaseAppConnectionSchema,
|
||||
GenericCreateAppConnectionFieldsSchema,
|
||||
GenericUpdateAppConnectionFieldsSchema
|
||||
} from "@app/services/app-connection/app-connection-schemas";
|
||||
|
||||
import { AppConnection } from "../app-connection-enums";
|
||||
import { BaseSqlUsernameAndPasswordConnectionSchema } from "../shared/sql";
|
||||
import { MySqlConnectionMethod } from "./mysql-connection-enums";
|
||||
|
||||
export const MySqlConnectionAccessTokenCredentialsSchema = BaseSqlUsernameAndPasswordConnectionSchema;
|
||||
|
||||
const BaseMySqlConnectionSchema = BaseAppConnectionSchema.extend({ app: z.literal(AppConnection.MySql) });
|
||||
|
||||
export const MySqlConnectionSchema = BaseMySqlConnectionSchema.extend({
|
||||
method: z.literal(MySqlConnectionMethod.UsernameAndPassword),
|
||||
credentials: MySqlConnectionAccessTokenCredentialsSchema
|
||||
});
|
||||
|
||||
export const SanitizedMySqlConnectionSchema = z.discriminatedUnion("method", [
|
||||
BaseMySqlConnectionSchema.extend({
|
||||
method: z.literal(MySqlConnectionMethod.UsernameAndPassword),
|
||||
credentials: MySqlConnectionAccessTokenCredentialsSchema.pick({
|
||||
host: true,
|
||||
database: true,
|
||||
port: true,
|
||||
username: true,
|
||||
sslEnabled: true,
|
||||
sslRejectUnauthorized: true,
|
||||
sslCertificate: true
|
||||
})
|
||||
})
|
||||
]);
|
||||
|
||||
export const ValidateMySqlConnectionCredentialsSchema = z.discriminatedUnion("method", [
|
||||
z.object({
|
||||
method: z
|
||||
.literal(MySqlConnectionMethod.UsernameAndPassword)
|
||||
.describe(AppConnections.CREATE(AppConnection.MySql).method),
|
||||
credentials: MySqlConnectionAccessTokenCredentialsSchema.describe(
|
||||
AppConnections.CREATE(AppConnection.MySql).credentials
|
||||
)
|
||||
})
|
||||
]);
|
||||
|
||||
export const CreateMySqlConnectionSchema = ValidateMySqlConnectionCredentialsSchema.and(
|
||||
GenericCreateAppConnectionFieldsSchema(AppConnection.MySql, { supportsPlatformManagedCredentials: true })
|
||||
);
|
||||
|
||||
export const UpdateMySqlConnectionSchema = z
|
||||
.object({
|
||||
credentials: MySqlConnectionAccessTokenCredentialsSchema.optional().describe(
|
||||
AppConnections.UPDATE(AppConnection.MySql).credentials
|
||||
)
|
||||
})
|
||||
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.MySql, { supportsPlatformManagedCredentials: true }));
|
||||
|
||||
export const MySqlConnectionListItemSchema = z.object({
|
||||
name: z.literal("MySQL"),
|
||||
app: z.literal(AppConnection.MySql),
|
||||
methods: z.nativeEnum(MySqlConnectionMethod).array(),
|
||||
supportsPlatformManagement: z.literal(true)
|
||||
});
|
||||
@@ -0,0 +1,16 @@
|
||||
import z from "zod";
|
||||
|
||||
import { AppConnection } from "../app-connection-enums";
|
||||
import {
|
||||
CreateMySqlConnectionSchema,
|
||||
MySqlConnectionSchema,
|
||||
ValidateMySqlConnectionCredentialsSchema
|
||||
} from "./mysql-connection-schemas";
|
||||
|
||||
export type TMySqlConnection = z.infer<typeof MySqlConnectionSchema>;
|
||||
|
||||
export type TMySqlConnectionInput = z.infer<typeof CreateMySqlConnectionSchema> & {
|
||||
app: AppConnection.MySql;
|
||||
};
|
||||
|
||||
export type TValidateMySqlConnectionCredentialsSchema = typeof ValidateMySqlConnectionCredentialsSchema;
|
||||
@@ -15,7 +15,8 @@ const EXTERNAL_REQUEST_TIMEOUT = 10 * 1000;
|
||||
|
||||
const SQL_CONNECTION_CLIENT_MAP = {
|
||||
[AppConnection.Postgres]: "pg",
|
||||
[AppConnection.MsSql]: "mssql"
|
||||
[AppConnection.MsSql]: "mssql",
|
||||
[AppConnection.MySql]: "mysql2"
|
||||
};
|
||||
|
||||
const getConnectionConfig = ({
|
||||
@@ -45,6 +46,17 @@ const getConnectionConfig = ({
|
||||
: { encrypt: false }
|
||||
};
|
||||
}
|
||||
case AppConnection.MySql: {
|
||||
return {
|
||||
ssl: sslEnabled
|
||||
? {
|
||||
rejectUnauthorized: sslRejectUnauthorized,
|
||||
ca: sslCertificate,
|
||||
servername: host
|
||||
}
|
||||
: false
|
||||
};
|
||||
}
|
||||
default:
|
||||
throw new Error(`Unhandled SQL Connection Config: ${app as AppConnection}`);
|
||||
}
|
||||
@@ -101,7 +113,8 @@ export const SQL_CONNECTION_ALTER_LOGIN_STATEMENT: Record<
|
||||
(credentials: TSqlCredentialsRotationGeneratedCredentials[number]) => [string, Knex.RawBinding]
|
||||
> = {
|
||||
[AppConnection.Postgres]: ({ username, password }) => [`ALTER USER ?? WITH PASSWORD '${password}';`, [username]],
|
||||
[AppConnection.MsSql]: ({ username, password }) => [`ALTER LOGIN ?? WITH PASSWORD = '${password}';`, [username]]
|
||||
[AppConnection.MsSql]: ({ username, password }) => [`ALTER LOGIN ?? WITH PASSWORD = '${password}';`, [username]],
|
||||
[AppConnection.MySql]: ({ username, password }) => [`ALTER USER ??@'%' IDENTIFIED BY '${password}';`, [username]]
|
||||
};
|
||||
|
||||
export const transferSqlConnectionCredentialsToPlatform = async (
|
||||
|
||||
Reference in New Issue
Block a user