mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Merge pull request #3722 from Infisical/feat/dynamicSecretIdentityName
Add identityName to Dynamic Secrets userName template
This commit is contained in:
@@ -23,7 +23,10 @@ const validateUsernameTemplateCharacters = characterValidator([
|
|||||||
CharacterType.CloseBrace,
|
CharacterType.CloseBrace,
|
||||||
CharacterType.CloseBracket,
|
CharacterType.CloseBracket,
|
||||||
CharacterType.OpenBracket,
|
CharacterType.OpenBracket,
|
||||||
CharacterType.Fullstop
|
CharacterType.Fullstop,
|
||||||
|
CharacterType.SingleQuote,
|
||||||
|
CharacterType.Spaces,
|
||||||
|
CharacterType.Pipe
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const userTemplateSchema = z
|
const userTemplateSchema = z
|
||||||
@@ -33,7 +36,7 @@ const userTemplateSchema = z
|
|||||||
.refine((el) => validateUsernameTemplateCharacters(el))
|
.refine((el) => validateUsernameTemplateCharacters(el))
|
||||||
.refine((el) =>
|
.refine((el) =>
|
||||||
isValidHandleBarTemplate(el, {
|
isValidHandleBarTemplate(el, {
|
||||||
allowedExpressions: (val) => ["randomUsername", "unixTimestamp"].includes(val)
|
allowedExpressions: (val) => ["randomUsername", "unixTimestamp", "identity.name"].includes(val)
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { ForbiddenError, subject } from "@casl/ability";
|
import { ForbiddenError, subject } from "@casl/ability";
|
||||||
|
import RE2 from "re2";
|
||||||
|
|
||||||
import { ActionProjectType } from "@app/db/schemas";
|
import { ActionProjectType } from "@app/db/schemas";
|
||||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||||
@@ -11,10 +12,13 @@ import { getConfig } from "@app/lib/config/env";
|
|||||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
||||||
import { logger } from "@app/lib/logger";
|
import { logger } from "@app/lib/logger";
|
||||||
import { ms } from "@app/lib/ms";
|
import { ms } from "@app/lib/ms";
|
||||||
|
import { ActorType } from "@app/services/auth/auth-type";
|
||||||
|
import { TIdentityDALFactory } from "@app/services/identity/identity-dal";
|
||||||
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
||||||
import { KmsDataKey } from "@app/services/kms/kms-types";
|
import { KmsDataKey } from "@app/services/kms/kms-types";
|
||||||
import { TProjectDALFactory } from "@app/services/project/project-dal";
|
import { TProjectDALFactory } from "@app/services/project/project-dal";
|
||||||
import { TSecretFolderDALFactory } from "@app/services/secret-folder/secret-folder-dal";
|
import { TSecretFolderDALFactory } from "@app/services/secret-folder/secret-folder-dal";
|
||||||
|
import { TUserDALFactory } from "@app/services/user/user-dal";
|
||||||
|
|
||||||
import { TDynamicSecretDALFactory } from "../dynamic-secret/dynamic-secret-dal";
|
import { TDynamicSecretDALFactory } from "../dynamic-secret/dynamic-secret-dal";
|
||||||
import { DynamicSecretProviders, TDynamicProviderFns } from "../dynamic-secret/providers/models";
|
import { DynamicSecretProviders, TDynamicProviderFns } from "../dynamic-secret/providers/models";
|
||||||
@@ -39,6 +43,8 @@ type TDynamicSecretLeaseServiceFactoryDep = {
|
|||||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
||||||
projectDAL: Pick<TProjectDALFactory, "findProjectBySlug">;
|
projectDAL: Pick<TProjectDALFactory, "findProjectBySlug">;
|
||||||
kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">;
|
kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">;
|
||||||
|
userDAL: Pick<TUserDALFactory, "findById">;
|
||||||
|
identityDAL: TIdentityDALFactory;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TDynamicSecretLeaseServiceFactory = ReturnType<typeof dynamicSecretLeaseServiceFactory>;
|
export type TDynamicSecretLeaseServiceFactory = ReturnType<typeof dynamicSecretLeaseServiceFactory>;
|
||||||
@@ -52,8 +58,16 @@ export const dynamicSecretLeaseServiceFactory = ({
|
|||||||
dynamicSecretQueueService,
|
dynamicSecretQueueService,
|
||||||
projectDAL,
|
projectDAL,
|
||||||
licenseService,
|
licenseService,
|
||||||
kmsService
|
kmsService,
|
||||||
|
userDAL,
|
||||||
|
identityDAL
|
||||||
}: TDynamicSecretLeaseServiceFactoryDep) => {
|
}: TDynamicSecretLeaseServiceFactoryDep) => {
|
||||||
|
const extractEmailUsername = (email: string) => {
|
||||||
|
const regex = new RE2(/^([^@]+)/);
|
||||||
|
const match = email.match(regex);
|
||||||
|
return match ? match[1] : email;
|
||||||
|
};
|
||||||
|
|
||||||
const create = async ({
|
const create = async ({
|
||||||
environmentSlug,
|
environmentSlug,
|
||||||
path,
|
path,
|
||||||
@@ -132,10 +146,23 @@ export const dynamicSecretLeaseServiceFactory = ({
|
|||||||
|
|
||||||
let result;
|
let result;
|
||||||
try {
|
try {
|
||||||
|
const identity: { name: string } = { name: "" };
|
||||||
|
if (actor === ActorType.USER) {
|
||||||
|
const user = await userDAL.findById(actorId);
|
||||||
|
if (user) {
|
||||||
|
identity.name = extractEmailUsername(user.username);
|
||||||
|
}
|
||||||
|
} else if (actor === ActorType.Machine) {
|
||||||
|
const machineIdentity = await identityDAL.findById(actorId);
|
||||||
|
if (machineIdentity) {
|
||||||
|
identity.name = machineIdentity.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
result = await selectedProvider.create({
|
result = await selectedProvider.create({
|
||||||
inputs: decryptedStoredInput,
|
inputs: decryptedStoredInput,
|
||||||
expireAt: expireAt.getTime(),
|
expireAt: expireAt.getTime(),
|
||||||
usernameTemplate: dynamicSecretCfg.usernameTemplate,
|
usernameTemplate: dynamicSecretCfg.usernameTemplate,
|
||||||
|
identity,
|
||||||
metadata: { projectId }
|
metadata: { projectId }
|
||||||
});
|
});
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { BadRequestError } from "@app/lib/errors";
|
|||||||
import { validateHandlebarTemplate } from "@app/lib/template/validate-handlebars";
|
import { validateHandlebarTemplate } from "@app/lib/template/validate-handlebars";
|
||||||
|
|
||||||
import { DynamicSecretAwsElastiCacheSchema, TDynamicProviderFns } from "./models";
|
import { DynamicSecretAwsElastiCacheSchema, TDynamicProviderFns } from "./models";
|
||||||
|
import { compileUsernameTemplate } from "./templateUtils";
|
||||||
|
|
||||||
const CreateElastiCacheUserSchema = z.object({
|
const CreateElastiCacheUserSchema = z.object({
|
||||||
UserId: z.string().trim().min(1),
|
UserId: z.string().trim().min(1),
|
||||||
@@ -132,14 +133,14 @@ const generatePassword = () => {
|
|||||||
return customAlphabet(charset, 64)();
|
return customAlphabet(charset, 64)();
|
||||||
};
|
};
|
||||||
|
|
||||||
const generateUsername = (usernameTemplate?: string | null) => {
|
const generateUsername = (usernameTemplate?: string | null, identity?: { name: string }) => {
|
||||||
const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-";
|
const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-";
|
||||||
const randomUsername = `inf-${customAlphabet(charset, 32)()}`;
|
const randomUsername = `inf-${customAlphabet(charset, 32)()}`;
|
||||||
if (!usernameTemplate) return randomUsername;
|
if (!usernameTemplate) return randomUsername;
|
||||||
|
return compileUsernameTemplate({
|
||||||
return handlebars.compile(usernameTemplate)({
|
usernameTemplate,
|
||||||
randomUsername,
|
randomUsername,
|
||||||
unixTimestamp: Math.floor(Date.now() / 100)
|
identity
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -174,14 +175,21 @@ export const AwsElastiCacheDatabaseProvider = (): TDynamicProviderFns => {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const create = async (data: { inputs: unknown; expireAt: number; usernameTemplate?: string | null }) => {
|
const create = async (data: {
|
||||||
const { inputs, expireAt, usernameTemplate } = data;
|
inputs: unknown;
|
||||||
|
expireAt: number;
|
||||||
|
usernameTemplate?: string | null;
|
||||||
|
identity?: {
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
}) => {
|
||||||
|
const { inputs, expireAt, usernameTemplate, identity } = data;
|
||||||
const providerInputs = await validateProviderInputs(inputs);
|
const providerInputs = await validateProviderInputs(inputs);
|
||||||
if (!(await validateConnection(providerInputs))) {
|
if (!(await validateConnection(providerInputs))) {
|
||||||
throw new BadRequestError({ message: "Failed to establish connection" });
|
throw new BadRequestError({ message: "Failed to establish connection" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const leaseUsername = generateUsername(usernameTemplate);
|
const leaseUsername = generateUsername(usernameTemplate, identity);
|
||||||
const leasePassword = generatePassword();
|
const leasePassword = generatePassword();
|
||||||
const leaseExpiration = new Date(expireAt).toISOString();
|
const leaseExpiration = new Date(expireAt).toISOString();
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import {
|
|||||||
} from "@aws-sdk/client-iam";
|
} from "@aws-sdk/client-iam";
|
||||||
import { AssumeRoleCommand, STSClient } from "@aws-sdk/client-sts";
|
import { AssumeRoleCommand, STSClient } from "@aws-sdk/client-sts";
|
||||||
import { randomUUID } from "crypto";
|
import { randomUUID } from "crypto";
|
||||||
import handlebars from "handlebars";
|
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
@@ -26,14 +25,16 @@ import { BadRequestError } from "@app/lib/errors";
|
|||||||
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
||||||
|
|
||||||
import { AwsIamAuthType, DynamicSecretAwsIamSchema, TDynamicProviderFns } from "./models";
|
import { AwsIamAuthType, DynamicSecretAwsIamSchema, TDynamicProviderFns } from "./models";
|
||||||
|
import { compileUsernameTemplate } from "./templateUtils";
|
||||||
|
|
||||||
const generateUsername = (usernameTemplate?: string | null) => {
|
const generateUsername = (usernameTemplate?: string | null, identity?: { name: string }) => {
|
||||||
const randomUsername = alphaNumericNanoId(32);
|
const randomUsername = alphaNumericNanoId(32);
|
||||||
if (!usernameTemplate) return randomUsername;
|
if (!usernameTemplate) return randomUsername;
|
||||||
|
|
||||||
return handlebars.compile(usernameTemplate)({
|
return compileUsernameTemplate({
|
||||||
|
usernameTemplate,
|
||||||
randomUsername,
|
randomUsername,
|
||||||
unixTimestamp: Math.floor(Date.now() / 100)
|
identity
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -115,14 +116,17 @@ export const AwsIamProvider = (): TDynamicProviderFns => {
|
|||||||
inputs: unknown;
|
inputs: unknown;
|
||||||
expireAt: number;
|
expireAt: number;
|
||||||
usernameTemplate?: string | null;
|
usernameTemplate?: string | null;
|
||||||
|
identity?: {
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
metadata: { projectId: string };
|
metadata: { projectId: string };
|
||||||
}) => {
|
}) => {
|
||||||
const { inputs, usernameTemplate, metadata } = data;
|
const { inputs, usernameTemplate, metadata, identity } = data;
|
||||||
|
|
||||||
const providerInputs = await validateProviderInputs(inputs);
|
const providerInputs = await validateProviderInputs(inputs);
|
||||||
const client = await $getClient(providerInputs, metadata.projectId);
|
const client = await $getClient(providerInputs, metadata.projectId);
|
||||||
|
|
||||||
const username = generateUsername(usernameTemplate);
|
const username = generateUsername(usernameTemplate, identity);
|
||||||
const { policyArns, userGroups, policyDocument, awsPath, permissionBoundaryPolicyArn } = providerInputs;
|
const { policyArns, userGroups, policyDocument, awsPath, permissionBoundaryPolicyArn } = providerInputs;
|
||||||
const createUserRes = await client.send(
|
const createUserRes = await client.send(
|
||||||
new CreateUserCommand({
|
new CreateUserCommand({
|
||||||
|
|||||||
@@ -8,19 +8,20 @@ import { validateHandlebarTemplate } from "@app/lib/template/validate-handlebars
|
|||||||
|
|
||||||
import { verifyHostInputValidity } from "../dynamic-secret-fns";
|
import { verifyHostInputValidity } from "../dynamic-secret-fns";
|
||||||
import { DynamicSecretCassandraSchema, TDynamicProviderFns } from "./models";
|
import { DynamicSecretCassandraSchema, TDynamicProviderFns } from "./models";
|
||||||
|
import { compileUsernameTemplate } from "./templateUtils";
|
||||||
|
|
||||||
const generatePassword = (size = 48) => {
|
const generatePassword = (size = 48) => {
|
||||||
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~!*";
|
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~!*";
|
||||||
return customAlphabet(charset, 48)(size);
|
return customAlphabet(charset, 48)(size);
|
||||||
};
|
};
|
||||||
|
|
||||||
const generateUsername = (usernameTemplate?: string | null) => {
|
const generateUsername = (usernameTemplate?: string | null, identity?: { name: string }) => {
|
||||||
const randomUsername = alphaNumericNanoId(32); // Username must start with an ascii letter, so we prepend the username with "inf-"
|
const randomUsername = alphaNumericNanoId(32); // Username must start with an ascii letter, so we prepend the username with "inf-"
|
||||||
if (!usernameTemplate) return randomUsername;
|
if (!usernameTemplate) return randomUsername;
|
||||||
|
return compileUsernameTemplate({
|
||||||
return handlebars.compile(usernameTemplate)({
|
usernameTemplate,
|
||||||
randomUsername,
|
randomUsername,
|
||||||
unixTimestamp: Math.floor(Date.now() / 100)
|
identity
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -75,12 +76,17 @@ export const CassandraProvider = (): TDynamicProviderFns => {
|
|||||||
return isConnected;
|
return isConnected;
|
||||||
};
|
};
|
||||||
|
|
||||||
const create = async (data: { inputs: unknown; expireAt: number; usernameTemplate?: string | null }) => {
|
const create = async (data: {
|
||||||
const { inputs, expireAt, usernameTemplate } = data;
|
inputs: unknown;
|
||||||
|
expireAt: number;
|
||||||
|
usernameTemplate?: string | null;
|
||||||
|
identity?: { name: string };
|
||||||
|
}) => {
|
||||||
|
const { inputs, expireAt, usernameTemplate, identity } = data;
|
||||||
const providerInputs = await validateProviderInputs(inputs);
|
const providerInputs = await validateProviderInputs(inputs);
|
||||||
const client = await $getClient(providerInputs);
|
const client = await $getClient(providerInputs);
|
||||||
|
|
||||||
const username = generateUsername(usernameTemplate);
|
const username = generateUsername(usernameTemplate, identity);
|
||||||
const password = generatePassword();
|
const password = generatePassword();
|
||||||
const { keyspace } = providerInputs;
|
const { keyspace } = providerInputs;
|
||||||
const expiration = new Date(expireAt).toISOString();
|
const expiration = new Date(expireAt).toISOString();
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { Client as ElasticSearchClient } from "@elastic/elasticsearch";
|
import { Client as ElasticSearchClient } from "@elastic/elasticsearch";
|
||||||
import handlebars from "handlebars";
|
|
||||||
import { customAlphabet } from "nanoid";
|
import { customAlphabet } from "nanoid";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
@@ -7,19 +6,20 @@ import { alphaNumericNanoId } from "@app/lib/nanoid";
|
|||||||
|
|
||||||
import { verifyHostInputValidity } from "../dynamic-secret-fns";
|
import { verifyHostInputValidity } from "../dynamic-secret-fns";
|
||||||
import { DynamicSecretElasticSearchSchema, ElasticSearchAuthTypes, TDynamicProviderFns } from "./models";
|
import { DynamicSecretElasticSearchSchema, ElasticSearchAuthTypes, TDynamicProviderFns } from "./models";
|
||||||
|
import { compileUsernameTemplate } from "./templateUtils";
|
||||||
|
|
||||||
const generatePassword = () => {
|
const generatePassword = () => {
|
||||||
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~!*";
|
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~!*";
|
||||||
return customAlphabet(charset, 64)();
|
return customAlphabet(charset, 64)();
|
||||||
};
|
};
|
||||||
|
|
||||||
const generateUsername = (usernameTemplate?: string | null) => {
|
const generateUsername = (usernameTemplate?: string | null, identity?: { name: string }) => {
|
||||||
const randomUsername = alphaNumericNanoId(32); // Username must start with an ascii letter, so we prepend the username with "inf-"
|
const randomUsername = alphaNumericNanoId(32); // Username must start with an ascii letter, so we prepend the username with "inf-"
|
||||||
if (!usernameTemplate) return randomUsername;
|
if (!usernameTemplate) return randomUsername;
|
||||||
|
return compileUsernameTemplate({
|
||||||
return handlebars.compile(usernameTemplate)({
|
usernameTemplate,
|
||||||
randomUsername,
|
randomUsername,
|
||||||
unixTimestamp: Math.floor(Date.now() / 100)
|
identity
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -71,12 +71,12 @@ export const ElasticSearchProvider = (): TDynamicProviderFns => {
|
|||||||
return infoResponse;
|
return infoResponse;
|
||||||
};
|
};
|
||||||
|
|
||||||
const create = async (data: { inputs: unknown; usernameTemplate?: string | null }) => {
|
const create = async (data: { inputs: unknown; usernameTemplate?: string | null; identity?: { name: string } }) => {
|
||||||
const { inputs, usernameTemplate } = data;
|
const { inputs, usernameTemplate, identity } = data;
|
||||||
const providerInputs = await validateProviderInputs(inputs);
|
const providerInputs = await validateProviderInputs(inputs);
|
||||||
const connection = await $getClient(providerInputs);
|
const connection = await $getClient(providerInputs);
|
||||||
|
|
||||||
const username = generateUsername(usernameTemplate);
|
const username = generateUsername(usernameTemplate, identity);
|
||||||
const password = generatePassword();
|
const password = generatePassword();
|
||||||
|
|
||||||
await connection.security.putUser({
|
await connection.security.putUser({
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { BadRequestError } from "@app/lib/errors";
|
|||||||
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
||||||
|
|
||||||
import { LdapCredentialType, LdapSchema, TDynamicProviderFns } from "./models";
|
import { LdapCredentialType, LdapSchema, TDynamicProviderFns } from "./models";
|
||||||
|
import { compileUsernameTemplate } from "./templateUtils";
|
||||||
|
|
||||||
const generatePassword = () => {
|
const generatePassword = () => {
|
||||||
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~!*$#";
|
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~!*$#";
|
||||||
@@ -22,13 +23,13 @@ const encodePassword = (password?: string) => {
|
|||||||
return base64Password;
|
return base64Password;
|
||||||
};
|
};
|
||||||
|
|
||||||
const generateUsername = (usernameTemplate?: string | null) => {
|
const generateUsername = (usernameTemplate?: string | null, identity?: { name: string }) => {
|
||||||
const randomUsername = alphaNumericNanoId(32); // Username must start with an ascii letter, so we prepend the username with "inf-"
|
const randomUsername = alphaNumericNanoId(32); // Username must start with an ascii letter, so we prepend the username with "inf-"
|
||||||
if (!usernameTemplate) return randomUsername;
|
if (!usernameTemplate) return randomUsername;
|
||||||
|
return compileUsernameTemplate({
|
||||||
return handlebars.compile(usernameTemplate)({
|
usernameTemplate,
|
||||||
randomUsername,
|
randomUsername,
|
||||||
unixTimestamp: Math.floor(Date.now() / 100)
|
identity
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -196,8 +197,8 @@ export const LdapProvider = (): TDynamicProviderFns => {
|
|||||||
return dnArray;
|
return dnArray;
|
||||||
};
|
};
|
||||||
|
|
||||||
const create = async (data: { inputs: unknown; usernameTemplate?: string | null }) => {
|
const create = async (data: { inputs: unknown; usernameTemplate?: string | null; identity?: { name: string } }) => {
|
||||||
const { inputs, usernameTemplate } = data;
|
const { inputs, usernameTemplate, identity } = data;
|
||||||
const providerInputs = await validateProviderInputs(inputs);
|
const providerInputs = await validateProviderInputs(inputs);
|
||||||
const client = await $getClient(providerInputs);
|
const client = await $getClient(providerInputs);
|
||||||
|
|
||||||
@@ -224,7 +225,7 @@ export const LdapProvider = (): TDynamicProviderFns => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const username = generateUsername(usernameTemplate);
|
const username = generateUsername(usernameTemplate, identity);
|
||||||
const password = generatePassword();
|
const password = generatePassword();
|
||||||
const generatedLdif = generateLDIF({ username, password, ldifTemplate: providerInputs.creationLdif });
|
const generatedLdif = generateLDIF({ username, password, ldifTemplate: providerInputs.creationLdif });
|
||||||
|
|
||||||
|
|||||||
@@ -427,6 +427,9 @@ export type TDynamicProviderFns = {
|
|||||||
inputs: unknown;
|
inputs: unknown;
|
||||||
expireAt: number;
|
expireAt: number;
|
||||||
usernameTemplate?: string | null;
|
usernameTemplate?: string | null;
|
||||||
|
identity?: {
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
metadata: { projectId: string };
|
metadata: { projectId: string };
|
||||||
}) => Promise<{ entityId: string; data: unknown }>;
|
}) => Promise<{ entityId: string; data: unknown }>;
|
||||||
validateConnection: (inputs: unknown, metadata: { projectId: string }) => Promise<boolean>;
|
validateConnection: (inputs: unknown, metadata: { projectId: string }) => Promise<boolean>;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import axios, { AxiosError } from "axios";
|
import axios, { AxiosError } from "axios";
|
||||||
import handlebars from "handlebars";
|
|
||||||
import { customAlphabet } from "nanoid";
|
import { customAlphabet } from "nanoid";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
@@ -7,19 +6,20 @@ import { createDigestAuthRequestInterceptor } from "@app/lib/axios/digest-auth";
|
|||||||
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
||||||
|
|
||||||
import { DynamicSecretMongoAtlasSchema, TDynamicProviderFns } from "./models";
|
import { DynamicSecretMongoAtlasSchema, TDynamicProviderFns } from "./models";
|
||||||
|
import { compileUsernameTemplate } from "./templateUtils";
|
||||||
|
|
||||||
const generatePassword = (size = 48) => {
|
const generatePassword = (size = 48) => {
|
||||||
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~!*";
|
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~!*";
|
||||||
return customAlphabet(charset, 48)(size);
|
return customAlphabet(charset, 48)(size);
|
||||||
};
|
};
|
||||||
|
|
||||||
const generateUsername = (usernameTemplate?: string | null) => {
|
const generateUsername = (usernameTemplate?: string | null, identity?: { name: string }) => {
|
||||||
const randomUsername = alphaNumericNanoId(32);
|
const randomUsername = alphaNumericNanoId(32);
|
||||||
if (!usernameTemplate) return randomUsername;
|
if (!usernameTemplate) return randomUsername;
|
||||||
|
return compileUsernameTemplate({
|
||||||
return handlebars.compile(usernameTemplate)({
|
usernameTemplate,
|
||||||
randomUsername,
|
randomUsername,
|
||||||
unixTimestamp: Math.floor(Date.now() / 100)
|
identity
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -64,12 +64,17 @@ export const MongoAtlasProvider = (): TDynamicProviderFns => {
|
|||||||
return isConnected;
|
return isConnected;
|
||||||
};
|
};
|
||||||
|
|
||||||
const create = async (data: { inputs: unknown; expireAt: number; usernameTemplate?: string | null }) => {
|
const create = async (data: {
|
||||||
const { inputs, expireAt, usernameTemplate } = data;
|
inputs: unknown;
|
||||||
|
expireAt: number;
|
||||||
|
usernameTemplate?: string | null;
|
||||||
|
identity?: { name: string };
|
||||||
|
}) => {
|
||||||
|
const { inputs, expireAt, usernameTemplate, identity } = data;
|
||||||
const providerInputs = await validateProviderInputs(inputs);
|
const providerInputs = await validateProviderInputs(inputs);
|
||||||
const client = await $getClient(providerInputs);
|
const client = await $getClient(providerInputs);
|
||||||
|
|
||||||
const username = generateUsername(usernameTemplate);
|
const username = generateUsername(usernameTemplate, identity);
|
||||||
const password = generatePassword();
|
const password = generatePassword();
|
||||||
const expiration = new Date(expireAt).toISOString();
|
const expiration = new Date(expireAt).toISOString();
|
||||||
await client({
|
await client({
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import handlebars from "handlebars";
|
|
||||||
import { MongoClient } from "mongodb";
|
import { MongoClient } from "mongodb";
|
||||||
import { customAlphabet } from "nanoid";
|
import { customAlphabet } from "nanoid";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
@@ -7,19 +6,20 @@ import { alphaNumericNanoId } from "@app/lib/nanoid";
|
|||||||
|
|
||||||
import { verifyHostInputValidity } from "../dynamic-secret-fns";
|
import { verifyHostInputValidity } from "../dynamic-secret-fns";
|
||||||
import { DynamicSecretMongoDBSchema, TDynamicProviderFns } from "./models";
|
import { DynamicSecretMongoDBSchema, TDynamicProviderFns } from "./models";
|
||||||
|
import { compileUsernameTemplate } from "./templateUtils";
|
||||||
|
|
||||||
const generatePassword = (size = 48) => {
|
const generatePassword = (size = 48) => {
|
||||||
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~!*";
|
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~!*";
|
||||||
return customAlphabet(charset, 48)(size);
|
return customAlphabet(charset, 48)(size);
|
||||||
};
|
};
|
||||||
|
|
||||||
const generateUsername = (usernameTemplate?: string | null) => {
|
const generateUsername = (usernameTemplate?: string | null, identity?: { name: string }) => {
|
||||||
const randomUsername = alphaNumericNanoId(32);
|
const randomUsername = alphaNumericNanoId(32);
|
||||||
if (!usernameTemplate) return randomUsername;
|
if (!usernameTemplate) return randomUsername;
|
||||||
|
return compileUsernameTemplate({
|
||||||
return handlebars.compile(usernameTemplate)({
|
usernameTemplate,
|
||||||
randomUsername,
|
randomUsername,
|
||||||
unixTimestamp: Math.floor(Date.now() / 100)
|
identity
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -60,12 +60,12 @@ export const MongoDBProvider = (): TDynamicProviderFns => {
|
|||||||
return isConnected;
|
return isConnected;
|
||||||
};
|
};
|
||||||
|
|
||||||
const create = async (data: { inputs: unknown; usernameTemplate?: string | null }) => {
|
const create = async (data: { inputs: unknown; usernameTemplate?: string | null; identity?: { name: string } }) => {
|
||||||
const { inputs, usernameTemplate } = data;
|
const { inputs, usernameTemplate, identity } = data;
|
||||||
const providerInputs = await validateProviderInputs(inputs);
|
const providerInputs = await validateProviderInputs(inputs);
|
||||||
const client = await $getClient(providerInputs);
|
const client = await $getClient(providerInputs);
|
||||||
|
|
||||||
const username = generateUsername(usernameTemplate);
|
const username = generateUsername(usernameTemplate, identity);
|
||||||
const password = generatePassword();
|
const password = generatePassword();
|
||||||
|
|
||||||
const db = client.db(providerInputs.database);
|
const db = client.db(providerInputs.database);
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import axios, { Axios } from "axios";
|
import axios, { Axios } from "axios";
|
||||||
import handlebars from "handlebars";
|
|
||||||
import https from "https";
|
import https from "https";
|
||||||
import { customAlphabet } from "nanoid";
|
import { customAlphabet } from "nanoid";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
@@ -9,19 +8,20 @@ import { alphaNumericNanoId } from "@app/lib/nanoid";
|
|||||||
|
|
||||||
import { verifyHostInputValidity } from "../dynamic-secret-fns";
|
import { verifyHostInputValidity } from "../dynamic-secret-fns";
|
||||||
import { DynamicSecretRabbitMqSchema, TDynamicProviderFns } from "./models";
|
import { DynamicSecretRabbitMqSchema, TDynamicProviderFns } from "./models";
|
||||||
|
import { compileUsernameTemplate } from "./templateUtils";
|
||||||
|
|
||||||
const generatePassword = () => {
|
const generatePassword = () => {
|
||||||
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~!*";
|
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~!*";
|
||||||
return customAlphabet(charset, 64)();
|
return customAlphabet(charset, 64)();
|
||||||
};
|
};
|
||||||
|
|
||||||
const generateUsername = (usernameTemplate?: string | null) => {
|
const generateUsername = (usernameTemplate?: string | null, identity?: { name: string }) => {
|
||||||
const randomUsername = alphaNumericNanoId(32); // Username must start with an ascii letter, so we prepend the username with "inf-"
|
const randomUsername = alphaNumericNanoId(32); // Username must start with an ascii letter, so we prepend the username with "inf-"
|
||||||
if (!usernameTemplate) return randomUsername;
|
if (!usernameTemplate) return randomUsername;
|
||||||
|
return compileUsernameTemplate({
|
||||||
return handlebars.compile(usernameTemplate)({
|
usernameTemplate,
|
||||||
randomUsername,
|
randomUsername,
|
||||||
unixTimestamp: Math.floor(Date.now() / 100)
|
identity
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -117,12 +117,12 @@ export const RabbitMqProvider = (): TDynamicProviderFns => {
|
|||||||
return infoResponse;
|
return infoResponse;
|
||||||
};
|
};
|
||||||
|
|
||||||
const create = async (data: { inputs: unknown; usernameTemplate?: string | null }) => {
|
const create = async (data: { inputs: unknown; usernameTemplate?: string | null; identity?: { name: string } }) => {
|
||||||
const { inputs, usernameTemplate } = data;
|
const { inputs, usernameTemplate, identity } = data;
|
||||||
const providerInputs = await validateProviderInputs(inputs);
|
const providerInputs = await validateProviderInputs(inputs);
|
||||||
const connection = await $getClient(providerInputs);
|
const connection = await $getClient(providerInputs);
|
||||||
|
|
||||||
const username = generateUsername(usernameTemplate);
|
const username = generateUsername(usernameTemplate, identity);
|
||||||
const password = generatePassword();
|
const password = generatePassword();
|
||||||
|
|
||||||
await createRabbitMqUser({
|
await createRabbitMqUser({
|
||||||
|
|||||||
@@ -9,19 +9,20 @@ import { validateHandlebarTemplate } from "@app/lib/template/validate-handlebars
|
|||||||
|
|
||||||
import { verifyHostInputValidity } from "../dynamic-secret-fns";
|
import { verifyHostInputValidity } from "../dynamic-secret-fns";
|
||||||
import { DynamicSecretRedisDBSchema, TDynamicProviderFns } from "./models";
|
import { DynamicSecretRedisDBSchema, TDynamicProviderFns } from "./models";
|
||||||
|
import { compileUsernameTemplate } from "./templateUtils";
|
||||||
|
|
||||||
const generatePassword = () => {
|
const generatePassword = () => {
|
||||||
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~!*";
|
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~!*";
|
||||||
return customAlphabet(charset, 64)();
|
return customAlphabet(charset, 64)();
|
||||||
};
|
};
|
||||||
|
|
||||||
const generateUsername = (usernameTemplate?: string | null) => {
|
const generateUsername = (usernameTemplate?: string | null, identity?: { name: string }) => {
|
||||||
const randomUsername = alphaNumericNanoId(32); // Username must start with an ascii letter, so we prepend the username with "inf-"
|
const randomUsername = alphaNumericNanoId(32); // Username must start with an ascii letter, so we prepend the username with "inf-"
|
||||||
if (!usernameTemplate) return randomUsername;
|
if (!usernameTemplate) return randomUsername;
|
||||||
|
return compileUsernameTemplate({
|
||||||
return handlebars.compile(usernameTemplate)({
|
usernameTemplate,
|
||||||
randomUsername,
|
randomUsername,
|
||||||
unixTimestamp: Math.floor(Date.now() / 100)
|
identity
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -121,12 +122,17 @@ export const RedisDatabaseProvider = (): TDynamicProviderFns => {
|
|||||||
return pingResponse;
|
return pingResponse;
|
||||||
};
|
};
|
||||||
|
|
||||||
const create = async (data: { inputs: unknown; expireAt: number; usernameTemplate?: string | null }) => {
|
const create = async (data: {
|
||||||
const { inputs, expireAt, usernameTemplate } = data;
|
inputs: unknown;
|
||||||
|
expireAt: number;
|
||||||
|
usernameTemplate?: string | null;
|
||||||
|
identity?: { name: string };
|
||||||
|
}) => {
|
||||||
|
const { inputs, expireAt, usernameTemplate, identity } = data;
|
||||||
const providerInputs = await validateProviderInputs(inputs);
|
const providerInputs = await validateProviderInputs(inputs);
|
||||||
const connection = await $getClient(providerInputs);
|
const connection = await $getClient(providerInputs);
|
||||||
|
|
||||||
const username = generateUsername(usernameTemplate);
|
const username = generateUsername(usernameTemplate, identity);
|
||||||
const password = generatePassword();
|
const password = generatePassword();
|
||||||
const expiration = new Date(expireAt).toISOString();
|
const expiration = new Date(expireAt).toISOString();
|
||||||
|
|
||||||
|
|||||||
@@ -9,19 +9,20 @@ import { validateHandlebarTemplate } from "@app/lib/template/validate-handlebars
|
|||||||
|
|
||||||
import { verifyHostInputValidity } from "../dynamic-secret-fns";
|
import { verifyHostInputValidity } from "../dynamic-secret-fns";
|
||||||
import { DynamicSecretSapAseSchema, TDynamicProviderFns } from "./models";
|
import { DynamicSecretSapAseSchema, TDynamicProviderFns } from "./models";
|
||||||
|
import { compileUsernameTemplate } from "./templateUtils";
|
||||||
|
|
||||||
const generatePassword = (size = 48) => {
|
const generatePassword = (size = 48) => {
|
||||||
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||||
return customAlphabet(charset, 48)(size);
|
return customAlphabet(charset, 48)(size);
|
||||||
};
|
};
|
||||||
|
|
||||||
const generateUsername = (usernameTemplate?: string | null) => {
|
const generateUsername = (usernameTemplate?: string | null, identity?: { name: string }) => {
|
||||||
const randomUsername = `inf_${alphaNumericNanoId(25)}`; // Username must start with an ascii letter, so we prepend the username with "inf-"
|
const randomUsername = `inf_${alphaNumericNanoId(25)}`; // Username must start with an ascii letter, so we prepend the username with "inf-"
|
||||||
if (!usernameTemplate) return randomUsername;
|
if (!usernameTemplate) return randomUsername;
|
||||||
|
return compileUsernameTemplate({
|
||||||
return handlebars.compile(usernameTemplate)({
|
usernameTemplate,
|
||||||
randomUsername,
|
randomUsername,
|
||||||
unixTimestamp: Math.floor(Date.now() / 100)
|
identity
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -87,11 +88,11 @@ export const SapAseProvider = (): TDynamicProviderFns => {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const create = async (data: { inputs: unknown; usernameTemplate?: string | null }) => {
|
const create = async (data: { inputs: unknown; usernameTemplate?: string | null; identity?: { name: string } }) => {
|
||||||
const { inputs, usernameTemplate } = data;
|
const { inputs, usernameTemplate, identity } = data;
|
||||||
const providerInputs = await validateProviderInputs(inputs);
|
const providerInputs = await validateProviderInputs(inputs);
|
||||||
|
|
||||||
const username = generateUsername(usernameTemplate);
|
const username = generateUsername(usernameTemplate, identity);
|
||||||
const password = generatePassword();
|
const password = generatePassword();
|
||||||
|
|
||||||
const client = await $getClient(providerInputs);
|
const client = await $getClient(providerInputs);
|
||||||
|
|||||||
@@ -15,19 +15,20 @@ import { validateHandlebarTemplate } from "@app/lib/template/validate-handlebars
|
|||||||
|
|
||||||
import { verifyHostInputValidity } from "../dynamic-secret-fns";
|
import { verifyHostInputValidity } from "../dynamic-secret-fns";
|
||||||
import { DynamicSecretSapHanaSchema, TDynamicProviderFns } from "./models";
|
import { DynamicSecretSapHanaSchema, TDynamicProviderFns } from "./models";
|
||||||
|
import { compileUsernameTemplate } from "./templateUtils";
|
||||||
|
|
||||||
const generatePassword = (size = 48) => {
|
const generatePassword = (size = 48) => {
|
||||||
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||||
return customAlphabet(charset, 48)(size);
|
return customAlphabet(charset, 48)(size);
|
||||||
};
|
};
|
||||||
|
|
||||||
const generateUsername = (usernameTemplate?: string | null) => {
|
const generateUsername = (usernameTemplate?: string | null, identity?: { name: string }) => {
|
||||||
const randomUsername = alphaNumericNanoId(32); // Username must start with an ascii letter, so we prepend the username with "inf-"
|
const randomUsername = alphaNumericNanoId(32); // Username must start with an ascii letter, so we prepend the username with "inf-"
|
||||||
if (!usernameTemplate) return randomUsername;
|
if (!usernameTemplate) return randomUsername;
|
||||||
|
return compileUsernameTemplate({
|
||||||
return handlebars.compile(usernameTemplate)({
|
usernameTemplate,
|
||||||
randomUsername,
|
randomUsername,
|
||||||
unixTimestamp: Math.floor(Date.now() / 100)
|
identity
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -97,11 +98,16 @@ export const SapHanaProvider = (): TDynamicProviderFns => {
|
|||||||
return testResult;
|
return testResult;
|
||||||
};
|
};
|
||||||
|
|
||||||
const create = async (data: { inputs: unknown; expireAt: number; usernameTemplate?: string | null }) => {
|
const create = async (data: {
|
||||||
const { inputs, expireAt, usernameTemplate } = data;
|
inputs: unknown;
|
||||||
|
expireAt: number;
|
||||||
|
usernameTemplate?: string | null;
|
||||||
|
identity?: { name: string };
|
||||||
|
}) => {
|
||||||
|
const { inputs, expireAt, usernameTemplate, identity } = data;
|
||||||
const providerInputs = await validateProviderInputs(inputs);
|
const providerInputs = await validateProviderInputs(inputs);
|
||||||
|
|
||||||
const username = generateUsername(usernameTemplate);
|
const username = generateUsername(usernameTemplate, identity);
|
||||||
const password = generatePassword();
|
const password = generatePassword();
|
||||||
const expiration = new Date(expireAt).toISOString();
|
const expiration = new Date(expireAt).toISOString();
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { alphaNumericNanoId } from "@app/lib/nanoid";
|
|||||||
import { validateHandlebarTemplate } from "@app/lib/template/validate-handlebars";
|
import { validateHandlebarTemplate } from "@app/lib/template/validate-handlebars";
|
||||||
|
|
||||||
import { DynamicSecretSnowflakeSchema, TDynamicProviderFns } from "./models";
|
import { DynamicSecretSnowflakeSchema, TDynamicProviderFns } from "./models";
|
||||||
|
import { compileUsernameTemplate } from "./templateUtils";
|
||||||
|
|
||||||
// destroy client requires callback...
|
// destroy client requires callback...
|
||||||
const noop = () => {};
|
const noop = () => {};
|
||||||
@@ -17,13 +18,13 @@ const generatePassword = (size = 48) => {
|
|||||||
return customAlphabet(charset, 48)(size);
|
return customAlphabet(charset, 48)(size);
|
||||||
};
|
};
|
||||||
|
|
||||||
const generateUsername = (usernameTemplate?: string | null) => {
|
const generateUsername = (usernameTemplate?: string | null, identity?: { name: string }) => {
|
||||||
const randomUsername = `infisical_${alphaNumericNanoId(32)}`; // Username must start with an ascii letter, so we prepend the username with "inf-"
|
const randomUsername = `infisical_${alphaNumericNanoId(32)}`; // Username must start with an ascii letter, so we prepend the username with "inf-"
|
||||||
if (!usernameTemplate) return randomUsername;
|
if (!usernameTemplate) return randomUsername;
|
||||||
|
return compileUsernameTemplate({
|
||||||
return handlebars.compile(usernameTemplate)({
|
usernameTemplate,
|
||||||
randomUsername,
|
randomUsername,
|
||||||
unixTimestamp: Math.floor(Date.now() / 100)
|
identity
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -88,13 +89,18 @@ export const SnowflakeProvider = (): TDynamicProviderFns => {
|
|||||||
return isValidConnection;
|
return isValidConnection;
|
||||||
};
|
};
|
||||||
|
|
||||||
const create = async (data: { inputs: unknown; expireAt: number; usernameTemplate?: string | null }) => {
|
const create = async (data: {
|
||||||
const { inputs, expireAt, usernameTemplate } = data;
|
inputs: unknown;
|
||||||
|
expireAt: number;
|
||||||
|
usernameTemplate?: string | null;
|
||||||
|
identity?: { name: string };
|
||||||
|
}) => {
|
||||||
|
const { inputs, expireAt, usernameTemplate, identity } = data;
|
||||||
const providerInputs = await validateProviderInputs(inputs);
|
const providerInputs = await validateProviderInputs(inputs);
|
||||||
|
|
||||||
const client = await $getClient(providerInputs);
|
const client = await $getClient(providerInputs);
|
||||||
|
|
||||||
const username = generateUsername(usernameTemplate);
|
const username = generateUsername(usernameTemplate, identity);
|
||||||
const password = generatePassword();
|
const password = generatePassword();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { validateHandlebarTemplate } from "@app/lib/template/validate-handlebars
|
|||||||
import { TGatewayServiceFactory } from "../../gateway/gateway-service";
|
import { TGatewayServiceFactory } from "../../gateway/gateway-service";
|
||||||
import { verifyHostInputValidity } from "../dynamic-secret-fns";
|
import { verifyHostInputValidity } from "../dynamic-secret-fns";
|
||||||
import { DynamicSecretSqlDBSchema, PasswordRequirements, SqlProviders, TDynamicProviderFns } from "./models";
|
import { DynamicSecretSqlDBSchema, PasswordRequirements, SqlProviders, TDynamicProviderFns } from "./models";
|
||||||
|
import { compileUsernameTemplate } from "./templateUtils";
|
||||||
|
|
||||||
const EXTERNAL_REQUEST_TIMEOUT = 10 * 1000;
|
const EXTERNAL_REQUEST_TIMEOUT = 10 * 1000;
|
||||||
|
|
||||||
@@ -104,9 +105,8 @@ const generatePassword = (provider: SqlProviders, requirements?: PasswordRequire
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const generateUsername = (provider: SqlProviders, usernameTemplate?: string | null) => {
|
const generateUsername = (provider: SqlProviders, usernameTemplate?: string | null, identity?: { name: string }) => {
|
||||||
let randomUsername = "";
|
let randomUsername = "";
|
||||||
|
|
||||||
// For oracle, the client assumes everything is upper case when not using quotes around the password
|
// For oracle, the client assumes everything is upper case when not using quotes around the password
|
||||||
if (provider === SqlProviders.Oracle) {
|
if (provider === SqlProviders.Oracle) {
|
||||||
randomUsername = alphaNumericNanoId(32).toUpperCase();
|
randomUsername = alphaNumericNanoId(32).toUpperCase();
|
||||||
@@ -114,10 +114,13 @@ const generateUsername = (provider: SqlProviders, usernameTemplate?: string | nu
|
|||||||
randomUsername = alphaNumericNanoId(32);
|
randomUsername = alphaNumericNanoId(32);
|
||||||
}
|
}
|
||||||
if (!usernameTemplate) return randomUsername;
|
if (!usernameTemplate) return randomUsername;
|
||||||
|
return compileUsernameTemplate({
|
||||||
return handlebars.compile(usernameTemplate)({
|
usernameTemplate,
|
||||||
randomUsername,
|
randomUsername,
|
||||||
unixTimestamp: Math.floor(Date.now() / 100)
|
identity,
|
||||||
|
options: {
|
||||||
|
toUpperCase: provider === SqlProviders.Oracle
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -221,11 +224,16 @@ export const SqlDatabaseProvider = ({ gatewayService }: TSqlDatabaseProviderDTO)
|
|||||||
return isConnected;
|
return isConnected;
|
||||||
};
|
};
|
||||||
|
|
||||||
const create = async (data: { inputs: unknown; expireAt: number; usernameTemplate?: string | null }) => {
|
const create = async (data: {
|
||||||
const { inputs, expireAt, usernameTemplate } = data;
|
inputs: unknown;
|
||||||
|
expireAt: number;
|
||||||
|
usernameTemplate?: string | null;
|
||||||
|
identity?: { name: string };
|
||||||
|
}) => {
|
||||||
|
const { inputs, expireAt, usernameTemplate, identity } = data;
|
||||||
|
|
||||||
const providerInputs = await validateProviderInputs(inputs);
|
const providerInputs = await validateProviderInputs(inputs);
|
||||||
const username = generateUsername(providerInputs.client, usernameTemplate);
|
const username = generateUsername(providerInputs.client, usernameTemplate, identity);
|
||||||
|
|
||||||
const password = generatePassword(providerInputs.client, providerInputs.passwordRequirements);
|
const password = generatePassword(providerInputs.client, providerInputs.passwordRequirements);
|
||||||
const gatewayCallback = async (host = providerInputs.host, port = providerInputs.port) => {
|
const gatewayCallback = async (host = providerInputs.host, port = providerInputs.port) => {
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
/* eslint-disable func-names */
|
||||||
|
import handlebars from "handlebars";
|
||||||
|
import RE2 from "re2";
|
||||||
|
|
||||||
|
import { logger } from "@app/lib/logger";
|
||||||
|
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
||||||
|
|
||||||
|
export const compileUsernameTemplate = ({
|
||||||
|
usernameTemplate,
|
||||||
|
randomUsername,
|
||||||
|
identity,
|
||||||
|
unixTimestamp,
|
||||||
|
options
|
||||||
|
}: {
|
||||||
|
usernameTemplate: string;
|
||||||
|
randomUsername: string;
|
||||||
|
identity?: { name: string };
|
||||||
|
unixTimestamp?: number;
|
||||||
|
options?: {
|
||||||
|
toUpperCase?: boolean;
|
||||||
|
};
|
||||||
|
}): string => {
|
||||||
|
// Create isolated handlebars instance
|
||||||
|
const hbs = handlebars.create();
|
||||||
|
|
||||||
|
// Register random helper on local instance
|
||||||
|
hbs.registerHelper("random", function (length: number) {
|
||||||
|
if (typeof length !== "number" || length <= 0 || length > 100) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return alphaNumericNanoId(length);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Register replace helper on local instance
|
||||||
|
hbs.registerHelper("replace", function (text: string, searchValue: string, replaceValue: string) {
|
||||||
|
// Convert to string if it's not already
|
||||||
|
const textStr = String(text || "");
|
||||||
|
if (!textStr) {
|
||||||
|
return textStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const re2Pattern = new RE2(searchValue, "g");
|
||||||
|
// Replace all occurrences
|
||||||
|
return re2Pattern.replace(textStr, replaceValue);
|
||||||
|
} catch (error) {
|
||||||
|
logger.error(error, "RE2 pattern failed, using original template");
|
||||||
|
return textStr;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Register truncate helper on local instance
|
||||||
|
hbs.registerHelper("truncate", function (text: string, length: number) {
|
||||||
|
// Convert to string if it's not already
|
||||||
|
const textStr = String(text || "");
|
||||||
|
if (!textStr) {
|
||||||
|
return textStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof length !== "number" || length <= 0) return textStr;
|
||||||
|
return textStr.substring(0, length);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Compile template with context using local instance
|
||||||
|
const context = {
|
||||||
|
randomUsername,
|
||||||
|
unixTimestamp: unixTimestamp || Math.floor(Date.now() / 100),
|
||||||
|
identity: {
|
||||||
|
name: identity?.name
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = hbs.compile(usernameTemplate)(context);
|
||||||
|
|
||||||
|
if (options?.toUpperCase) {
|
||||||
|
return result.toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
@@ -7,13 +7,24 @@ type SanitizationArg = {
|
|||||||
allowedExpressions?: (arg: string) => boolean;
|
allowedExpressions?: (arg: string) => boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isValidExpression = (expression: string, dto: SanitizationArg): boolean => {
|
||||||
|
// Allow helper functions (replace, truncate)
|
||||||
|
const allowedHelpers = ["replace", "truncate", "random"];
|
||||||
|
if (allowedHelpers.includes(expression)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check regular allowed expressions
|
||||||
|
return dto?.allowedExpressions?.(expression) || false;
|
||||||
|
};
|
||||||
|
|
||||||
export const validateHandlebarTemplate = (templateName: string, template: string, dto: SanitizationArg) => {
|
export const validateHandlebarTemplate = (templateName: string, template: string, dto: SanitizationArg) => {
|
||||||
const parsedAst = handlebars.parse(template);
|
const parsedAst = handlebars.parse(template);
|
||||||
parsedAst.body.forEach((el) => {
|
parsedAst.body.forEach((el) => {
|
||||||
if (el.type === "ContentStatement") return;
|
if (el.type === "ContentStatement") return;
|
||||||
if (el.type === "MustacheStatement" && "path" in el) {
|
if (el.type === "MustacheStatement" && "path" in el) {
|
||||||
const { path } = el as { type: "MustacheStatement"; path: { type: "PathExpression"; original: string } };
|
const { path } = el as { type: "MustacheStatement"; path: { type: "PathExpression"; original: string } };
|
||||||
if (path.type === "PathExpression" && dto?.allowedExpressions?.(path.original)) return;
|
if (path.type === "PathExpression" && isValidExpression(path.original, dto)) return;
|
||||||
}
|
}
|
||||||
logger.error(el, "Template sanitization failed");
|
logger.error(el, "Template sanitization failed");
|
||||||
throw new BadRequestError({ message: `Template sanitization failed: ${templateName}` });
|
throw new BadRequestError({ message: `Template sanitization failed: ${templateName}` });
|
||||||
@@ -26,7 +37,7 @@ export const isValidHandleBarTemplate = (template: string, dto: SanitizationArg)
|
|||||||
if (el.type === "ContentStatement") return true;
|
if (el.type === "ContentStatement") return true;
|
||||||
if (el.type === "MustacheStatement" && "path" in el) {
|
if (el.type === "MustacheStatement" && "path" in el) {
|
||||||
const { path } = el as { type: "MustacheStatement"; path: { type: "PathExpression"; original: string } };
|
const { path } = el as { type: "MustacheStatement"; path: { type: "PathExpression"; original: string } };
|
||||||
if (path.type === "PathExpression" && dto?.allowedExpressions?.(path.original)) return true;
|
if (path.type === "PathExpression" && isValidExpression(path.original, dto)) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1516,7 +1516,9 @@ export const registerRoutes = async (
|
|||||||
dynamicSecretProviders,
|
dynamicSecretProviders,
|
||||||
folderDAL,
|
folderDAL,
|
||||||
licenseService,
|
licenseService,
|
||||||
kmsService
|
kmsService,
|
||||||
|
userDAL,
|
||||||
|
identityDAL
|
||||||
});
|
});
|
||||||
const dailyResourceCleanUp = dailyResourceCleanUpQueueServiceFactory({
|
const dailyResourceCleanUp = dailyResourceCleanUpQueueServiceFactory({
|
||||||
auditLogDAL,
|
auditLogDAL,
|
||||||
|
|||||||
@@ -95,12 +95,28 @@ The Infisical AWS ElastiCache dynamic secret allows you to generate AWS ElastiCa
|
|||||||
</Step>
|
</Step>
|
||||||
<Step title="(Optional) Modify ElastiCache Statements">
|
<Step title="(Optional) Modify ElastiCache Statements">
|
||||||

|

|
||||||
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
||||||
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
||||||
|
|
||||||
Allowed template variables are
|
Allowed template variables are
|
||||||
- `{{randomUsername}}`: Random username string
|
- `{{randomUsername}}`: Random username string
|
||||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||||
|
- `{{identity.name}}`: Name of the identity that is generating the secret
|
||||||
|
- `{{random N}}`: Random string of N characters
|
||||||
|
|
||||||
|
Allowed template functions are
|
||||||
|
- `truncate`: Truncates a string to a specified length
|
||||||
|
- `replace`: Replaces a substring with another value
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
```
|
||||||
|
{{randomUsername}} // 3POnzeFyK9gW2nioK0q2gMjr6CZqsRiX
|
||||||
|
{{unixTimestamp}} // 17490641580
|
||||||
|
{{identity.name}} // testuser
|
||||||
|
{{random-5}} // x9k2m
|
||||||
|
{{truncate identity.name 4}} // test
|
||||||
|
{{replace identity.name 'user' 'replace'}} // testreplace
|
||||||
|
```
|
||||||
</ParamField>
|
</ParamField>
|
||||||
<ParamField path="Customize ElastiCache Statement" type="string">
|
<ParamField path="Customize ElastiCache Statement" type="string">
|
||||||
If you want to provide specific privileges for the generated dynamic credentials, you can modify the ElastiCache statement to your needs. This is useful if you want to only give access to a specific resource.
|
If you want to provide specific privileges for the generated dynamic credentials, you can modify the ElastiCache statement to your needs. This is useful if you want to only give access to a specific resource.
|
||||||
|
|||||||
@@ -137,9 +137,32 @@ Replace **\<account id\>** with your AWS account id and **\<aws-scope-path\>** w
|
|||||||
Maximum time-to-live for a generated secret
|
Maximum time-to-live for a generated secret
|
||||||
</ParamField>
|
</ParamField>
|
||||||
|
|
||||||
<ParamField path="Method" type="string" required>
|
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
||||||
Select *Assume Role* method.
|
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
||||||
</ParamField>
|
|
||||||
|
Allowed template variables are
|
||||||
|
- `{{randomUsername}}`: Random username string
|
||||||
|
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||||
|
- `{{identity.name}}`: Name of the identity that is generating the secret
|
||||||
|
- `{{random N}}`: Random string of N characters
|
||||||
|
|
||||||
|
Allowed template functions are
|
||||||
|
- `truncate`: Truncates a string to a specified length
|
||||||
|
- `replace`: Replaces a substring with another value
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
```
|
||||||
|
{{randomUsername}} // 3POnzeFyK9gW2nioK0q2gMjr6CZqsRiX
|
||||||
|
{{unixTimestamp}} // 17490641580
|
||||||
|
{{identity.name}} // testuser
|
||||||
|
{{random-5}} // x9k2m
|
||||||
|
{{truncate identity.name 4}} // test
|
||||||
|
{{replace identity.name 'user' 'replace'}} // testreplace
|
||||||
|
```
|
||||||
|
</ParamField>
|
||||||
|
<ParamField path="Method" type="string" required>
|
||||||
|
Select *Assume Role* method.
|
||||||
|
</ParamField>
|
||||||
|
|
||||||
<ParamField path="Aws Role ARN" type="string" required>
|
<ParamField path="Aws Role ARN" type="string" required>
|
||||||
The ARN of the AWS Role to assume.
|
The ARN of the AWS Role to assume.
|
||||||
|
|||||||
@@ -80,11 +80,27 @@ The above configuration allows user creation and granting permissions.
|
|||||||
<Step title="(Optional) Modify CQL Statements">
|
<Step title="(Optional) Modify CQL Statements">
|
||||||

|

|
||||||
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
||||||
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
||||||
|
|
||||||
Allowed template variables are
|
Allowed template variables are
|
||||||
- `{{randomUsername}}`: Random username string
|
- `{{randomUsername}}`: Random username string
|
||||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||||
|
- `{{identity.name}}`: Name of the identity that is generating the secret
|
||||||
|
- `{{random N}}`: Random string of N characters
|
||||||
|
|
||||||
|
Allowed template functions are
|
||||||
|
- `truncate`: Truncates a string to a specified length
|
||||||
|
- `replace`: Replaces a substring with another value
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
```
|
||||||
|
{{randomUsername}} // 3POnzeFyK9gW2nioK0q2gMjr6CZqsRiX
|
||||||
|
{{unixTimestamp}} // 17490641580
|
||||||
|
{{identity.name}} // testuser
|
||||||
|
{{random-5}} // x9k2m
|
||||||
|
{{truncate identity.name 4}} // test
|
||||||
|
{{replace identity.name 'user' 'replace'}} // testreplace
|
||||||
|
```
|
||||||
</ParamField>
|
</ParamField>
|
||||||
<ParamField path="Customize CQL Statement" type="string">
|
<ParamField path="Customize CQL Statement" type="string">
|
||||||
If you want to provide specific privileges for the generated dynamic credentials, you can modify the CQL statement to your needs. This is useful if you want to only give access to a specific key-space(s).
|
If you want to provide specific privileges for the generated dynamic credentials, you can modify the CQL statement to your needs. This is useful if you want to only give access to a specific key-space(s).
|
||||||
|
|||||||
@@ -87,13 +87,29 @@ The port that your Elasticsearch instance is running on. _(Example: 9200)_
|
|||||||
<ParamField path="CA(SSL)" type="string">
|
<ParamField path="CA(SSL)" type="string">
|
||||||
A CA may be required if your DB requires it for incoming connections. This is often the case when connecting to a managed service.
|
A CA may be required if your DB requires it for incoming connections. This is often the case when connecting to a managed service.
|
||||||
</ParamField>
|
</ParamField>
|
||||||
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
||||||
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
||||||
|
|
||||||
Allowed template variables are
|
Allowed template variables are
|
||||||
- `{{randomUsername}}`: Random username string
|
- `{{randomUsername}}`: Random username string
|
||||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||||
</ParamField>
|
- `{{identity.name}}`: Name of the identity that is generating the secret
|
||||||
|
- `{{random N}}`: Random string of N characters
|
||||||
|
|
||||||
|
Allowed template functions are
|
||||||
|
- `truncate`: Truncates a string to a specified length
|
||||||
|
- `replace`: Replaces a substring with another value
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
```
|
||||||
|
{{randomUsername}} // 3POnzeFyK9gW2nioK0q2gMjr6CZqsRiX
|
||||||
|
{{unixTimestamp}} // 17490641580
|
||||||
|
{{identity.name}} // testuser
|
||||||
|
{{random-5}} // x9k2m
|
||||||
|
{{truncate identity.name 4}} // test
|
||||||
|
{{replace identity.name 'user' 'replace'}} // testreplace
|
||||||
|
```
|
||||||
|
</ParamField>
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|||||||
@@ -123,13 +123,29 @@ The Infisical LDAP dynamic secret allows you to generate user credentials on dem
|
|||||||
changetype: delete
|
changetype: delete
|
||||||
```
|
```
|
||||||
</ParamField>
|
</ParamField>
|
||||||
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
||||||
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
||||||
|
|
||||||
Allowed template variables are
|
Allowed template variables are
|
||||||
- `{{randomUsername}}`: Random username string
|
- `{{randomUsername}}`: Random username string
|
||||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||||
</ParamField>
|
- `{{identity.name}}`: Name of the identity that is generating the secret
|
||||||
|
- `{{random N}}`: Random string of N characters
|
||||||
|
|
||||||
|
Allowed template functions are
|
||||||
|
- `truncate`: Truncates a string to a specified length
|
||||||
|
- `replace`: Replaces a substring with another value
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
```
|
||||||
|
{{randomUsername}} // 3POnzeFyK9gW2nioK0q2gMjr6CZqsRiX
|
||||||
|
{{unixTimestamp}} // 17490641580
|
||||||
|
{{identity.name}} // testuser
|
||||||
|
{{random-5}} // x9k2m
|
||||||
|
{{truncate identity.name 4}} // test
|
||||||
|
{{replace identity.name 'user' 'replace'}} // testreplace
|
||||||
|
```
|
||||||
|
</ParamField>
|
||||||
</Step>
|
</Step>
|
||||||
|
|
||||||
<Step title="Click `Submit`">
|
<Step title="Click `Submit`">
|
||||||
|
|||||||
@@ -63,13 +63,29 @@ Create a project scoped API Key with the required permission in your Mongo Atlas
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
||||||
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
||||||
|
|
||||||
Allowed template variables are
|
Allowed template variables are
|
||||||
- `{{randomUsername}}`: Random username string
|
- `{{randomUsername}}`: Random username string
|
||||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||||
</ParamField>
|
- `{{identity.name}}`: Name of the identity that is generating the secret
|
||||||
|
- `{{random N}}`: Random string of N characters
|
||||||
|
|
||||||
|
Allowed template functions are
|
||||||
|
- `truncate`: Truncates a string to a specified length
|
||||||
|
- `replace`: Replaces a substring with another value
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
```
|
||||||
|
{{randomUsername}} // 3POnzeFyK9gW2nioK0q2gMjr6CZqsRiX
|
||||||
|
{{unixTimestamp}} // 17490641580
|
||||||
|
{{identity.name}} // testuser
|
||||||
|
{{random-5}} // x9k2m
|
||||||
|
{{truncate identity.name 4}} // test
|
||||||
|
{{replace identity.name 'user' 'replace'}} // testreplace
|
||||||
|
```
|
||||||
|
</ParamField>
|
||||||
<ParamField path="Customize Scope" type="string">
|
<ParamField path="Customize Scope" type="string">
|
||||||
|
|
||||||
List that contains clusters, MongoDB Atlas Data Lakes, and MongoDB Atlas Streams Instances that this database user can access. If omitted, MongoDB Cloud grants the database user access to all the clusters, MongoDB Atlas Data Lakes, and MongoDB Atlas Streams Instances in the project.
|
List that contains clusters, MongoDB Atlas Data Lakes, and MongoDB Atlas Streams Instances that this database user can access. If omitted, MongoDB Cloud grants the database user access to all the clusters, MongoDB Atlas Data Lakes, and MongoDB Atlas Streams Instances in the project.
|
||||||
|
|||||||
@@ -66,12 +66,28 @@ Create a user with the required permission in your MongoDB instance. This user w
|
|||||||
<ParamField path="CA(SSL)" type="string">
|
<ParamField path="CA(SSL)" type="string">
|
||||||
A CA may be required if your DB requires it for incoming connections.
|
A CA may be required if your DB requires it for incoming connections.
|
||||||
</ParamField>
|
</ParamField>
|
||||||
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
||||||
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
||||||
|
|
||||||
Allowed template variables are
|
Allowed template variables are
|
||||||
- `{{randomUsername}}`: Random username string
|
- `{{randomUsername}}`: Random username string
|
||||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||||
|
- `{{identity.name}}`: Name of the identity that is generating the secret
|
||||||
|
- `{{random N}}`: Random string of N characters
|
||||||
|
|
||||||
|
Allowed template functions are
|
||||||
|
- `truncate`: Truncates a string to a specified length
|
||||||
|
- `replace`: Replaces a substring with another value
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
```
|
||||||
|
{{randomUsername}} // 3POnzeFyK9gW2nioK0q2gMjr6CZqsRiX
|
||||||
|
{{unixTimestamp}} // 17490641580
|
||||||
|
{{identity.name}} // testuser
|
||||||
|
{{random-5}} // x9k2m
|
||||||
|
{{truncate identity.name 4}} // test
|
||||||
|
{{replace identity.name 'user' 'replace'}} // testreplace
|
||||||
|
```
|
||||||
</ParamField>
|
</ParamField>
|
||||||
|
|
||||||

|

|
||||||
|
|||||||
@@ -9,7 +9,6 @@ The Infisical MS SQL dynamic secret allows you to generate Microsoft SQL server
|
|||||||
|
|
||||||
Create a user with the required permission in your SQL instance. This user will be used to create new accounts on-demand.
|
Create a user with the required permission in your SQL instance. This user will be used to create new accounts on-demand.
|
||||||
|
|
||||||
|
|
||||||
## Set up Dynamic Secrets with MS SQL
|
## Set up Dynamic Secrets with MS SQL
|
||||||
|
|
||||||
<Steps>
|
<Steps>
|
||||||
@@ -27,104 +26,123 @@ Create a user with the required permission in your SQL instance. This user will
|
|||||||
Name by which you want the secret to be referenced
|
Name by which you want the secret to be referenced
|
||||||
</ParamField>
|
</ParamField>
|
||||||
|
|
||||||
<ParamField path="Default TTL" type="string" required>
|
<ParamField path="Default TTL" type="string" required>
|
||||||
Default time-to-live for a generated secret (it is possible to modify this value after a secret is generated)
|
Default time-to-live for a generated secret (it is possible to modify this value after a secret is generated)
|
||||||
</ParamField>
|
</ParamField>
|
||||||
|
|
||||||
<ParamField path="Max TTL" type="string" required>
|
<ParamField path="Max TTL" type="string" required>
|
||||||
Maximum time-to-live for a generated secret
|
Maximum time-to-live for a generated secret
|
||||||
</ParamField>
|
</ParamField>
|
||||||
|
|
||||||
<ParamField path="Metadata" type="list" required>
|
<ParamField path="Metadata" type="list" required>
|
||||||
List of key/value metadata pairs
|
List of key/value metadata pairs
|
||||||
</ParamField>
|
</ParamField>
|
||||||
|
|
||||||
<ParamField path="Service" type="string" required>
|
<ParamField path="Service" type="string" required>
|
||||||
Choose the service you want to generate dynamic secrets for. This must be selected as **MS SQL**.
|
Choose the service you want to generate dynamic secrets for. This must be selected as **MS SQL**.
|
||||||
</ParamField>
|
</ParamField>
|
||||||
|
|
||||||
<ParamField path="Host" type="string" required>
|
<ParamField path="Host" type="string" required>
|
||||||
Database host
|
Database host
|
||||||
</ParamField>
|
</ParamField>
|
||||||
|
|
||||||
<ParamField path="Port" type="number" required>
|
<ParamField path="Port" type="number" required>
|
||||||
Database port
|
Database port
|
||||||
</ParamField>
|
</ParamField>
|
||||||
|
|
||||||
<ParamField path="User" type="string" required>
|
<ParamField path="User" type="string" required>
|
||||||
Username that will be used to create dynamic secrets
|
Username that will be used to create dynamic secrets
|
||||||
</ParamField>
|
</ParamField>
|
||||||
|
|
||||||
<ParamField path="Password" type="string" required>
|
<ParamField path="Password" type="string" required>
|
||||||
Password that will be used to create dynamic secrets
|
Password that will be used to create dynamic secrets
|
||||||
</ParamField>
|
</ParamField>
|
||||||
|
|
||||||
<ParamField path="Database Name" type="string" required>
|
<ParamField path="Database Name" type="string" required>
|
||||||
Name of the database for which you want to create dynamic secrets
|
Name of the database for which you want to create dynamic secrets
|
||||||
</ParamField>
|
</ParamField>
|
||||||
|
|
||||||
<ParamField path="CA(SSL)" type="string">
|
<ParamField path="CA(SSL)" type="string">
|
||||||
A CA may be required if your DB requires it for incoming connections. AWS RDS instances with default settings will requires a CA which can be downloaded [here](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.SSL.html#UsingWithRDS.SSL.CertificatesAllRegions).
|
A CA may be required if your DB requires it for incoming connections. AWS RDS instances with default settings will requires a CA which can be downloaded [here](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.SSL.html#UsingWithRDS.SSL.CertificatesAllRegions).
|
||||||
</ParamField>
|
</ParamField>
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
</Step>
|
</Step>
|
||||||
<Step title="(Optional) Modify SQL Statements">
|
<Step title="(Optional) Modify SQL Statements">
|
||||||

|

|
||||||
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
||||||
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
||||||
|
|
||||||
|
Allowed template variables are
|
||||||
|
- `{{randomUsername}}`: Random username string
|
||||||
|
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||||
|
- `{{identity.name}}`: Name of the identity that is generating the secret
|
||||||
|
- `{{random N}}`: Random string of N characters
|
||||||
|
|
||||||
|
Allowed template functions are
|
||||||
|
- `truncate`: Truncates a string to a specified length
|
||||||
|
- `replace`: Replaces a substring with another value
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
```
|
||||||
|
{{randomUsername}} // 3POnzeFyK9gW2nioK0q2gMjr6CZqsRiX
|
||||||
|
{{unixTimestamp}} // 17490641580
|
||||||
|
{{identity.name}} // testuser
|
||||||
|
{{random-5}} // x9k2m
|
||||||
|
{{truncate identity.name 4}} // test
|
||||||
|
{{replace identity.name 'user' 'replace'}} // testreplace
|
||||||
|
```
|
||||||
|
</ParamField>
|
||||||
|
|
||||||
Allowed template variables are
|
|
||||||
- `{{randomUsername}}`: Random username string
|
|
||||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
|
||||||
</ParamField>
|
|
||||||
<ParamField path="Customize SQL Statement" type="string">
|
|
||||||
If you want to provide specific privileges for the generated dynamic credentials, you can modify the SQL statement to your needs. This is useful if you want to only give access to a specific table(s).
|
|
||||||
</ParamField>
|
|
||||||
</Step>
|
</Step>
|
||||||
<Step title="Click 'Submit'">
|
<Step title="Click 'Submit'">
|
||||||
After submitting the form, you will see a dynamic secret created in the dashboard.
|
After submitting the form, you will see a dynamic secret created in the dashboard.
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
If this step fails, you may have to add the CA certificate.
|
If this step fails, you may have to add the CA certificate.
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||

|
|
||||||
</Step>
|
</Step>
|
||||||
<Step title="Generate dynamic secrets">
|
<Step title="Generate dynamic secrets">
|
||||||
Once you've successfully configured the dynamic secret, you're ready to generate on-demand credentials.
|
Once you've successfully configured the dynamic secret, you're ready to generate on-demand credentials.
|
||||||
To do this, simply click on the 'Generate' button which appears when hovering over the dynamic secret item.
|
To do this, simply click on the 'Generate' button which appears when hovering over the dynamic secret item.
|
||||||
Alternatively, you can initiate the creation of a new lease by selecting 'New Lease' from the dynamic secret lease list section.
|
Alternatively, you can initiate the creation of a new lease by selecting 'New Lease' from the dynamic secret lease list section.
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||
|
|
||||||
When generating these secrets, it's important to specify a Time-to-Live (TTL) duration. This will dictate how long the credentials are valid for.
|
When generating these secrets, it's important to specify a Time-to-Live (TTL) duration. This will dictate how long the credentials are valid for.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
<Tip>
|
<Tip>
|
||||||
Ensure that the TTL for the lease fall within the maximum TTL defined when configuring the dynamic secret.
|
Ensure that the TTL for the lease fall within the maximum TTL defined when configuring the dynamic secret.
|
||||||
</Tip>
|
</Tip>
|
||||||
|
|
||||||
|
|
||||||
Once you click the `Submit` button, a new secret lease will be generated and the credentials for it will be shown to you.
|
Once you click the `Submit` button, a new secret lease will be generated and the credentials for it will be shown to you.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||

|
|
||||||
</Step>
|
</Step>
|
||||||
</Steps>
|
</Steps>
|
||||||
|
|
||||||
## Audit or Revoke Leases
|
## Audit or Revoke Leases
|
||||||
|
|
||||||
Once you have created one or more leases, you will be able to access them by clicking on the respective dynamic secret item on the dashboard.
|
Once you have created one or more leases, you will be able to access them by clicking on the respective dynamic secret item on the dashboard.
|
||||||
This will allow you to see the expiration time of the lease or delete the lease before it's set time to live.
|
This will allow you to see the expiration time of the lease or delete the lease before it's set time to live.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Renew Leases
|
## Renew Leases
|
||||||
|
|
||||||
To extend the life of the generated dynamic secret leases past its initial time to live, simply click on the **Renew** button as illustrated below.
|
To extend the life of the generated dynamic secret leases past its initial time to live, simply click on the **Renew** button as illustrated below.
|
||||||

|

|
||||||
|
|
||||||
<Warning>
|
<Warning>
|
||||||
Lease renewals cannot exceed the maximum TTL set when configuring the dynamic secret
|
Lease renewals cannot exceed the maximum TTL set when configuring the dynamic
|
||||||
|
secret
|
||||||
</Warning>
|
</Warning>
|
||||||
|
|||||||
@@ -69,15 +69,28 @@ Create a user with the required permission in your SQL instance. This user will
|
|||||||
</Step>
|
</Step>
|
||||||
<Step title="(Optional) Modify SQL Statements">
|
<Step title="(Optional) Modify SQL Statements">
|
||||||

|

|
||||||
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
||||||
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
||||||
|
|
||||||
Allowed template variables are
|
Allowed template variables are
|
||||||
- `{{randomUsername}}`: Random username string
|
- `{{randomUsername}}`: Random username string
|
||||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||||
</ParamField>
|
- `{{identity.name}}`: Name of the identity that is generating the secret
|
||||||
<ParamField path="Customize SQL Statement" type="string">
|
- `{{random N}}`: Random string of N characters
|
||||||
If you want to provide specific privileges for the generated dynamic credentials, you can modify the SQL statement to your needs. This is useful if you want to only give access to a specific table(s).
|
|
||||||
|
Allowed template functions are
|
||||||
|
- `truncate`: Truncates a string to a specified length
|
||||||
|
- `replace`: Replaces a substring with another value
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
```
|
||||||
|
{{randomUsername}} // 3POnzeFyK9gW2nioK0q2gMjr6CZqsRiX
|
||||||
|
{{unixTimestamp}} // 17490641580
|
||||||
|
{{identity.name}} // testuser
|
||||||
|
{{random-5}} // x9k2m
|
||||||
|
{{truncate identity.name 4}} // test
|
||||||
|
{{replace identity.name 'user' 'replace'}} // testreplace
|
||||||
|
```
|
||||||
</ParamField>
|
</ParamField>
|
||||||
</Step>
|
</Step>
|
||||||
<Step title="Click `Submit`">
|
<Step title="Click `Submit`">
|
||||||
|
|||||||
@@ -71,15 +71,28 @@ Create a user with the required permission in your SQL instance. This user will
|
|||||||
</Step>
|
</Step>
|
||||||
<Step title="(Optional) Modify SQL Statements">
|
<Step title="(Optional) Modify SQL Statements">
|
||||||

|

|
||||||
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
||||||
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
||||||
|
|
||||||
Allowed template variables are
|
Allowed template variables are
|
||||||
- `{{randomUsername}}`: Random username string
|
- `{{randomUsername}}`: Random username string
|
||||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||||
</ParamField>
|
- `{{identity.name}}`: Name of the identity that is generating the secret
|
||||||
<ParamField path="Customize SQL Statement" type="string">
|
- `{{random N}}`: Random string of N characters
|
||||||
If you want to provide specific privileges for the generated dynamic credentials, you can modify the SQL statement to your needs. This is useful if you want to only give access to a specific table(s).
|
|
||||||
|
Allowed template functions are
|
||||||
|
- `truncate`: Truncates a string to a specified length
|
||||||
|
- `replace`: Replaces a substring with another value
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
```
|
||||||
|
{{randomUsername}} // 3POnzeFyK9gW2nioK0q2gMjr6CZqsRiX
|
||||||
|
{{unixTimestamp}} // 17490641580
|
||||||
|
{{identity.name}} // testuser
|
||||||
|
{{random-5}} // x9k2m
|
||||||
|
{{truncate identity.name 4}} // test
|
||||||
|
{{replace identity.name 'user' 'replace'}} // testreplace
|
||||||
|
```
|
||||||
</ParamField>
|
</ParamField>
|
||||||
</Step>
|
</Step>
|
||||||
<Step title="Click 'Submit'">
|
<Step title="Click 'Submit'">
|
||||||
|
|||||||
@@ -72,12 +72,28 @@ Create a user with the required permission in your SQL instance. This user will
|
|||||||
</Step>
|
</Step>
|
||||||
<Step title="(Optional) Modify SQL Statements">
|
<Step title="(Optional) Modify SQL Statements">
|
||||||

|

|
||||||
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
||||||
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
||||||
|
|
||||||
Allowed template variables are
|
Allowed template variables are
|
||||||
- `{{randomUsername}}`: Random username string
|
- `{{randomUsername}}`: Random username string
|
||||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||||
|
- `{{identity.name}}`: Name of the identity that is generating the secret
|
||||||
|
- `{{random N}}`: Random string of N characters
|
||||||
|
|
||||||
|
Allowed template functions are
|
||||||
|
- `truncate`: Truncates a string to a specified length
|
||||||
|
- `replace`: Replaces a substring with another value
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
```
|
||||||
|
{{randomUsername}} // 3POnzeFyK9gW2nioK0q2gMjr6CZqsRiX
|
||||||
|
{{unixTimestamp}} // 17490641580
|
||||||
|
{{identity.name}} // testuser
|
||||||
|
{{random-5}} // x9k2m
|
||||||
|
{{truncate identity.name 4}} // test
|
||||||
|
{{replace identity.name 'user' 'replace'}} // testreplace
|
||||||
|
```
|
||||||
</ParamField>
|
</ParamField>
|
||||||
<ParamField path="Customize SQL Statement" type="string">
|
<ParamField path="Customize SQL Statement" type="string">
|
||||||
If you want to provide specific privileges for the generated dynamic credentials, you can modify the SQL statement to your needs. This is useful if you want to only give access to a specific table(s).
|
If you want to provide specific privileges for the generated dynamic credentials, you can modify the SQL statement to your needs. This is useful if you want to only give access to a specific table(s).
|
||||||
|
|||||||
@@ -66,12 +66,28 @@ The port that the RabbitMQ management plugin is listening on. This is `15672` by
|
|||||||
</ParamField>
|
</ParamField>
|
||||||
|
|
||||||
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
||||||
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
||||||
|
|
||||||
Allowed template variables are
|
Allowed template variables are
|
||||||
- `{{randomUsername}}`: Random username string
|
- `{{randomUsername}}`: Random username string
|
||||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||||
</ParamField>
|
- `{{identity.name}}`: Name of the identity that is generating the secret
|
||||||
|
- `{{random N}}`: Random string of N characters
|
||||||
|
|
||||||
|
Allowed template functions are
|
||||||
|
- `truncate`: Truncates a string to a specified length
|
||||||
|
- `replace`: Replaces a substring with another value
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
```
|
||||||
|
{{randomUsername}} // 3POnzeFyK9gW2nioK0q2gMjr6CZqsRiX
|
||||||
|
{{unixTimestamp}} // 17490641580
|
||||||
|
{{identity.name}} // testuser
|
||||||
|
{{random-5}} // x9k2m
|
||||||
|
{{truncate identity.name 4}} // test
|
||||||
|
{{replace identity.name 'user' 'replace'}} // testreplace
|
||||||
|
```
|
||||||
|
</ParamField>
|
||||||
|
|
||||||
<ParamField path="CA(SSL)" type="string">
|
<ParamField path="CA(SSL)" type="string">
|
||||||
A CA may be required if your DB requires it for incoming connections. This is often the case when connecting to a managed service.
|
A CA may be required if your DB requires it for incoming connections. This is often the case when connecting to a managed service.
|
||||||
|
|||||||
@@ -57,12 +57,28 @@ Create a user with the required permission in your Redis instance. This user wil
|
|||||||
</Step>
|
</Step>
|
||||||
<Step title="(Optional) Modify Redis Statements">
|
<Step title="(Optional) Modify Redis Statements">
|
||||||

|

|
||||||
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
||||||
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
||||||
|
|
||||||
Allowed template variables are
|
Allowed template variables are
|
||||||
- `{{randomUsername}}`: Random username string
|
- `{{randomUsername}}`: Random username string
|
||||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||||
|
- `{{identity.name}}`: Name of the identity that is generating the secret
|
||||||
|
- `{{random N}}`: Random string of N characters
|
||||||
|
|
||||||
|
Allowed template functions are
|
||||||
|
- `truncate`: Truncates a string to a specified length
|
||||||
|
- `replace`: Replaces a substring with another value
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
```
|
||||||
|
{{randomUsername}} // 3POnzeFyK9gW2nioK0q2gMjr6CZqsRiX
|
||||||
|
{{unixTimestamp}} // 17490641580
|
||||||
|
{{identity.name}} // testuser
|
||||||
|
{{random-5}} // x9k2m
|
||||||
|
{{truncate identity.name 4}} // test
|
||||||
|
{{replace identity.name 'user' 'replace'}} // testreplace
|
||||||
|
```
|
||||||
</ParamField>
|
</ParamField>
|
||||||
<ParamField path="Customize Redis Statement" type="string">
|
<ParamField path="Customize Redis Statement" type="string">
|
||||||
If you want to provide specific privileges for the generated dynamic credentials, you can modify the Redis statement to your needs. This is useful if you want to only give access to a specific table(s).
|
If you want to provide specific privileges for the generated dynamic credentials, you can modify the Redis statement to your needs. This is useful if you want to only give access to a specific table(s).
|
||||||
|
|||||||
@@ -64,13 +64,29 @@ The Infisical SAP ASE dynamic secret allows you to generate SAP ASE database cre
|
|||||||
</Step>
|
</Step>
|
||||||
<Step title="(Optional) Modify SAP SQL Statements">
|
<Step title="(Optional) Modify SAP SQL Statements">
|
||||||

|

|
||||||
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
||||||
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
||||||
|
|
||||||
Allowed template variables are
|
Allowed template variables are
|
||||||
- `{{randomUsername}}`: Random username string
|
- `{{randomUsername}}`: Random username string
|
||||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||||
</ParamField>
|
- `{{identity.name}}`: Name of the identity that is generating the secret
|
||||||
|
- `{{random N}}`: Random string of N characters
|
||||||
|
|
||||||
|
Allowed template functions are
|
||||||
|
- `truncate`: Truncates a string to a specified length
|
||||||
|
- `replace`: Replaces a substring with another value
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
```
|
||||||
|
{{randomUsername}} // 3POnzeFyK9gW2nioK0q2gMjr6CZqsRiX
|
||||||
|
{{unixTimestamp}} // 17490641580
|
||||||
|
{{identity.name}} // testuser
|
||||||
|
{{random-5}} // x9k2m
|
||||||
|
{{truncate identity.name 4}} // test
|
||||||
|
{{replace identity.name 'user' 'replace'}} // testreplace
|
||||||
|
```
|
||||||
|
</ParamField>
|
||||||
<ParamField path="Customize Statement" type="string">
|
<ParamField path="Customize Statement" type="string">
|
||||||
|
|
||||||
If you want to provide specific privileges for the generated dynamic credentials, you can modify the SQL statement to your needs.
|
If you want to provide specific privileges for the generated dynamic credentials, you can modify the SQL statement to your needs.
|
||||||
|
|||||||
@@ -64,12 +64,28 @@ The Infisical SAP HANA dynamic secret allows you to generate SAP HANA database c
|
|||||||
</Step>
|
</Step>
|
||||||
<Step title="(Optional) Modify SAP SQL Statements">
|
<Step title="(Optional) Modify SAP SQL Statements">
|
||||||

|

|
||||||
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
||||||
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
||||||
|
|
||||||
Allowed template variables are
|
Allowed template variables are
|
||||||
- `{{randomUsername}}`: Random username string
|
- `{{randomUsername}}`: Random username string
|
||||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||||
|
- `{{identity.name}}`: Name of the identity that is generating the secret
|
||||||
|
- `{{random N}}`: Random string of N characters
|
||||||
|
|
||||||
|
Allowed template functions are
|
||||||
|
- `truncate`: Truncates a string to a specified length
|
||||||
|
- `replace`: Replaces a substring with another value
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
```
|
||||||
|
{{randomUsername}} // 3POnzeFyK9gW2nioK0q2gMjr6CZqsRiX
|
||||||
|
{{unixTimestamp}} // 17490641580
|
||||||
|
{{identity.name}} // testuser
|
||||||
|
{{random-5}} // x9k2m
|
||||||
|
{{truncate identity.name 4}} // test
|
||||||
|
{{replace identity.name 'user' 'replace'}} // testreplace
|
||||||
|
```
|
||||||
</ParamField>
|
</ParamField>
|
||||||
<ParamField path="Customize Statement" type="string">
|
<ParamField path="Customize Statement" type="string">
|
||||||
|
|
||||||
|
|||||||
@@ -78,12 +78,28 @@ Infisical's Snowflake dynamic secrets allow you to generate Snowflake user crede
|
|||||||
<Step title="(Optional) Modify SQL Statements">
|
<Step title="(Optional) Modify SQL Statements">
|
||||||

|

|
||||||
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
<ParamField path="Username Template" type="string" default="{{randomUsername}}">
|
||||||
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
Specifies a template for generating usernames. This field allows customization of how usernames are automatically created.
|
||||||
|
|
||||||
Allowed template variables are
|
Allowed template variables are
|
||||||
- `{{randomUsername}}`: Random username string
|
- `{{randomUsername}}`: Random username string
|
||||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||||
</ParamField>
|
- `{{identity.name}}`: Name of the identity that is generating the secret
|
||||||
|
- `{{random N}}`: Random string of N characters
|
||||||
|
|
||||||
|
Allowed template functions are
|
||||||
|
- `truncate`: Truncates a string to a specified length
|
||||||
|
- `replace`: Replaces a substring with another value
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
```
|
||||||
|
{{randomUsername}} // 3POnzeFyK9gW2nioK0q2gMjr6CZqsRiX
|
||||||
|
{{unixTimestamp}} // 17490641580
|
||||||
|
{{identity.name}} // testuser
|
||||||
|
{{random-5}} // x9k2m
|
||||||
|
{{truncate identity.name 4}} // test
|
||||||
|
{{replace identity.name 'user' 'replace'}} // testreplace
|
||||||
|
```
|
||||||
|
</ParamField>
|
||||||
<ParamField path="Customize Statement" type="string">
|
<ParamField path="Customize Statement" type="string">
|
||||||
|
|
||||||
If you want to provide specific privileges for the generated dynamic credentials, you can modify the SQL
|
If you want to provide specific privileges for the generated dynamic credentials, you can modify the SQL
|
||||||
|
|||||||
Reference in New Issue
Block a user