diff --git a/backend/src/services/secret-sync/secret-sync-fns.ts b/backend/src/services/secret-sync/secret-sync-fns.ts index 8e99aabb8..ba3a79c50 100644 --- a/backend/src/services/secret-sync/secret-sync-fns.ts +++ b/backend/src/services/secret-sync/secret-sync-fns.ts @@ -86,10 +86,17 @@ const addSchema = (unprocessedSecretMap: TSecretMap, environment: string, schema }; // Strip schema from secret keys -const stripSchema = (unprocessedSecretMap: TSecretMap, schema?: string): TSecretMap => { +const stripSchema = (unprocessedSecretMap: TSecretMap, environment: string, schema?: string): TSecretMap => { if (!schema) return unprocessedSecretMap; - const [prefix, suffix] = schema.split("{{secretKey}}"); + const compiledSchemaPattern = handlebars.compile(schema)({ + secretKey: "{{secretKey}}", // Keep secretKey + environment + }); + + const parts = compiledSchemaPattern.split("{{secretKey}}"); + const prefix = parts[0]; + const suffix = parts[parts.length - 1]; const strippedMap: TSecretMap = {}; @@ -278,10 +285,9 @@ export const SecretSyncFns = { ); } - return stripSchema( - filterForSchema(secretMap, secretSync.environment?.slug || "", secretSync.syncOptions.keySchema), - secretSync.syncOptions.keySchema - ); + const filtered = filterForSchema(secretMap, secretSync.environment?.slug || "", secretSync.syncOptions.keySchema); + const stripped = stripSchema(filtered, secretSync.environment?.slug || "", secretSync.syncOptions.keySchema); + return stripped; }, removeSecrets: ( secretSync: TSecretSyncWithCredentials, diff --git a/docs/integrations/secret-syncs/overview.mdx b/docs/integrations/secret-syncs/overview.mdx index 65ec4e6cf..937c8d826 100644 --- a/docs/integrations/secret-syncs/overview.mdx +++ b/docs/integrations/secret-syncs/overview.mdx @@ -101,6 +101,10 @@ Key Schemas transform your secret keys by applying a prefix, suffix, or format p Any destination secrets which do not match the schema will not get deleted or updated by Infisical. +Key Schemas use handlebars syntax to define dynamic values. Here's a full list of available variables: +- `{{secretKey}}` - The key of the secret +- `{{environment}}` - The environment which the secret is in (e.g. dev, staging, prod) + **Example:** - Infisical key: `SECRET_1` - Schema: `INFISICAL_{{secretKey}}` diff --git a/frontend/src/components/secret-syncs/forms/SecretSyncOptionsFields/SecretSyncOptionsFields.tsx b/frontend/src/components/secret-syncs/forms/SecretSyncOptionsFields/SecretSyncOptionsFields.tsx index 6050cab21..7536d1192 100644 --- a/frontend/src/components/secret-syncs/forms/SecretSyncOptionsFields/SecretSyncOptionsFields.tsx +++ b/frontend/src/components/secret-syncs/forms/SecretSyncOptionsFields/SecretSyncOptionsFields.tsx @@ -131,7 +131,27 @@ export const SecretSyncOptionsFields = ({ hideInitialSync }: Props) => { render={({ field: { value, onChange }, fieldState: { error } }) => ( + + When a secret is synced, values will be injected into the key schema before it + reaches the destination. This is useful for organization. + + +
+ Available keys: + +
+ + } isError={Boolean(error)} isOptional errorText={error?.message}