mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-16 13:56:43 +00:00
feat: half-way done through integrating with platform
This commit is contained in:
@@ -73,6 +73,7 @@ export const dynamicSecretServiceFactory = ({
|
||||
metadata,
|
||||
usernameTemplate
|
||||
}) => {
|
||||
let isGatewayV1 = true;
|
||||
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
|
||||
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
|
||||
|
||||
@@ -129,6 +130,10 @@ export const dynamicSecretServiceFactory = ({
|
||||
});
|
||||
}
|
||||
|
||||
if (!gateway) {
|
||||
isGatewayV1 = false;
|
||||
}
|
||||
|
||||
const { permission: orgPermission } = await permissionService.getOrgPermission(
|
||||
actor,
|
||||
actorId,
|
||||
@@ -163,7 +168,8 @@ export const dynamicSecretServiceFactory = ({
|
||||
defaultTTL,
|
||||
folderId: folder.id,
|
||||
name,
|
||||
gatewayId: selectedGatewayId,
|
||||
gatewayId: isGatewayV1 ? selectedGatewayId : undefined,
|
||||
gatewayV2Id: isGatewayV1 ? undefined : selectedGatewayId,
|
||||
usernameTemplate
|
||||
},
|
||||
tx
|
||||
@@ -274,20 +280,27 @@ export const dynamicSecretServiceFactory = ({
|
||||
const updatedInput = await selectedProvider.validateProviderInputs(newInput, { projectId });
|
||||
|
||||
let selectedGatewayId: string | null = null;
|
||||
let isGatewayV1 = true;
|
||||
if (updatedInput && typeof updatedInput === "object" && "gatewayId" in updatedInput && updatedInput?.gatewayId) {
|
||||
const gatewayId = updatedInput.gatewayId as string;
|
||||
|
||||
const [gateway] = await gatewayDAL.find({ id: gatewayId, orgId: actorOrgId });
|
||||
if (!gateway) {
|
||||
const [gatewayv2] = await gatewayV2DAL.find({ id: gatewayId, orgId: actorOrgId });
|
||||
|
||||
if (!gateway && !gatewayv2) {
|
||||
throw new NotFoundError({
|
||||
message: `Gateway with ID ${gatewayId} not found`
|
||||
});
|
||||
}
|
||||
|
||||
if (!gateway) {
|
||||
isGatewayV1 = false;
|
||||
}
|
||||
|
||||
const { permission: orgPermission } = await permissionService.getOrgPermission(
|
||||
actor,
|
||||
actorId,
|
||||
gateway.orgId,
|
||||
actorOrgId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
);
|
||||
@@ -297,7 +310,7 @@ export const dynamicSecretServiceFactory = ({
|
||||
OrgPermissionSubjects.Gateway
|
||||
);
|
||||
|
||||
selectedGatewayId = gateway.id;
|
||||
selectedGatewayId = gateway?.id ?? gatewayv2?.id;
|
||||
}
|
||||
|
||||
const isConnected = await selectedProvider.validateConnection(newInput, { projectId });
|
||||
@@ -313,7 +326,8 @@ export const dynamicSecretServiceFactory = ({
|
||||
defaultTTL,
|
||||
name: newName ?? name,
|
||||
status: null,
|
||||
gatewayId: selectedGatewayId,
|
||||
gatewayId: isGatewayV1 ? selectedGatewayId : null,
|
||||
gatewayV2Id: isGatewayV1 ? null : selectedGatewayId,
|
||||
usernameTemplate
|
||||
},
|
||||
tx
|
||||
|
||||
@@ -32,7 +32,7 @@ export const buildDynamicSecretProviders = ({
|
||||
gatewayService,
|
||||
gatewayV2Service
|
||||
}: TBuildDynamicSecretProviderDTO): Record<DynamicSecretProviders, TDynamicProviderFns> => ({
|
||||
[DynamicSecretProviders.SqlDatabase]: SqlDatabaseProvider({ gatewayService }),
|
||||
[DynamicSecretProviders.SqlDatabase]: SqlDatabaseProvider({ gatewayService, gatewayV2Service }),
|
||||
[DynamicSecretProviders.Cassandra]: CassandraProvider(),
|
||||
[DynamicSecretProviders.AwsIam]: AwsIamProvider(),
|
||||
[DynamicSecretProviders.Redis]: RedisDatabaseProvider(),
|
||||
|
||||
@@ -64,7 +64,11 @@ export const KubernetesProvider = ({
|
||||
},
|
||||
gatewayCallback: (host: string, port: number, httpsAgent?: https.Agent) => Promise<T>
|
||||
): Promise<T> => {
|
||||
const gatewayV2ConnectionDetails = await gatewayV2Service.getPlatformConnectionDetailsByGatewayId(inputs.gatewayId);
|
||||
const gatewayV2ConnectionDetails = await gatewayV2Service.getPlatformConnectionDetailsByGatewayId({
|
||||
gatewayId: inputs.gatewayId,
|
||||
targetHost: inputs.targetHost,
|
||||
targetPort: inputs.targetPort
|
||||
});
|
||||
if (gatewayV2ConnectionDetails) {
|
||||
const callbackResult = await withGatewayV2Proxy(
|
||||
async (port) => {
|
||||
@@ -77,7 +81,9 @@ export const KubernetesProvider = ({
|
||||
{
|
||||
proxyIp: gatewayV2ConnectionDetails.proxyIp,
|
||||
gateway: gatewayV2ConnectionDetails.gateway,
|
||||
proxy: gatewayV2ConnectionDetails.proxy
|
||||
proxy: gatewayV2ConnectionDetails.proxy,
|
||||
protocol: inputs.reviewTokenThroughGateway ? GatewayProxyProtocol.Http : GatewayProxyProtocol.Tcp,
|
||||
httpsAgent: inputs.httpsAgent
|
||||
}
|
||||
);
|
||||
|
||||
@@ -379,8 +385,18 @@ export const KubernetesProvider = ({
|
||||
return true;
|
||||
} catch (error) {
|
||||
let errorMessage = error instanceof Error ? error.message : "Unknown error";
|
||||
if (axios.isAxiosError(error) && (error.response?.data as { message: string })?.message) {
|
||||
errorMessage = (error.response?.data as { message: string }).message;
|
||||
if (axios.isAxiosError(error)) {
|
||||
if (error.response) {
|
||||
let { message } = error?.response?.data as unknown as { message?: string };
|
||||
|
||||
if (!message && typeof error.response.data === "string") {
|
||||
message = error.response.data;
|
||||
}
|
||||
|
||||
if (message) {
|
||||
errorMessage = message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const sanitizedErrorMessage = sanitizeString({
|
||||
@@ -629,8 +645,18 @@ export const KubernetesProvider = ({
|
||||
};
|
||||
} catch (error) {
|
||||
let errorMessage = error instanceof Error ? error.message : "Unknown error";
|
||||
if (axios.isAxiosError(error) && (error.response?.data as { message: string })?.message) {
|
||||
errorMessage = (error.response?.data as { message: string }).message;
|
||||
if (axios.isAxiosError(error)) {
|
||||
if (error.response) {
|
||||
let { message } = error?.response?.data as unknown as { message?: string };
|
||||
|
||||
if (!message && typeof error.response.data === "string") {
|
||||
message = error.response.data;
|
||||
}
|
||||
|
||||
if (message) {
|
||||
errorMessage = message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const sanitizedErrorMessage = sanitizeString({
|
||||
@@ -766,8 +792,18 @@ export const KubernetesProvider = ({
|
||||
}
|
||||
} catch (error) {
|
||||
let errorMessage = error instanceof Error ? error.message : "Unknown error";
|
||||
if (axios.isAxiosError(error) && (error.response?.data as { message: string })?.message) {
|
||||
errorMessage = (error.response?.data as { message: string }).message;
|
||||
if (axios.isAxiosError(error)) {
|
||||
if (error.response) {
|
||||
let { message } = error?.response?.data as unknown as { message?: string };
|
||||
|
||||
if (!message && typeof error.response.data === "string") {
|
||||
message = error.response.data;
|
||||
}
|
||||
|
||||
if (message) {
|
||||
errorMessage = message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const sanitizedErrorMessage = sanitizeString({
|
||||
|
||||
@@ -6,10 +6,12 @@ import { crypto } from "@app/lib/crypto/cryptography";
|
||||
import { BadRequestError } from "@app/lib/errors";
|
||||
import { sanitizeString } from "@app/lib/fn";
|
||||
import { GatewayProxyProtocol, withGatewayProxy } from "@app/lib/gateway";
|
||||
import { withGatewayV2Proxy } from "@app/lib/gateway-v2/gateway-v2";
|
||||
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
||||
import { validateHandlebarTemplate } from "@app/lib/template/validate-handlebars";
|
||||
|
||||
import { TGatewayServiceFactory } from "../../gateway/gateway-service";
|
||||
import { TGatewayV2ServiceFactory } from "../../gateway-v2/gateway-v2-service";
|
||||
import { verifyHostInputValidity } from "../dynamic-secret-fns";
|
||||
import { DynamicSecretSqlDBSchema, PasswordRequirements, SqlProviders, TDynamicProviderFns } from "./models";
|
||||
import { compileUsernameTemplate } from "./templateUtils";
|
||||
@@ -128,9 +130,13 @@ const generateUsername = (provider: SqlProviders, usernameTemplate?: string | nu
|
||||
|
||||
type TSqlDatabaseProviderDTO = {
|
||||
gatewayService: Pick<TGatewayServiceFactory, "fnGetGatewayClientTlsByGatewayId">;
|
||||
gatewayV2Service: Pick<TGatewayV2ServiceFactory, "getPlatformConnectionDetailsByGatewayId">;
|
||||
};
|
||||
|
||||
export const SqlDatabaseProvider = ({ gatewayService }: TSqlDatabaseProviderDTO): TDynamicProviderFns => {
|
||||
export const SqlDatabaseProvider = ({
|
||||
gatewayService,
|
||||
gatewayV2Service
|
||||
}: TSqlDatabaseProviderDTO): TDynamicProviderFns => {
|
||||
const validateProviderInputs = async (inputs: unknown) => {
|
||||
const providerInputs = await DynamicSecretSqlDBSchema.parseAsync(inputs);
|
||||
|
||||
@@ -183,6 +189,26 @@ export const SqlDatabaseProvider = ({ gatewayService }: TSqlDatabaseProviderDTO)
|
||||
providerInputs: z.infer<typeof DynamicSecretSqlDBSchema>,
|
||||
gatewayCallback: (host: string, port: number) => Promise<void>
|
||||
) => {
|
||||
const gatewayV2ConnectionDetails = await gatewayV2Service.getPlatformConnectionDetailsByGatewayId({
|
||||
gatewayId: providerInputs.gatewayId as string,
|
||||
targetHost: providerInputs.host,
|
||||
targetPort: providerInputs.port
|
||||
});
|
||||
|
||||
if (gatewayV2ConnectionDetails) {
|
||||
return withGatewayV2Proxy(
|
||||
async (port) => {
|
||||
await gatewayCallback("localhost", port);
|
||||
},
|
||||
{
|
||||
proxyIp: gatewayV2ConnectionDetails.proxyIp,
|
||||
gateway: gatewayV2ConnectionDetails.gateway,
|
||||
proxy: gatewayV2ConnectionDetails.proxy,
|
||||
protocol: GatewayProxyProtocol.Tcp
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const relayDetails = await gatewayService.fnGetGatewayClientTlsByGatewayId(providerInputs.gatewayId as string);
|
||||
const [relayHost, relayPort] = relayDetails.relayAddress.split(":");
|
||||
await withGatewayProxy(
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
export const GATEWAY_ROUTING_INFO_OID = "1.3.6.1.4.1.12345.100.1";
|
||||
export const GATEWAY_ACTOR_OID = "1.3.6.1.4.1.12345.100.2";
|
||||
@@ -15,14 +15,17 @@ import {
|
||||
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
||||
import { KmsDataKey } from "@app/services/kms/kms-types";
|
||||
|
||||
import { TLicenseServiceFactory } from "../license/license-service";
|
||||
import { TProxyDALFactory } from "../proxy/proxy-dal";
|
||||
import { isInstanceProxy } from "../proxy/proxy-fns";
|
||||
import { TProxyServiceFactory } from "../proxy/proxy-service";
|
||||
import { GATEWAY_ACTOR_OID, GATEWAY_ROUTING_INFO_OID } from "./gateway-v2-constants";
|
||||
import { TGatewayV2DALFactory } from "./gateway-v2-dal";
|
||||
import { TOrgGatewayConfigV2DALFactory } from "./org-gateway-config-v2-dal";
|
||||
|
||||
type TGatewayV2ServiceFactoryDep = {
|
||||
orgGatewayConfigV2DAL: Pick<TOrgGatewayConfigV2DALFactory, "findOne" | "create" | "transaction" | "findById">;
|
||||
licenseService: Pick<TLicenseServiceFactory, "onPremFeatures" | "getPlan">;
|
||||
kmsService: TKmsServiceFactory;
|
||||
proxyService: TProxyServiceFactory;
|
||||
gatewayV2DAL: TGatewayV2DALFactory;
|
||||
@@ -33,6 +36,7 @@ export type TGatewayV2ServiceFactory = ReturnType<typeof gatewayV2ServiceFactory
|
||||
|
||||
export const gatewayV2ServiceFactory = ({
|
||||
orgGatewayConfigV2DAL,
|
||||
licenseService,
|
||||
kmsService,
|
||||
proxyService,
|
||||
gatewayV2DAL,
|
||||
@@ -231,7 +235,15 @@ export const gatewayV2ServiceFactory = ({
|
||||
return gateways;
|
||||
};
|
||||
|
||||
const getPlatformConnectionDetailsByGatewayId = async (gatewayId: string) => {
|
||||
const getPlatformConnectionDetailsByGatewayId = async ({
|
||||
gatewayId,
|
||||
targetHost,
|
||||
targetPort
|
||||
}: {
|
||||
gatewayId: string;
|
||||
targetHost: string;
|
||||
targetPort: number;
|
||||
}) => {
|
||||
const gateway = await gatewayV2DAL.findById(gatewayId);
|
||||
if (!gateway) {
|
||||
return;
|
||||
@@ -248,12 +260,12 @@ export const gatewayV2ServiceFactory = ({
|
||||
});
|
||||
}
|
||||
|
||||
// const orgLicensePlan = await licenseService.getPlan(orgGatewayConfig.orgId);
|
||||
// if (!orgLicensePlan.gateway) {
|
||||
// throw new BadRequestError({
|
||||
// message: "Please upgrade your instance to Infisical's Enterprise plan to use gateways."
|
||||
// });
|
||||
// }
|
||||
const orgLicensePlan = await licenseService.getPlan(orgGatewayConfig.orgId);
|
||||
if (!orgLicensePlan.gateway) {
|
||||
throw new BadRequestError({
|
||||
message: "Please upgrade your instance to Infisical's Enterprise plan to use gateways."
|
||||
});
|
||||
}
|
||||
|
||||
const { decryptor: orgKmsDecryptor } = await kmsService.createCipherPairWithDataKey({
|
||||
type: KmsDataKey.Organization,
|
||||
@@ -274,6 +286,12 @@ export const gatewayV2ServiceFactory = ({
|
||||
})
|
||||
);
|
||||
|
||||
const gatewayServerCaCert = new x509.X509Certificate(
|
||||
orgKmsDecryptor({
|
||||
cipherTextBlob: orgGatewayConfig.encryptedGatewayServerCaCertificate
|
||||
})
|
||||
);
|
||||
|
||||
const gatewayClientCaPrivateKey = orgKmsDecryptor({
|
||||
cipherTextBlob: orgGatewayConfig.encryptedGatewayClientCaPrivateKey
|
||||
});
|
||||
@@ -297,6 +315,23 @@ export const gatewayV2ServiceFactory = ({
|
||||
const clientKeys = await crypto.nativeCrypto.subtle.generateKey(alg, true, ["sign", "verify"]);
|
||||
const clientCertSerialNumber = createSerialNumber();
|
||||
|
||||
const routingInfo = {
|
||||
targetHost,
|
||||
targetPort
|
||||
};
|
||||
|
||||
const routingExtension = new x509.Extension(
|
||||
GATEWAY_ROUTING_INFO_OID,
|
||||
false,
|
||||
Buffer.from(JSON.stringify(routingInfo))
|
||||
);
|
||||
|
||||
const actorExtension = new x509.Extension(
|
||||
GATEWAY_ACTOR_OID,
|
||||
false,
|
||||
Buffer.from(JSON.stringify({ type: ActorType.PLATFORM }))
|
||||
);
|
||||
|
||||
const clientCert = await x509.X509CertificateGenerator.create({
|
||||
serialNumber: clientCertSerialNumber,
|
||||
subject: `O=${orgGatewayConfig.orgId},OU=gateway-client,CN=${ActorType.PLATFORM}:${gatewayId}`,
|
||||
@@ -318,16 +353,18 @@ export const gatewayV2ServiceFactory = ({
|
||||
x509.KeyUsageFlags[CertKeyUsage.KEY_AGREEMENT],
|
||||
true
|
||||
),
|
||||
new x509.ExtendedKeyUsageExtension([x509.ExtendedKeyUsage[CertExtendedKeyUsage.CLIENT_AUTH]], true)
|
||||
new x509.ExtendedKeyUsageExtension([x509.ExtendedKeyUsage[CertExtendedKeyUsage.CLIENT_AUTH]], true),
|
||||
routingExtension,
|
||||
actorExtension
|
||||
]
|
||||
});
|
||||
|
||||
const gatewayClientCertPrivateKey = crypto.nativeCrypto.KeyObject.from(clientKeys.privateKey);
|
||||
|
||||
const proxyCredentials = await proxyService.getCredentialsForClient({
|
||||
proxyId: gateway.proxyId,
|
||||
orgId: gateway.orgId,
|
||||
gatewayId,
|
||||
actor: ActorType.PLATFORM
|
||||
gatewayId
|
||||
});
|
||||
|
||||
return {
|
||||
@@ -335,8 +372,7 @@ export const gatewayV2ServiceFactory = ({
|
||||
gateway: {
|
||||
clientCertificate: clientCert.toString("pem"),
|
||||
clientPrivateKey: gatewayClientCertPrivateKey.export({ format: "pem", type: "pkcs8" }).toString(),
|
||||
clientCertificateChain: constructPemChainFromCerts([gatewayClientCaCert, rootGatewayCaCert]),
|
||||
serverCA: rootGatewayCaCert.toString("pem")
|
||||
serverCertificateChain: constructPemChainFromCerts([gatewayServerCaCert, rootGatewayCaCert])
|
||||
},
|
||||
proxy: {
|
||||
clientCertificate: proxyCredentials.clientCertificate,
|
||||
@@ -385,6 +421,7 @@ export const gatewayV2ServiceFactory = ({
|
||||
const alg = keyAlgorithmToAlgCfg(CertKeyAlgorithm.RSA_2048);
|
||||
const gatewayServerCaCert = new x509.X509Certificate(orgCAs.gatewayServerCaCertificate);
|
||||
const rootGatewayCaCert = new x509.X509Certificate(orgCAs.rootGatewayCaCertificate);
|
||||
const gatewayClientCaCert = new x509.X509Certificate(orgCAs.gatewayClientCaCertificate);
|
||||
|
||||
const gatewayServerCaSkObj = crypto.nativeCrypto.createPrivateKey({
|
||||
key: orgCAs.gatewayServerCaPrivateKey,
|
||||
@@ -414,7 +451,12 @@ export const gatewayV2ServiceFactory = ({
|
||||
x509.KeyUsageFlags[CertKeyUsage.DIGITAL_SIGNATURE] | x509.KeyUsageFlags[CertKeyUsage.KEY_ENCIPHERMENT],
|
||||
true
|
||||
),
|
||||
new x509.ExtendedKeyUsageExtension([x509.ExtendedKeyUsage[CertExtendedKeyUsage.SERVER_AUTH]], true)
|
||||
new x509.ExtendedKeyUsageExtension([x509.ExtendedKeyUsage[CertExtendedKeyUsage.SERVER_AUTH]], true),
|
||||
new x509.SubjectAlternativeNameExtension([
|
||||
{ type: "dns", value: "localhost" },
|
||||
{ type: "ip", value: "127.0.0.1" },
|
||||
{ type: "ip", value: "::1" }
|
||||
])
|
||||
];
|
||||
|
||||
const gatewayServerSerialNumber = createSerialNumber();
|
||||
@@ -441,9 +483,8 @@ export const gatewayV2ServiceFactory = ({
|
||||
proxyIp: proxyCredentials.proxyIp,
|
||||
pki: {
|
||||
serverCertificate: gatewayServerCertificate.toString("pem"),
|
||||
serverCertificateChain: constructPemChainFromCerts([gatewayServerCaCert, rootGatewayCaCert]),
|
||||
serverPrivateKey: gatewayServerCertPrivateKey.export({ format: "pem", type: "pkcs8" }).toString(),
|
||||
clientCA: rootGatewayCaCert.toString("pem")
|
||||
clientCertificateChain: constructPemChainFromCerts([gatewayClientCaCert, rootGatewayCaCert])
|
||||
},
|
||||
ssh: {
|
||||
clientCertificate: proxyCredentials.clientSshCert,
|
||||
|
||||
@@ -4,7 +4,6 @@ import { TProxies } from "@app/db/schemas";
|
||||
import { PgSqlLock } from "@app/keystore/keystore";
|
||||
import { crypto } from "@app/lib/crypto";
|
||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
||||
import { ActorType } from "@app/services/auth/auth-type";
|
||||
import { constructPemChainFromCerts, prependCertToPemChain } from "@app/services/certificate/certificate-fns";
|
||||
import { CertExtendedKeyUsage, CertKeyAlgorithm, CertKeyUsage } from "@app/services/certificate/certificate-types";
|
||||
import {
|
||||
@@ -689,7 +688,6 @@ export const proxyServiceFactory = ({
|
||||
};
|
||||
|
||||
const $generateProxyClientCredentials = async ({
|
||||
actor,
|
||||
gatewayId,
|
||||
orgId,
|
||||
proxyPkiClientCaCertificate,
|
||||
@@ -697,7 +695,6 @@ export const proxyServiceFactory = ({
|
||||
proxyPkiServerCaCertificate,
|
||||
proxyPkiServerCaCertificateChain
|
||||
}: {
|
||||
actor: ActorType;
|
||||
gatewayId: string;
|
||||
orgId: string;
|
||||
proxyPkiClientCaCertificate: Buffer;
|
||||
@@ -728,29 +725,32 @@ export const proxyServiceFactory = ({
|
||||
const clientCertPrivateKey = crypto.nativeCrypto.KeyObject.from(clientKeys.privateKey);
|
||||
const clientCertSerialNumber = createSerialNumber();
|
||||
|
||||
// Build standard extensions
|
||||
const extensions: x509.Extension[] = [
|
||||
new x509.BasicConstraintsExtension(false),
|
||||
await x509.AuthorityKeyIdentifierExtension.create(proxyClientCaCert, false),
|
||||
await x509.SubjectKeyIdentifierExtension.create(clientKeys.publicKey),
|
||||
new x509.CertificatePolicyExtension(["2.5.29.32.0"]), // anyPolicy
|
||||
new x509.KeyUsagesExtension(
|
||||
// eslint-disable-next-line no-bitwise
|
||||
x509.KeyUsageFlags[CertKeyUsage.DIGITAL_SIGNATURE] |
|
||||
x509.KeyUsageFlags[CertKeyUsage.KEY_ENCIPHERMENT] |
|
||||
x509.KeyUsageFlags[CertKeyUsage.KEY_AGREEMENT],
|
||||
true
|
||||
),
|
||||
new x509.ExtendedKeyUsageExtension([x509.ExtendedKeyUsage[CertExtendedKeyUsage.CLIENT_AUTH]], true)
|
||||
];
|
||||
|
||||
const clientCert = await x509.X509CertificateGenerator.create({
|
||||
serialNumber: clientCertSerialNumber,
|
||||
subject: `O=${orgId},OU=proxy-client,CN=${actor}:${gatewayId}`,
|
||||
subject: `O=${orgId},OU=proxy-client,CN=${gatewayId}`,
|
||||
issuer: proxyClientCaCert.subject,
|
||||
notAfter: clientCertExpiration,
|
||||
notBefore: clientCertIssuedAt,
|
||||
signingKey: importedProxyClientCaPrivateKey,
|
||||
publicKey: clientKeys.publicKey,
|
||||
signingAlgorithm: alg,
|
||||
extensions: [
|
||||
new x509.BasicConstraintsExtension(false),
|
||||
await x509.AuthorityKeyIdentifierExtension.create(proxyClientCaCert, false),
|
||||
await x509.SubjectKeyIdentifierExtension.create(clientKeys.publicKey),
|
||||
new x509.CertificatePolicyExtension(["2.5.29.32.0"]), // anyPolicy
|
||||
new x509.KeyUsagesExtension(
|
||||
// eslint-disable-next-line no-bitwise
|
||||
x509.KeyUsageFlags[CertKeyUsage.DIGITAL_SIGNATURE] |
|
||||
x509.KeyUsageFlags[CertKeyUsage.KEY_ENCIPHERMENT] |
|
||||
x509.KeyUsageFlags[CertKeyUsage.KEY_AGREEMENT],
|
||||
true
|
||||
),
|
||||
new x509.ExtendedKeyUsageExtension([x509.ExtendedKeyUsage[CertExtendedKeyUsage.CLIENT_AUTH]], true)
|
||||
]
|
||||
extensions
|
||||
});
|
||||
|
||||
return {
|
||||
@@ -834,13 +834,11 @@ export const proxyServiceFactory = ({
|
||||
const getCredentialsForClient = async ({
|
||||
proxyId,
|
||||
orgId,
|
||||
gatewayId,
|
||||
actor
|
||||
gatewayId
|
||||
}: {
|
||||
proxyId: string;
|
||||
orgId: string;
|
||||
gatewayId: string;
|
||||
actor: ActorType;
|
||||
}) => {
|
||||
const proxy = await proxyDAL.findOne({
|
||||
id: proxyId
|
||||
@@ -855,7 +853,6 @@ export const proxyServiceFactory = ({
|
||||
if (isInstanceProxy(proxy.name)) {
|
||||
const instanceCAs = await $getInstanceCAs();
|
||||
const proxyCertificateCredentials = await $generateProxyClientCredentials({
|
||||
actor,
|
||||
gatewayId,
|
||||
orgId,
|
||||
proxyPkiClientCaCertificate: instanceCAs.instanceProxyPkiClientCaCertificate,
|
||||
@@ -872,7 +869,6 @@ export const proxyServiceFactory = ({
|
||||
|
||||
const orgCAs = await $getOrgCAs(orgId);
|
||||
const proxyCertificateCredentials = await $generateProxyClientCredentials({
|
||||
actor,
|
||||
gatewayId,
|
||||
orgId,
|
||||
proxyPkiClientCaCertificate: orgCAs.proxyPkiClientCaCertificate,
|
||||
|
||||
@@ -82,6 +82,7 @@ import {
|
||||
import { TSecretVersionV2DALFactory } from "@app/services/secret-v2-bridge/secret-version-dal";
|
||||
import { TSecretVersionV2TagDALFactory } from "@app/services/secret-v2-bridge/secret-version-tag-dal";
|
||||
|
||||
import { TGatewayV2ServiceFactory } from "../gateway-v2/gateway-v2-service";
|
||||
import { awsIamUserSecretRotationFactory } from "./aws-iam-user-secret/aws-iam-user-secret-rotation-fns";
|
||||
import { oktaClientSecretRotationFactory } from "./okta-client-secret/okta-client-secret-rotation-fns";
|
||||
import { TSecretRotationV2DALFactory } from "./secret-rotation-v2-dal";
|
||||
@@ -110,6 +111,7 @@ export type TSecretRotationV2ServiceFactoryDep = {
|
||||
appConnectionDAL: Pick<TAppConnectionDALFactory, "findById" | "update" | "updateById">;
|
||||
folderCommitService: Pick<TFolderCommitServiceFactory, "createCommit">;
|
||||
gatewayService: Pick<TGatewayServiceFactory, "fnGetGatewayClientTlsByGatewayId">;
|
||||
gatewayV2Service: Pick<TGatewayV2ServiceFactory, "getPlatformConnectionDetailsByGatewayId">;
|
||||
};
|
||||
|
||||
export type TSecretRotationV2ServiceFactory = ReturnType<typeof secretRotationV2ServiceFactory>;
|
||||
@@ -153,7 +155,8 @@ export const secretRotationV2ServiceFactory = ({
|
||||
queueService,
|
||||
folderCommitService,
|
||||
appConnectionDAL,
|
||||
gatewayService
|
||||
gatewayService,
|
||||
gatewayV2Service
|
||||
}: TSecretRotationV2ServiceFactoryDep) => {
|
||||
const $queueSendSecretRotationStatusNotification = async (secretRotation: TSecretRotationV2Raw) => {
|
||||
const appCfg = getConfig();
|
||||
@@ -467,7 +470,8 @@ export const secretRotationV2ServiceFactory = ({
|
||||
} as TSecretRotationV2WithConnection,
|
||||
appConnectionDAL,
|
||||
kmsService,
|
||||
gatewayService
|
||||
gatewayService,
|
||||
gatewayV2Service
|
||||
);
|
||||
|
||||
// even though we have a db constraint we want to check before any rotation of credentials is attempted
|
||||
@@ -831,7 +835,8 @@ export const secretRotationV2ServiceFactory = ({
|
||||
} as TSecretRotationV2WithConnection,
|
||||
appConnectionDAL,
|
||||
kmsService,
|
||||
gatewayService
|
||||
gatewayService,
|
||||
gatewayV2Service
|
||||
);
|
||||
|
||||
const generatedCredentials = await decryptSecretRotationCredentials({
|
||||
@@ -915,7 +920,8 @@ export const secretRotationV2ServiceFactory = ({
|
||||
} as TSecretRotationV2WithConnection,
|
||||
appConnectionDAL,
|
||||
kmsService,
|
||||
gatewayService
|
||||
gatewayService,
|
||||
gatewayV2Service
|
||||
);
|
||||
|
||||
const updatedRotation = await rotationFactory.rotateCredentials(
|
||||
|
||||
@@ -6,6 +6,7 @@ import { TAppConnectionDALFactory } from "@app/services/app-connection/app-conne
|
||||
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
||||
import { SecretsOrderBy } from "@app/services/secret/secret-types";
|
||||
|
||||
import { TGatewayV2ServiceFactory } from "../gateway-v2/gateway-v2-service";
|
||||
import {
|
||||
TAuth0ClientSecretRotation,
|
||||
TAuth0ClientSecretRotationGeneratedCredentials,
|
||||
@@ -253,7 +254,8 @@ export type TRotationFactory<
|
||||
secretRotation: T,
|
||||
appConnectionDAL: Pick<TAppConnectionDALFactory, "findById" | "update" | "updateById">,
|
||||
kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">,
|
||||
gatewayService: Pick<TGatewayServiceFactory, "fnGetGatewayClientTlsByGatewayId">
|
||||
gatewayService: Pick<TGatewayServiceFactory, "fnGetGatewayClientTlsByGatewayId">,
|
||||
gatewayV2Service: Pick<TGatewayV2ServiceFactory, "getPlatformConnectionDetailsByGatewayId">
|
||||
) => {
|
||||
issueCredentials: TRotationFactoryIssueCredentials<C, P>;
|
||||
revokeCredentials: TRotationFactoryRevokeCredentials<C>;
|
||||
|
||||
+2
-1
@@ -41,7 +41,7 @@ const ORACLE_PASSWORD_REQUIREMENTS = {
|
||||
export const sqlCredentialsRotationFactory: TRotationFactory<
|
||||
TSqlCredentialsRotationWithConnection,
|
||||
TSqlCredentialsRotationGeneratedCredentials
|
||||
> = (secretRotation, _appConnectionDAL, _kmsService, gatewayService) => {
|
||||
> = (secretRotation, _appConnectionDAL, _kmsService, gatewayService, gatewayV2Service) => {
|
||||
const {
|
||||
connection,
|
||||
parameters: { username1, username2 },
|
||||
@@ -67,6 +67,7 @@ export const sqlCredentialsRotationFactory: TRotationFactory<
|
||||
credentials: finalCredentials
|
||||
},
|
||||
gatewayService,
|
||||
gatewayV2Service,
|
||||
(client) => operation(client)
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user