mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Add identityName to Dynamic Secrets userName template
This commit is contained in:
@@ -33,7 +33,7 @@ const userTemplateSchema = z
|
||||
.refine((el) => validateUsernameTemplateCharacters(el))
|
||||
.refine((el) =>
|
||||
isValidHandleBarTemplate(el, {
|
||||
allowedExpressions: (val) => ["randomUsername", "unixTimestamp"].includes(val)
|
||||
allowedExpressions: (val) => ["randomUsername", "unixTimestamp", "identityName"].includes(val)
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ForbiddenError, subject } from "@casl/ability";
|
||||
import RE2 from "re2";
|
||||
|
||||
import { ActionProjectType } from "@app/db/schemas";
|
||||
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 { logger } from "@app/lib/logger";
|
||||
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 { KmsDataKey } from "@app/services/kms/kms-types";
|
||||
import { TProjectDALFactory } from "@app/services/project/project-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 { DynamicSecretProviders, TDynamicProviderFns } from "../dynamic-secret/providers/models";
|
||||
@@ -39,6 +43,8 @@ type TDynamicSecretLeaseServiceFactoryDep = {
|
||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
||||
projectDAL: Pick<TProjectDALFactory, "findProjectBySlug">;
|
||||
kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">;
|
||||
userDAL: Pick<TUserDALFactory, "findById">;
|
||||
identityDAL: TIdentityDALFactory;
|
||||
};
|
||||
|
||||
export type TDynamicSecretLeaseServiceFactory = ReturnType<typeof dynamicSecretLeaseServiceFactory>;
|
||||
@@ -52,8 +58,16 @@ export const dynamicSecretLeaseServiceFactory = ({
|
||||
dynamicSecretQueueService,
|
||||
projectDAL,
|
||||
licenseService,
|
||||
kmsService
|
||||
kmsService,
|
||||
userDAL,
|
||||
identityDAL
|
||||
}: TDynamicSecretLeaseServiceFactoryDep) => {
|
||||
const extractEmailUsername = (email: string) => {
|
||||
const regex = new RE2(/^([^@]+)/);
|
||||
const match = email.match(regex);
|
||||
return match ? match[1] : email;
|
||||
};
|
||||
|
||||
const create = async ({
|
||||
environmentSlug,
|
||||
path,
|
||||
@@ -132,10 +146,23 @@ export const dynamicSecretLeaseServiceFactory = ({
|
||||
|
||||
let result;
|
||||
try {
|
||||
let identityName = "";
|
||||
if (actor === ActorType.USER) {
|
||||
const user = await userDAL.findById(actorId);
|
||||
if (user) {
|
||||
identityName = extractEmailUsername(user.username);
|
||||
}
|
||||
} else if (actor === ActorType.Machine) {
|
||||
const identity = await identityDAL.findById(actorId);
|
||||
if (identity) {
|
||||
identityName = identity.name;
|
||||
}
|
||||
}
|
||||
result = await selectedProvider.create({
|
||||
inputs: decryptedStoredInput,
|
||||
expireAt: expireAt.getTime(),
|
||||
usernameTemplate: dynamicSecretCfg.usernameTemplate
|
||||
usernameTemplate: dynamicSecretCfg.usernameTemplate,
|
||||
identityName
|
||||
});
|
||||
} catch (error: unknown) {
|
||||
if (error && typeof error === "object" && error !== null && "sqlMessage" in error) {
|
||||
|
||||
@@ -132,14 +132,15 @@ const generatePassword = () => {
|
||||
return customAlphabet(charset, 64)();
|
||||
};
|
||||
|
||||
const generateUsername = (usernameTemplate?: string | null) => {
|
||||
const generateUsername = (usernameTemplate?: string | null, identityName?: string) => {
|
||||
const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-";
|
||||
const randomUsername = `inf-${customAlphabet(charset, 32)()}`;
|
||||
if (!usernameTemplate) return randomUsername;
|
||||
|
||||
return handlebars.compile(usernameTemplate)({
|
||||
randomUsername,
|
||||
unixTimestamp: Math.floor(Date.now() / 100)
|
||||
unixTimestamp: Math.floor(Date.now() / 100),
|
||||
identityName
|
||||
});
|
||||
};
|
||||
|
||||
@@ -174,14 +175,19 @@ export const AwsElastiCacheDatabaseProvider = (): TDynamicProviderFns => {
|
||||
return true;
|
||||
};
|
||||
|
||||
const create = async (data: { inputs: unknown; expireAt: number; usernameTemplate?: string | null }) => {
|
||||
const { inputs, expireAt, usernameTemplate } = data;
|
||||
const create = async (data: {
|
||||
inputs: unknown;
|
||||
expireAt: number;
|
||||
usernameTemplate?: string | null;
|
||||
identityName?: string;
|
||||
}) => {
|
||||
const { inputs, expireAt, usernameTemplate, identityName } = data;
|
||||
const providerInputs = await validateProviderInputs(inputs);
|
||||
if (!(await validateConnection(providerInputs))) {
|
||||
throw new BadRequestError({ message: "Failed to establish connection" });
|
||||
}
|
||||
|
||||
const leaseUsername = generateUsername(usernameTemplate);
|
||||
const leaseUsername = generateUsername(usernameTemplate, identityName);
|
||||
const leasePassword = generatePassword();
|
||||
const leaseExpiration = new Date(expireAt).toISOString();
|
||||
|
||||
|
||||
@@ -24,13 +24,14 @@ import { alphaNumericNanoId } from "@app/lib/nanoid";
|
||||
|
||||
import { DynamicSecretAwsIamSchema, TDynamicProviderFns } from "./models";
|
||||
|
||||
const generateUsername = (usernameTemplate?: string | null) => {
|
||||
const generateUsername = (usernameTemplate?: string | null, identityName?: string) => {
|
||||
const randomUsername = alphaNumericNanoId(32);
|
||||
if (!usernameTemplate) return randomUsername;
|
||||
|
||||
return handlebars.compile(usernameTemplate)({
|
||||
randomUsername,
|
||||
unixTimestamp: Math.floor(Date.now() / 100)
|
||||
unixTimestamp: Math.floor(Date.now() / 100),
|
||||
identityName
|
||||
});
|
||||
};
|
||||
|
||||
@@ -60,13 +61,18 @@ export const AwsIamProvider = (): TDynamicProviderFns => {
|
||||
return isConnected;
|
||||
};
|
||||
|
||||
const create = async (data: { inputs: unknown; expireAt: number; usernameTemplate?: string | null }) => {
|
||||
const { inputs, usernameTemplate } = data;
|
||||
const create = async (data: {
|
||||
inputs: unknown;
|
||||
expireAt: number;
|
||||
usernameTemplate?: string | null;
|
||||
identityName?: string;
|
||||
}) => {
|
||||
const { inputs, usernameTemplate, identityName } = data;
|
||||
|
||||
const providerInputs = await validateProviderInputs(inputs);
|
||||
const client = await $getClient(providerInputs);
|
||||
|
||||
const username = generateUsername(usernameTemplate);
|
||||
const username = generateUsername(usernameTemplate, identityName);
|
||||
const { policyArns, userGroups, policyDocument, awsPath, permissionBoundaryPolicyArn } = providerInputs;
|
||||
const createUserRes = await client.send(
|
||||
new CreateUserCommand({
|
||||
|
||||
@@ -14,13 +14,14 @@ const generatePassword = (size = 48) => {
|
||||
return customAlphabet(charset, 48)(size);
|
||||
};
|
||||
|
||||
const generateUsername = (usernameTemplate?: string | null) => {
|
||||
const generateUsername = (usernameTemplate?: string | null, identityName?: string) => {
|
||||
const randomUsername = alphaNumericNanoId(32); // Username must start with an ascii letter, so we prepend the username with "inf-"
|
||||
if (!usernameTemplate) return randomUsername;
|
||||
|
||||
return handlebars.compile(usernameTemplate)({
|
||||
randomUsername,
|
||||
unixTimestamp: Math.floor(Date.now() / 100)
|
||||
unixTimestamp: Math.floor(Date.now() / 100),
|
||||
identityName
|
||||
});
|
||||
};
|
||||
|
||||
@@ -75,12 +76,17 @@ export const CassandraProvider = (): TDynamicProviderFns => {
|
||||
return isConnected;
|
||||
};
|
||||
|
||||
const create = async (data: { inputs: unknown; expireAt: number; usernameTemplate?: string | null }) => {
|
||||
const { inputs, expireAt, usernameTemplate } = data;
|
||||
const create = async (data: {
|
||||
inputs: unknown;
|
||||
expireAt: number;
|
||||
usernameTemplate?: string | null;
|
||||
identityName?: string;
|
||||
}) => {
|
||||
const { inputs, expireAt, usernameTemplate, identityName } = data;
|
||||
const providerInputs = await validateProviderInputs(inputs);
|
||||
const client = await $getClient(providerInputs);
|
||||
|
||||
const username = generateUsername(usernameTemplate);
|
||||
const username = generateUsername(usernameTemplate, identityName);
|
||||
const password = generatePassword();
|
||||
const { keyspace } = providerInputs;
|
||||
const expiration = new Date(expireAt).toISOString();
|
||||
|
||||
@@ -13,13 +13,14 @@ const generatePassword = () => {
|
||||
return customAlphabet(charset, 64)();
|
||||
};
|
||||
|
||||
const generateUsername = (usernameTemplate?: string | null) => {
|
||||
const generateUsername = (usernameTemplate?: string | null, identityName?: string) => {
|
||||
const randomUsername = alphaNumericNanoId(32); // Username must start with an ascii letter, so we prepend the username with "inf-"
|
||||
if (!usernameTemplate) return randomUsername;
|
||||
|
||||
return handlebars.compile(usernameTemplate)({
|
||||
randomUsername,
|
||||
unixTimestamp: Math.floor(Date.now() / 100)
|
||||
unixTimestamp: Math.floor(Date.now() / 100),
|
||||
identityName
|
||||
});
|
||||
};
|
||||
|
||||
@@ -71,12 +72,12 @@ export const ElasticSearchProvider = (): TDynamicProviderFns => {
|
||||
return infoResponse;
|
||||
};
|
||||
|
||||
const create = async (data: { inputs: unknown; usernameTemplate?: string | null }) => {
|
||||
const { inputs, usernameTemplate } = data;
|
||||
const create = async (data: { inputs: unknown; usernameTemplate?: string | null; identityName?: string }) => {
|
||||
const { inputs, usernameTemplate, identityName } = data;
|
||||
const providerInputs = await validateProviderInputs(inputs);
|
||||
const connection = await $getClient(providerInputs);
|
||||
|
||||
const username = generateUsername(usernameTemplate);
|
||||
const username = generateUsername(usernameTemplate, identityName);
|
||||
const password = generatePassword();
|
||||
|
||||
await connection.security.putUser({
|
||||
|
||||
@@ -22,13 +22,14 @@ const encodePassword = (password?: string) => {
|
||||
return base64Password;
|
||||
};
|
||||
|
||||
const generateUsername = (usernameTemplate?: string | null) => {
|
||||
const generateUsername = (usernameTemplate?: string | null, identityName?: string) => {
|
||||
const randomUsername = alphaNumericNanoId(32); // Username must start with an ascii letter, so we prepend the username with "inf-"
|
||||
if (!usernameTemplate) return randomUsername;
|
||||
|
||||
return handlebars.compile(usernameTemplate)({
|
||||
randomUsername,
|
||||
unixTimestamp: Math.floor(Date.now() / 100)
|
||||
unixTimestamp: Math.floor(Date.now() / 100),
|
||||
identityName
|
||||
});
|
||||
};
|
||||
|
||||
@@ -196,8 +197,8 @@ export const LdapProvider = (): TDynamicProviderFns => {
|
||||
return dnArray;
|
||||
};
|
||||
|
||||
const create = async (data: { inputs: unknown; usernameTemplate?: string | null }) => {
|
||||
const { inputs, usernameTemplate } = data;
|
||||
const create = async (data: { inputs: unknown; usernameTemplate?: string | null; identityName?: string }) => {
|
||||
const { inputs, usernameTemplate, identityName } = data;
|
||||
const providerInputs = await validateProviderInputs(inputs);
|
||||
const client = await $getClient(providerInputs);
|
||||
|
||||
@@ -224,7 +225,7 @@ export const LdapProvider = (): TDynamicProviderFns => {
|
||||
});
|
||||
}
|
||||
} else {
|
||||
const username = generateUsername(usernameTemplate);
|
||||
const username = generateUsername(usernameTemplate, identityName);
|
||||
const password = generatePassword();
|
||||
const generatedLdif = generateLDIF({ username, password, ldifTemplate: providerInputs.creationLdif });
|
||||
|
||||
|
||||
@@ -364,6 +364,7 @@ export type TDynamicProviderFns = {
|
||||
inputs: unknown;
|
||||
expireAt: number;
|
||||
usernameTemplate?: string | null;
|
||||
identityName?: string;
|
||||
}) => Promise<{ entityId: string; data: unknown }>;
|
||||
validateConnection: (inputs: unknown) => Promise<boolean>;
|
||||
validateProviderInputs: (inputs: object) => Promise<unknown>;
|
||||
|
||||
@@ -13,13 +13,14 @@ const generatePassword = (size = 48) => {
|
||||
return customAlphabet(charset, 48)(size);
|
||||
};
|
||||
|
||||
const generateUsername = (usernameTemplate?: string | null) => {
|
||||
const generateUsername = (usernameTemplate?: string | null, identityName?: string) => {
|
||||
const randomUsername = alphaNumericNanoId(32);
|
||||
if (!usernameTemplate) return randomUsername;
|
||||
|
||||
return handlebars.compile(usernameTemplate)({
|
||||
randomUsername,
|
||||
unixTimestamp: Math.floor(Date.now() / 100)
|
||||
unixTimestamp: Math.floor(Date.now() / 100),
|
||||
identityName
|
||||
});
|
||||
};
|
||||
|
||||
@@ -64,12 +65,17 @@ export const MongoAtlasProvider = (): TDynamicProviderFns => {
|
||||
return isConnected;
|
||||
};
|
||||
|
||||
const create = async (data: { inputs: unknown; expireAt: number; usernameTemplate?: string | null }) => {
|
||||
const { inputs, expireAt, usernameTemplate } = data;
|
||||
const create = async (data: {
|
||||
inputs: unknown;
|
||||
expireAt: number;
|
||||
usernameTemplate?: string | null;
|
||||
identityName?: string;
|
||||
}) => {
|
||||
const { inputs, expireAt, usernameTemplate, identityName } = data;
|
||||
const providerInputs = await validateProviderInputs(inputs);
|
||||
const client = await $getClient(providerInputs);
|
||||
|
||||
const username = generateUsername(usernameTemplate);
|
||||
const username = generateUsername(usernameTemplate, identityName);
|
||||
const password = generatePassword();
|
||||
const expiration = new Date(expireAt).toISOString();
|
||||
await client({
|
||||
|
||||
@@ -13,13 +13,14 @@ const generatePassword = (size = 48) => {
|
||||
return customAlphabet(charset, 48)(size);
|
||||
};
|
||||
|
||||
const generateUsername = (usernameTemplate?: string | null) => {
|
||||
const generateUsername = (usernameTemplate?: string | null, identityName?: string) => {
|
||||
const randomUsername = alphaNumericNanoId(32);
|
||||
if (!usernameTemplate) return randomUsername;
|
||||
|
||||
return handlebars.compile(usernameTemplate)({
|
||||
randomUsername,
|
||||
unixTimestamp: Math.floor(Date.now() / 100)
|
||||
unixTimestamp: Math.floor(Date.now() / 100),
|
||||
identityName
|
||||
});
|
||||
};
|
||||
|
||||
@@ -60,12 +61,12 @@ export const MongoDBProvider = (): TDynamicProviderFns => {
|
||||
return isConnected;
|
||||
};
|
||||
|
||||
const create = async (data: { inputs: unknown; usernameTemplate?: string | null }) => {
|
||||
const { inputs, usernameTemplate } = data;
|
||||
const create = async (data: { inputs: unknown; usernameTemplate?: string | null; identityName?: string }) => {
|
||||
const { inputs, usernameTemplate, identityName } = data;
|
||||
const providerInputs = await validateProviderInputs(inputs);
|
||||
const client = await $getClient(providerInputs);
|
||||
|
||||
const username = generateUsername(usernameTemplate);
|
||||
const username = generateUsername(usernameTemplate, identityName);
|
||||
const password = generatePassword();
|
||||
|
||||
const db = client.db(providerInputs.database);
|
||||
|
||||
@@ -15,13 +15,14 @@ const generatePassword = () => {
|
||||
return customAlphabet(charset, 64)();
|
||||
};
|
||||
|
||||
const generateUsername = (usernameTemplate?: string | null) => {
|
||||
const generateUsername = (usernameTemplate?: string | null, identityName?: string) => {
|
||||
const randomUsername = alphaNumericNanoId(32); // Username must start with an ascii letter, so we prepend the username with "inf-"
|
||||
if (!usernameTemplate) return randomUsername;
|
||||
|
||||
return handlebars.compile(usernameTemplate)({
|
||||
randomUsername,
|
||||
unixTimestamp: Math.floor(Date.now() / 100)
|
||||
unixTimestamp: Math.floor(Date.now() / 100),
|
||||
identityName
|
||||
});
|
||||
};
|
||||
|
||||
@@ -117,12 +118,12 @@ export const RabbitMqProvider = (): TDynamicProviderFns => {
|
||||
return infoResponse;
|
||||
};
|
||||
|
||||
const create = async (data: { inputs: unknown; usernameTemplate?: string | null }) => {
|
||||
const { inputs, usernameTemplate } = data;
|
||||
const create = async (data: { inputs: unknown; usernameTemplate?: string | null; identityName?: string }) => {
|
||||
const { inputs, usernameTemplate, identityName } = data;
|
||||
const providerInputs = await validateProviderInputs(inputs);
|
||||
const connection = await $getClient(providerInputs);
|
||||
|
||||
const username = generateUsername(usernameTemplate);
|
||||
const username = generateUsername(usernameTemplate, identityName);
|
||||
const password = generatePassword();
|
||||
|
||||
await createRabbitMqUser({
|
||||
|
||||
@@ -15,13 +15,14 @@ const generatePassword = () => {
|
||||
return customAlphabet(charset, 64)();
|
||||
};
|
||||
|
||||
const generateUsername = (usernameTemplate?: string | null) => {
|
||||
const generateUsername = (usernameTemplate?: string | null, identityName?: string) => {
|
||||
const randomUsername = alphaNumericNanoId(32); // Username must start with an ascii letter, so we prepend the username with "inf-"
|
||||
if (!usernameTemplate) return randomUsername;
|
||||
|
||||
return handlebars.compile(usernameTemplate)({
|
||||
randomUsername,
|
||||
unixTimestamp: Math.floor(Date.now() / 100)
|
||||
unixTimestamp: Math.floor(Date.now() / 100),
|
||||
identityName
|
||||
});
|
||||
};
|
||||
|
||||
@@ -121,12 +122,17 @@ export const RedisDatabaseProvider = (): TDynamicProviderFns => {
|
||||
return pingResponse;
|
||||
};
|
||||
|
||||
const create = async (data: { inputs: unknown; expireAt: number; usernameTemplate?: string | null }) => {
|
||||
const { inputs, expireAt, usernameTemplate } = data;
|
||||
const create = async (data: {
|
||||
inputs: unknown;
|
||||
expireAt: number;
|
||||
usernameTemplate?: string | null;
|
||||
identityName?: string;
|
||||
}) => {
|
||||
const { inputs, expireAt, usernameTemplate, identityName } = data;
|
||||
const providerInputs = await validateProviderInputs(inputs);
|
||||
const connection = await $getClient(providerInputs);
|
||||
|
||||
const username = generateUsername(usernameTemplate);
|
||||
const username = generateUsername(usernameTemplate, identityName);
|
||||
const password = generatePassword();
|
||||
const expiration = new Date(expireAt).toISOString();
|
||||
|
||||
|
||||
@@ -15,13 +15,14 @@ const generatePassword = (size = 48) => {
|
||||
return customAlphabet(charset, 48)(size);
|
||||
};
|
||||
|
||||
const generateUsername = (usernameTemplate?: string | null) => {
|
||||
const generateUsername = (usernameTemplate?: string | null, identityName?: string) => {
|
||||
const randomUsername = `inf_${alphaNumericNanoId(25)}`; // Username must start with an ascii letter, so we prepend the username with "inf-"
|
||||
if (!usernameTemplate) return randomUsername;
|
||||
|
||||
return handlebars.compile(usernameTemplate)({
|
||||
randomUsername,
|
||||
unixTimestamp: Math.floor(Date.now() / 100)
|
||||
unixTimestamp: Math.floor(Date.now() / 100),
|
||||
identityName
|
||||
});
|
||||
};
|
||||
|
||||
@@ -87,11 +88,11 @@ export const SapAseProvider = (): TDynamicProviderFns => {
|
||||
return true;
|
||||
};
|
||||
|
||||
const create = async (data: { inputs: unknown; usernameTemplate?: string | null }) => {
|
||||
const { inputs, usernameTemplate } = data;
|
||||
const create = async (data: { inputs: unknown; usernameTemplate?: string | null; identityName?: string }) => {
|
||||
const { inputs, usernameTemplate, identityName } = data;
|
||||
const providerInputs = await validateProviderInputs(inputs);
|
||||
|
||||
const username = generateUsername(usernameTemplate);
|
||||
const username = generateUsername(usernameTemplate, identityName);
|
||||
const password = generatePassword();
|
||||
|
||||
const client = await $getClient(providerInputs);
|
||||
|
||||
@@ -21,13 +21,14 @@ const generatePassword = (size = 48) => {
|
||||
return customAlphabet(charset, 48)(size);
|
||||
};
|
||||
|
||||
const generateUsername = (usernameTemplate?: string | null) => {
|
||||
const generateUsername = (usernameTemplate?: string | null, identityName?: string) => {
|
||||
const randomUsername = alphaNumericNanoId(32); // Username must start with an ascii letter, so we prepend the username with "inf-"
|
||||
if (!usernameTemplate) return randomUsername;
|
||||
|
||||
return handlebars.compile(usernameTemplate)({
|
||||
randomUsername,
|
||||
unixTimestamp: Math.floor(Date.now() / 100)
|
||||
unixTimestamp: Math.floor(Date.now() / 100),
|
||||
identityName
|
||||
});
|
||||
};
|
||||
|
||||
@@ -97,11 +98,16 @@ export const SapHanaProvider = (): TDynamicProviderFns => {
|
||||
return testResult;
|
||||
};
|
||||
|
||||
const create = async (data: { inputs: unknown; expireAt: number; usernameTemplate?: string | null }) => {
|
||||
const { inputs, expireAt, usernameTemplate } = data;
|
||||
const create = async (data: {
|
||||
inputs: unknown;
|
||||
expireAt: number;
|
||||
usernameTemplate?: string | null;
|
||||
identityName?: string;
|
||||
}) => {
|
||||
const { inputs, expireAt, usernameTemplate, identityName } = data;
|
||||
const providerInputs = await validateProviderInputs(inputs);
|
||||
|
||||
const username = generateUsername(usernameTemplate);
|
||||
const username = generateUsername(usernameTemplate, identityName);
|
||||
const password = generatePassword();
|
||||
const expiration = new Date(expireAt).toISOString();
|
||||
|
||||
|
||||
@@ -17,13 +17,14 @@ const generatePassword = (size = 48) => {
|
||||
return customAlphabet(charset, 48)(size);
|
||||
};
|
||||
|
||||
const generateUsername = (usernameTemplate?: string | null) => {
|
||||
const generateUsername = (usernameTemplate?: string | null, identityName?: string) => {
|
||||
const randomUsername = `infisical_${alphaNumericNanoId(32)}`; // Username must start with an ascii letter, so we prepend the username with "inf-"
|
||||
if (!usernameTemplate) return randomUsername;
|
||||
|
||||
return handlebars.compile(usernameTemplate)({
|
||||
randomUsername,
|
||||
unixTimestamp: Math.floor(Date.now() / 100)
|
||||
unixTimestamp: Math.floor(Date.now() / 100),
|
||||
identityName
|
||||
});
|
||||
};
|
||||
|
||||
@@ -88,13 +89,18 @@ export const SnowflakeProvider = (): TDynamicProviderFns => {
|
||||
return isValidConnection;
|
||||
};
|
||||
|
||||
const create = async (data: { inputs: unknown; expireAt: number; usernameTemplate?: string | null }) => {
|
||||
const { inputs, expireAt, usernameTemplate } = data;
|
||||
const create = async (data: {
|
||||
inputs: unknown;
|
||||
expireAt: number;
|
||||
usernameTemplate?: string | null;
|
||||
identityName?: string;
|
||||
}) => {
|
||||
const { inputs, expireAt, usernameTemplate, identityName } = data;
|
||||
const providerInputs = await validateProviderInputs(inputs);
|
||||
|
||||
const client = await $getClient(providerInputs);
|
||||
|
||||
const username = generateUsername(usernameTemplate);
|
||||
const username = generateUsername(usernameTemplate, identityName);
|
||||
const password = generatePassword();
|
||||
|
||||
try {
|
||||
|
||||
@@ -104,9 +104,8 @@ const generatePassword = (provider: SqlProviders, requirements?: PasswordRequire
|
||||
}
|
||||
};
|
||||
|
||||
const generateUsername = (provider: SqlProviders, usernameTemplate?: string | null) => {
|
||||
const generateUsername = (provider: SqlProviders, usernameTemplate?: string | null, identityName?: string) => {
|
||||
let randomUsername = "";
|
||||
|
||||
// For oracle, the client assumes everything is upper case when not using quotes around the password
|
||||
if (provider === SqlProviders.Oracle) {
|
||||
randomUsername = alphaNumericNanoId(32).toUpperCase();
|
||||
@@ -117,7 +116,8 @@ const generateUsername = (provider: SqlProviders, usernameTemplate?: string | nu
|
||||
|
||||
return handlebars.compile(usernameTemplate)({
|
||||
randomUsername,
|
||||
unixTimestamp: Math.floor(Date.now() / 100)
|
||||
unixTimestamp: Math.floor(Date.now() / 100),
|
||||
identityName
|
||||
});
|
||||
};
|
||||
|
||||
@@ -220,11 +220,16 @@ export const SqlDatabaseProvider = ({ gatewayService }: TSqlDatabaseProviderDTO)
|
||||
return isConnected;
|
||||
};
|
||||
|
||||
const create = async (data: { inputs: unknown; expireAt: number; usernameTemplate?: string | null }) => {
|
||||
const { inputs, expireAt, usernameTemplate } = data;
|
||||
const create = async (data: {
|
||||
inputs: unknown;
|
||||
expireAt: number;
|
||||
usernameTemplate?: string | null;
|
||||
identityName?: string;
|
||||
}) => {
|
||||
const { inputs, expireAt, usernameTemplate, identityName } = data;
|
||||
|
||||
const providerInputs = await validateProviderInputs(inputs);
|
||||
const username = generateUsername(providerInputs.client, usernameTemplate);
|
||||
const username = generateUsername(providerInputs.client, usernameTemplate, identityName);
|
||||
|
||||
const password = generatePassword(providerInputs.client, providerInputs.passwordRequirements);
|
||||
const gatewayCallback = async (host = providerInputs.host, port = providerInputs.port) => {
|
||||
|
||||
@@ -1508,7 +1508,9 @@ export const registerRoutes = async (
|
||||
dynamicSecretProviders,
|
||||
folderDAL,
|
||||
licenseService,
|
||||
kmsService
|
||||
kmsService,
|
||||
userDAL,
|
||||
identityDAL
|
||||
});
|
||||
const dailyResourceCleanUp = dailyResourceCleanUpQueueServiceFactory({
|
||||
auditLogDAL,
|
||||
|
||||
@@ -101,6 +101,7 @@ The Infisical AWS ElastiCache dynamic secret allows you to generate AWS ElastiCa
|
||||
Allowed template variables are
|
||||
- `{{randomUsername}}`: Random username string
|
||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||
- `{{identityName}}`: Name of the identity that is generating the secret
|
||||
</ParamField>
|
||||
<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.
|
||||
|
||||
@@ -111,6 +111,7 @@ Specifies a template for generating usernames. This field allows customization o
|
||||
Allowed template variables are
|
||||
- `{{randomUsername}}`: Random username string
|
||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||
- `{{identityName}}`: Name of the identity that is generating the secret
|
||||
</ParamField>
|
||||
|
||||

|
||||
|
||||
@@ -85,6 +85,7 @@ The above configuration allows user creation and granting permissions.
|
||||
Allowed template variables are
|
||||
- `{{randomUsername}}`: Random username string
|
||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||
- `{{identityName}}`: Name of the identity that is generating the secret
|
||||
</ParamField>
|
||||
<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).
|
||||
|
||||
@@ -93,6 +93,7 @@ The port that your Elasticsearch instance is running on. _(Example: 9200)_
|
||||
Allowed template variables are
|
||||
- `{{randomUsername}}`: Random username string
|
||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||
- `{{identityName}}`: Name of the identity that is generating the secret
|
||||
</ParamField>
|
||||
|
||||

|
||||
|
||||
@@ -129,6 +129,7 @@ The Infisical LDAP dynamic secret allows you to generate user credentials on dem
|
||||
Allowed template variables are
|
||||
- `{{randomUsername}}`: Random username string
|
||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||
- `{{identityName}}`: Name of the identity that is generating the secret
|
||||
</ParamField>
|
||||
</Step>
|
||||
|
||||
|
||||
@@ -69,6 +69,7 @@ Create a project scoped API Key with the required permission in your Mongo Atlas
|
||||
Allowed template variables are
|
||||
- `{{randomUsername}}`: Random username string
|
||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||
- `{{identityName}}`: Name of the identity that is generating the secret
|
||||
</ParamField>
|
||||
<ParamField path="Customize Scope" type="string">
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ Create a user with the required permission in your MongoDB instance. This user w
|
||||
Allowed template variables are
|
||||
- `{{randomUsername}}`: Random username string
|
||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||
- `{{identityName}}`: Name of the identity that is generating the secret
|
||||
</ParamField>
|
||||
|
||||

|
||||
|
||||
@@ -78,6 +78,7 @@ Create a user with the required permission in your SQL instance. This user will
|
||||
Allowed template variables are
|
||||
- `{{randomUsername}}`: Random username string
|
||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||
- `{{identityName}}`: Name of the identity that is generating the secret
|
||||
</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).
|
||||
|
||||
@@ -75,6 +75,7 @@ Create a user with the required permission in your SQL instance. This user will
|
||||
Allowed template variables are
|
||||
- `{{randomUsername}}`: Random username string
|
||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||
- `{{identityName}}`: Name of the identity that is generating the secret
|
||||
</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).
|
||||
|
||||
@@ -77,6 +77,7 @@ Create a user with the required permission in your SQL instance. This user will
|
||||
Allowed template variables are
|
||||
- `{{randomUsername}}`: Random username string
|
||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||
- `{{identityName}}`: Name of the identity that is generating the secret
|
||||
</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).
|
||||
|
||||
@@ -78,6 +78,7 @@ Create a user with the required permission in your SQL instance. This user will
|
||||
Allowed template variables are
|
||||
- `{{randomUsername}}`: Random username string
|
||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||
- `{{identityName}}`: Name of the identity that is generating the secret
|
||||
</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).
|
||||
|
||||
@@ -71,6 +71,7 @@ Specifies a template for generating usernames. This field allows customization o
|
||||
Allowed template variables are
|
||||
- `{{randomUsername}}`: Random username string
|
||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||
- `{{identityName}}`: Name of the identity that is generating the secret
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="CA(SSL)" type="string">
|
||||
|
||||
@@ -63,6 +63,7 @@ Create a user with the required permission in your Redis instance. This user wil
|
||||
Allowed template variables are
|
||||
- `{{randomUsername}}`: Random username string
|
||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||
- `{{identityName}}`: Name of the identity that is generating the secret
|
||||
</ParamField>
|
||||
<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).
|
||||
|
||||
@@ -70,6 +70,7 @@ The Infisical SAP ASE dynamic secret allows you to generate SAP ASE database cre
|
||||
Allowed template variables are
|
||||
- `{{randomUsername}}`: Random username string
|
||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||
- `{{identityName}}`: Name of the identity that is generating the secret
|
||||
</ParamField>
|
||||
<ParamField path="Customize Statement" type="string">
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@ The Infisical SAP HANA dynamic secret allows you to generate SAP HANA database c
|
||||
Allowed template variables are
|
||||
- `{{randomUsername}}`: Random username string
|
||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||
- `{{identityName}}`: Name of the identity that is generating the secret
|
||||
</ParamField>
|
||||
<ParamField path="Customize Statement" type="string">
|
||||
|
||||
|
||||
@@ -83,6 +83,7 @@ Infisical's Snowflake dynamic secrets allow you to generate Snowflake user crede
|
||||
Allowed template variables are
|
||||
- `{{randomUsername}}`: Random username string
|
||||
- `{{unixTimestamp}}`: Current Unix timestamp
|
||||
- `{{identityName}}`: Name of the identity that is generating the secret
|
||||
</ParamField>
|
||||
<ParamField path="Customize Statement" type="string">
|
||||
|
||||
|
||||
Reference in New Issue
Block a user