mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-16 02:16:34 +00:00
Merge branch 'heads/main' into daniel/redis-secret-rotation-new
This commit is contained in:
@@ -320,10 +320,20 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
|
||||
.array(),
|
||||
secretPath: z.string(),
|
||||
commits: secretRawSchema
|
||||
.omit({ _id: true, environment: true, workspace: true, type: true, version: true, secretValue: true })
|
||||
.omit({
|
||||
_id: true,
|
||||
environment: true,
|
||||
workspace: true,
|
||||
type: true,
|
||||
version: true,
|
||||
secretValue: true,
|
||||
secretComment: true
|
||||
})
|
||||
.extend({
|
||||
secretValueHidden: z.boolean(),
|
||||
secretValue: z.string().optional(),
|
||||
secretComment: z.string().optional(),
|
||||
skipMultilineEncoding: z.boolean().nullish(),
|
||||
isRotatedSecret: z.boolean().optional(),
|
||||
op: z.string(),
|
||||
tags: SanitizedTagSchema.array().optional(),
|
||||
@@ -348,7 +358,8 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
|
||||
secretValueHidden: z.boolean(),
|
||||
secretComment: z.string().optional(),
|
||||
tags: SanitizedTagSchema.array().optional(),
|
||||
secretMetadata: ResourceMetadataSchema.nullish()
|
||||
secretMetadata: ResourceMetadataSchema.nullish(),
|
||||
skipMultilineEncoding: z.boolean().nullish()
|
||||
})
|
||||
.optional()
|
||||
})
|
||||
|
||||
@@ -407,6 +407,14 @@ export enum EventType {
|
||||
SECRET_SYNC_SYNC_SECRETS = "secret-sync-sync-secrets",
|
||||
SECRET_SYNC_IMPORT_SECRETS = "secret-sync-import-secrets",
|
||||
SECRET_SYNC_REMOVE_SECRETS = "secret-sync-remove-secrets",
|
||||
GET_PKI_SYNCS = "get-pki-syncs",
|
||||
GET_PKI_SYNC = "get-pki-sync",
|
||||
CREATE_PKI_SYNC = "create-pki-sync",
|
||||
UPDATE_PKI_SYNC = "update-pki-sync",
|
||||
DELETE_PKI_SYNC = "delete-pki-sync",
|
||||
PKI_SYNC_SYNC_CERTIFICATES = "pki-sync-sync-certificates",
|
||||
PKI_SYNC_IMPORT_CERTIFICATES = "pki-sync-import-certificates",
|
||||
PKI_SYNC_REMOVE_CERTIFICATES = "pki-sync-remove-certificates",
|
||||
OIDC_GROUP_MEMBERSHIP_MAPPING_ASSIGN_USER = "oidc-group-membership-mapping-assign-user",
|
||||
OIDC_GROUP_MEMBERSHIP_MAPPING_REMOVE_USER = "oidc-group-membership-mapping-remove-user",
|
||||
CREATE_KMIP_CLIENT = "create-kmip-client",
|
||||
@@ -2959,6 +2967,77 @@ interface SecretSyncRemoveSecretsEvent {
|
||||
};
|
||||
}
|
||||
|
||||
interface GetPkiSyncsEvent {
|
||||
type: EventType.GET_PKI_SYNCS;
|
||||
metadata: {
|
||||
projectId: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface GetPkiSyncEvent {
|
||||
type: EventType.GET_PKI_SYNC;
|
||||
metadata: {
|
||||
destination: string;
|
||||
syncId: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface CreatePkiSyncEvent {
|
||||
type: EventType.CREATE_PKI_SYNC;
|
||||
metadata: {
|
||||
pkiSyncId: string;
|
||||
name: string;
|
||||
destination: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface UpdatePkiSyncEvent {
|
||||
type: EventType.UPDATE_PKI_SYNC;
|
||||
metadata: {
|
||||
pkiSyncId: string;
|
||||
name: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface DeletePkiSyncEvent {
|
||||
type: EventType.DELETE_PKI_SYNC;
|
||||
metadata: {
|
||||
pkiSyncId: string;
|
||||
name: string;
|
||||
destination: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface PkiSyncSyncCertificatesEvent {
|
||||
type: EventType.PKI_SYNC_SYNC_CERTIFICATES;
|
||||
metadata: {
|
||||
syncId: string;
|
||||
syncMessage: string | null;
|
||||
jobId: string;
|
||||
jobRanAt: Date;
|
||||
};
|
||||
}
|
||||
|
||||
interface PkiSyncImportCertificatesEvent {
|
||||
type: EventType.PKI_SYNC_IMPORT_CERTIFICATES;
|
||||
metadata: {
|
||||
syncId: string;
|
||||
importMessage: string | null;
|
||||
jobId: string;
|
||||
jobRanAt: Date;
|
||||
};
|
||||
}
|
||||
|
||||
interface PkiSyncRemoveCertificatesEvent {
|
||||
type: EventType.PKI_SYNC_REMOVE_CERTIFICATES;
|
||||
metadata: {
|
||||
syncId: string;
|
||||
removeMessage: string | null;
|
||||
jobId: string;
|
||||
jobRanAt: Date;
|
||||
};
|
||||
}
|
||||
|
||||
interface OidcGroupMembershipMappingAssignUserEvent {
|
||||
type: EventType.OIDC_GROUP_MEMBERSHIP_MAPPING_ASSIGN_USER;
|
||||
metadata: {
|
||||
@@ -3859,6 +3938,14 @@ export type Event =
|
||||
| SecretSyncSyncSecretsEvent
|
||||
| SecretSyncImportSecretsEvent
|
||||
| SecretSyncRemoveSecretsEvent
|
||||
| GetPkiSyncsEvent
|
||||
| GetPkiSyncEvent
|
||||
| CreatePkiSyncEvent
|
||||
| UpdatePkiSyncEvent
|
||||
| DeletePkiSyncEvent
|
||||
| PkiSyncSyncCertificatesEvent
|
||||
| PkiSyncImportCertificatesEvent
|
||||
| PkiSyncRemoveCertificatesEvent
|
||||
| OidcGroupMembershipMappingAssignUserEvent
|
||||
| OidcGroupMembershipMappingRemoveUserEvent
|
||||
| CreateKmipClientEvent
|
||||
|
||||
@@ -31,6 +31,7 @@ export const getDefaultOnPremFeatures = () => {
|
||||
caCrl: false,
|
||||
sshHostGroups: false,
|
||||
enterpriseSecretSyncs: false,
|
||||
enterpriseCertificateSyncs: false,
|
||||
enterpriseAppConnections: true,
|
||||
machineIdentityAuthTemplates: false
|
||||
};
|
||||
|
||||
@@ -62,6 +62,7 @@ export const getDefaultOnPremFeatures = (): TFeatureSet => ({
|
||||
sshHostGroups: false,
|
||||
secretScanning: false,
|
||||
enterpriseSecretSyncs: false,
|
||||
enterpriseCertificateSyncs: false,
|
||||
enterpriseAppConnections: false,
|
||||
fips: false,
|
||||
eventSubscriptions: false,
|
||||
|
||||
@@ -75,6 +75,7 @@ export type TFeatureSet = {
|
||||
sshHostGroups: false;
|
||||
secretScanning: false;
|
||||
enterpriseSecretSyncs: false;
|
||||
enterpriseCertificateSyncs: false;
|
||||
enterpriseAppConnections: false;
|
||||
machineIdentityAuthTemplates: false;
|
||||
fips: false;
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
ProjectPermissionKmipActions,
|
||||
ProjectPermissionMemberActions,
|
||||
ProjectPermissionPkiSubscriberActions,
|
||||
ProjectPermissionPkiSyncActions,
|
||||
ProjectPermissionPkiTemplateActions,
|
||||
ProjectPermissionSecretActions,
|
||||
ProjectPermissionSecretEventActions,
|
||||
@@ -209,6 +210,19 @@ const buildAdminPermissionRules = () => {
|
||||
ProjectPermissionSub.SecretSyncs
|
||||
);
|
||||
|
||||
can(
|
||||
[
|
||||
ProjectPermissionPkiSyncActions.Create,
|
||||
ProjectPermissionPkiSyncActions.Edit,
|
||||
ProjectPermissionPkiSyncActions.Delete,
|
||||
ProjectPermissionPkiSyncActions.Read,
|
||||
ProjectPermissionPkiSyncActions.SyncCertificates,
|
||||
ProjectPermissionPkiSyncActions.ImportCertificates,
|
||||
ProjectPermissionPkiSyncActions.RemoveCertificates
|
||||
],
|
||||
ProjectPermissionSub.PkiSyncs
|
||||
);
|
||||
|
||||
can(
|
||||
[
|
||||
ProjectPermissionKmipActions.CreateClients,
|
||||
@@ -462,6 +476,19 @@ const buildMemberPermissionRules = () => {
|
||||
ProjectPermissionSub.SecretSyncs
|
||||
);
|
||||
|
||||
can(
|
||||
[
|
||||
ProjectPermissionPkiSyncActions.Create,
|
||||
ProjectPermissionPkiSyncActions.Edit,
|
||||
ProjectPermissionPkiSyncActions.Delete,
|
||||
ProjectPermissionPkiSyncActions.Read,
|
||||
ProjectPermissionPkiSyncActions.SyncCertificates,
|
||||
ProjectPermissionPkiSyncActions.ImportCertificates,
|
||||
ProjectPermissionPkiSyncActions.RemoveCertificates
|
||||
],
|
||||
ProjectPermissionSub.PkiSyncs
|
||||
);
|
||||
|
||||
can(
|
||||
[
|
||||
ProjectPermissionSecretScanningDataSourceActions.Read,
|
||||
@@ -526,6 +553,7 @@ const buildViewerPermissionRules = () => {
|
||||
can(ProjectPermissionActions.Read, ProjectPermissionSub.SshCertificates);
|
||||
can(ProjectPermissionActions.Read, ProjectPermissionSub.SshCertificateTemplates);
|
||||
can(ProjectPermissionSecretSyncActions.Read, ProjectPermissionSub.SecretSyncs);
|
||||
can(ProjectPermissionPkiSyncActions.Read, ProjectPermissionSub.PkiSyncs);
|
||||
can(ProjectPermissionCommitsActions.Read, ProjectPermissionSub.Commits);
|
||||
|
||||
can(
|
||||
|
||||
@@ -120,6 +120,16 @@ export enum ProjectPermissionSecretSyncActions {
|
||||
RemoveSecrets = "remove-secrets"
|
||||
}
|
||||
|
||||
export enum ProjectPermissionPkiSyncActions {
|
||||
Read = "read",
|
||||
Create = "create",
|
||||
Edit = "edit",
|
||||
Delete = "delete",
|
||||
SyncCertificates = "sync-certificates",
|
||||
ImportCertificates = "import-certificates",
|
||||
RemoveCertificates = "remove-certificates"
|
||||
}
|
||||
|
||||
export enum ProjectPermissionSecretRotationActions {
|
||||
Read = "read",
|
||||
ReadGeneratedCredentials = "read-generated-credentials",
|
||||
@@ -212,6 +222,7 @@ export enum ProjectPermissionSub {
|
||||
Kms = "kms",
|
||||
Cmek = "cmek",
|
||||
SecretSyncs = "secret-syncs",
|
||||
PkiSyncs = "pki-syncs",
|
||||
Kmip = "kmip",
|
||||
SecretScanningDataSources = "secret-scanning-data-sources",
|
||||
SecretScanningFindings = "secret-scanning-findings",
|
||||
@@ -244,6 +255,10 @@ export type SecretSyncSubjectFields = {
|
||||
secretPath: string;
|
||||
};
|
||||
|
||||
export type PkiSyncSubjectFields = {
|
||||
subscriberName: string;
|
||||
};
|
||||
|
||||
export type DynamicSecretSubjectFields = {
|
||||
environment: string;
|
||||
secretPath: string;
|
||||
@@ -308,6 +323,10 @@ export type ProjectPermissionSet =
|
||||
ProjectPermissionSecretSyncActions,
|
||||
ProjectPermissionSub.SecretSyncs | (ForcedSubject<ProjectPermissionSub.SecretSyncs> & SecretSyncSubjectFields)
|
||||
]
|
||||
| [
|
||||
ProjectPermissionPkiSyncActions,
|
||||
ProjectPermissionSub.PkiSyncs | (ForcedSubject<ProjectPermissionSub.PkiSyncs> & PkiSyncSubjectFields)
|
||||
]
|
||||
| [
|
||||
ProjectPermissionActions,
|
||||
(
|
||||
@@ -480,6 +499,22 @@ const SecretSyncConditionV2Schema = z
|
||||
})
|
||||
.partial();
|
||||
|
||||
const PkiSyncConditionSchema = z
|
||||
.object({
|
||||
subscriberName: z.union([
|
||||
z.string(),
|
||||
z
|
||||
.object({
|
||||
[PermissionConditionOperators.$EQ]: PermissionConditionSchema[PermissionConditionOperators.$EQ],
|
||||
[PermissionConditionOperators.$NEQ]: PermissionConditionSchema[PermissionConditionOperators.$NEQ],
|
||||
[PermissionConditionOperators.$IN]: PermissionConditionSchema[PermissionConditionOperators.$IN],
|
||||
[PermissionConditionOperators.$GLOB]: PermissionConditionSchema[PermissionConditionOperators.$GLOB]
|
||||
})
|
||||
.partial()
|
||||
])
|
||||
})
|
||||
.partial();
|
||||
|
||||
const SecretImportConditionSchema = z
|
||||
.object({
|
||||
environment: z.union([
|
||||
@@ -943,6 +978,16 @@ export const ProjectPermissionV2Schema = z.discriminatedUnion("subject", [
|
||||
"When specified, only matching conditions will be allowed to access given resource."
|
||||
).optional()
|
||||
}),
|
||||
z.object({
|
||||
subject: z.literal(ProjectPermissionSub.PkiSyncs).describe("The entity this permission pertains to."),
|
||||
inverted: z.boolean().optional().describe("Whether rule allows or forbids."),
|
||||
action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionPkiSyncActions).describe(
|
||||
"Describe what action an entity can take."
|
||||
),
|
||||
conditions: PkiSyncConditionSchema.describe(
|
||||
"When specified, only matching conditions will be allowed to access given resource."
|
||||
).optional()
|
||||
}),
|
||||
z.object({
|
||||
subject: z.literal(ProjectPermissionSub.SecretEvents).describe("The entity this permission pertains to."),
|
||||
inverted: z.boolean().optional().describe("Whether rule allows or forbids."),
|
||||
|
||||
+12
-3
@@ -284,7 +284,8 @@ export const secretApprovalRequestSecretDALFactory = (db: TDbClient) => {
|
||||
db.ref("version").withSchema(TableName.SecretVersionV2).as("secVerVersion"),
|
||||
db.ref("key").withSchema(TableName.SecretVersionV2).as("secVerKey"),
|
||||
db.ref("encryptedValue").withSchema(TableName.SecretVersionV2).as("secVerValue"),
|
||||
db.ref("encryptedComment").withSchema(TableName.SecretVersionV2).as("secVerComment")
|
||||
db.ref("encryptedComment").withSchema(TableName.SecretVersionV2).as("secVerComment"),
|
||||
db.ref("skipMultilineEncoding").withSchema(TableName.SecretVersionV2).as("secVerSkipMultilineEncoding")
|
||||
)
|
||||
.select(
|
||||
db.ref("id").withSchema(TableName.ResourceMetadata).as("metadataId"),
|
||||
@@ -326,14 +327,22 @@ export const secretApprovalRequestSecretDALFactory = (db: TDbClient) => {
|
||||
{
|
||||
key: "secretVersion",
|
||||
label: "secretVersion" as const,
|
||||
mapper: ({ secretVersion, secVerVersion, secVerKey, secVerValue, secVerComment }) =>
|
||||
mapper: ({
|
||||
secretVersion,
|
||||
secVerVersion,
|
||||
secVerKey,
|
||||
secVerValue,
|
||||
secVerComment,
|
||||
secVerSkipMultilineEncoding
|
||||
}) =>
|
||||
secretVersion
|
||||
? {
|
||||
version: secVerVersion,
|
||||
id: secretVersion,
|
||||
key: secVerKey,
|
||||
encryptedValue: secVerValue,
|
||||
encryptedComment: secVerComment
|
||||
encryptedComment: secVerComment,
|
||||
skipMultilineEncoding: secVerSkipMultilineEncoding
|
||||
}
|
||||
: undefined,
|
||||
childrenMapper: [
|
||||
|
||||
+20
-12
@@ -337,12 +337,17 @@ export const secretApprovalRequestServiceFactory = ({
|
||||
? INFISICAL_SECRET_VALUE_HIDDEN_MASK
|
||||
: el.secret && el.secret.isRotatedSecret
|
||||
? undefined
|
||||
: el.encryptedValue
|
||||
: el.encryptedValue !== undefined && el.encryptedValue !== null
|
||||
? secretManagerDecryptor({ cipherTextBlob: el.encryptedValue }).toString()
|
||||
: "",
|
||||
secretComment: el.encryptedComment
|
||||
? secretManagerDecryptor({ cipherTextBlob: el.encryptedComment }).toString()
|
||||
: "",
|
||||
: undefined,
|
||||
secretComment:
|
||||
el.encryptedComment !== undefined && el.encryptedComment !== null
|
||||
? secretManagerDecryptor({ cipherTextBlob: el.encryptedComment }).toString()
|
||||
: undefined,
|
||||
skipMultilineEncoding:
|
||||
el.skipMultilineEncoding !== undefined && el.skipMultilineEncoding !== null
|
||||
? el.skipMultilineEncoding
|
||||
: undefined,
|
||||
secret: el.secret
|
||||
? {
|
||||
secretKey: el.secret.key,
|
||||
@@ -394,7 +399,8 @@ export const secretApprovalRequestServiceFactory = ({
|
||||
? secretManagerDecryptor({ cipherTextBlob: el.secretVersion.encryptedComment }).toString()
|
||||
: "",
|
||||
tags: el.secretVersion.tags,
|
||||
secretMetadata: el.oldSecretMetadata as ResourceMetadataDTO
|
||||
secretMetadata: el.oldSecretMetadata as ResourceMetadataDTO,
|
||||
skipMultilineEncoding: el.secretVersion.skipMultilineEncoding
|
||||
}
|
||||
: undefined
|
||||
}));
|
||||
@@ -733,9 +739,9 @@ export const secretApprovalRequestServiceFactory = ({
|
||||
tx,
|
||||
inputSecrets: secretUpdationCommits.map((el) => {
|
||||
const encryptedValue =
|
||||
!el.secret?.isRotatedSecret && typeof el.encryptedValue !== "undefined"
|
||||
!el.secret?.isRotatedSecret && el.encryptedValue !== null && el.encryptedValue !== undefined
|
||||
? {
|
||||
encryptedValue: el.encryptedValue as Buffer,
|
||||
encryptedValue: el.encryptedValue,
|
||||
references: el.encryptedValue
|
||||
? getAllSecretReferencesV2Bridge(
|
||||
secretManagerDecryptor({
|
||||
@@ -749,9 +755,9 @@ export const secretApprovalRequestServiceFactory = ({
|
||||
filter: { id: el.secretId as string, type: SecretType.Shared },
|
||||
data: {
|
||||
reminderRepeatDays: el.reminderRepeatDays,
|
||||
encryptedComment: el.encryptedComment,
|
||||
encryptedComment: el.encryptedComment !== null ? el.encryptedComment : undefined,
|
||||
reminderNote: el.reminderNote,
|
||||
skipMultilineEncoding: el.skipMultilineEncoding,
|
||||
skipMultilineEncoding: el.skipMultilineEncoding !== null ? el.skipMultilineEncoding : undefined,
|
||||
key: el.key,
|
||||
tags: el?.tags.map(({ id }) => id),
|
||||
secretMetadata: el.secretMetadata as ResourceMetadataDTO,
|
||||
@@ -1633,11 +1639,13 @@ export const secretApprovalRequestServiceFactory = ({
|
||||
key: newSecretName || secretKey,
|
||||
encryptedComment: setKnexStringValue(
|
||||
secretComment,
|
||||
(value) => secretManagerEncryptor({ plainText: Buffer.from(value) }).cipherTextBlob
|
||||
(value) => secretManagerEncryptor({ plainText: Buffer.from(value) }).cipherTextBlob,
|
||||
true // scott: we need to encrypt empty string on update to differentiate not updating comment vs clearing comment
|
||||
),
|
||||
encryptedValue: setKnexStringValue(
|
||||
secretValue,
|
||||
(value) => secretManagerEncryptor({ plainText: Buffer.from(value) }).cipherTextBlob
|
||||
(value) => secretManagerEncryptor({ plainText: Buffer.from(value) }).cipherTextBlob,
|
||||
true // scott: we need to encrypt empty string on update to differentiate not updating value vs clearing value
|
||||
),
|
||||
reminderRepeatDays,
|
||||
reminderNote,
|
||||
|
||||
Reference in New Issue
Block a user