Added Microsoft ADCS connector

This commit is contained in:
Carlos Monastyrski
2025-08-27 02:45:46 -03:00
parent 5c21ac3182
commit 4e2592960d
79 changed files with 3500 additions and 514 deletions
+1
View File
@@ -948,6 +948,7 @@ export const registerRoutes = async (
certificateAuthorityCrlDAL,
certificateAuthoritySecretDAL,
projectDAL,
appConnectionDAL,
kmsService,
permissionService,
pkiCollectionDAL,
@@ -15,6 +15,10 @@ import {
} from "@app/services/app-connection/1password";
import { Auth0ConnectionListItemSchema, SanitizedAuth0ConnectionSchema } from "@app/services/app-connection/auth0";
import { AwsConnectionListItemSchema, SanitizedAwsConnectionSchema } from "@app/services/app-connection/aws";
import {
AzureADCSConnectionListItemSchema,
SanitizedAzureADCSConnectionSchema
} from "@app/services/app-connection/azure-adcs/azure-adcs-connection-schemas";
import {
AzureAppConfigurationConnectionListItemSchema,
SanitizedAzureAppConfigurationConnectionSchema
@@ -150,7 +154,8 @@ const SanitizedAppConnectionSchema = z.union([
...SanitizedSupabaseConnectionSchema.options,
...SanitizedDigitalOceanConnectionSchema.options,
...SanitizedNetlifyConnectionSchema.options,
...SanitizedOktaConnectionSchema.options
...SanitizedOktaConnectionSchema.options,
...SanitizedAzureADCSConnectionSchema.options
]);
const AppConnectionOptionsSchema = z.discriminatedUnion("app", [
@@ -190,7 +195,8 @@ const AppConnectionOptionsSchema = z.discriminatedUnion("app", [
SupabaseConnectionListItemSchema,
DigitalOceanConnectionListItemSchema,
NetlifyConnectionListItemSchema,
OktaConnectionListItemSchema
OktaConnectionListItemSchema,
AzureADCSConnectionListItemSchema
]);
export const registerAppConnectionRouter = async (server: FastifyZodProvider) => {
@@ -0,0 +1,18 @@
import { AppConnection } from "@app/services/app-connection/app-connection-enums";
import {
CreateAzureADCSConnectionSchema,
SanitizedAzureADCSConnectionSchema,
UpdateAzureADCSConnectionSchema
} from "@app/services/app-connection/azure-adcs";
import { registerAppConnectionEndpoints } from "./app-connection-endpoints";
export const registerAzureADCSConnectionRouter = async (server: FastifyZodProvider) => {
registerAppConnectionEndpoints({
app: AppConnection.AzureADCS,
server,
sanitizedResponseSchema: SanitizedAzureADCSConnectionSchema,
createSchema: CreateAzureADCSConnectionSchema,
updateSchema: UpdateAzureADCSConnectionSchema
});
};
@@ -5,6 +5,7 @@ import { AppConnection } from "@app/services/app-connection/app-connection-enums
import { registerOnePassConnectionRouter } from "./1password-connection-router";
import { registerAuth0ConnectionRouter } from "./auth0-connection-router";
import { registerAwsConnectionRouter } from "./aws-connection-router";
import { registerAzureADCSConnectionRouter } from "./azure-adcs-connection-router";
import { registerAzureAppConfigurationConnectionRouter } from "./azure-app-configuration-connection-router";
import { registerAzureClientSecretsConnectionRouter } from "./azure-client-secrets-connection-router";
import { registerAzureDevOpsConnectionRouter } from "./azure-devops-connection-router";
@@ -50,6 +51,7 @@ export const APP_CONNECTION_REGISTER_ROUTER_MAP: Record<AppConnection, (server:
[AppConnection.AzureAppConfiguration]: registerAzureAppConfigurationConnectionRouter,
[AppConnection.AzureClientSecrets]: registerAzureClientSecretsConnectionRouter,
[AppConnection.AzureDevOps]: registerAzureDevOpsConnectionRouter,
[AppConnection.AzureADCS]: registerAzureADCSConnectionRouter,
[AppConnection.Databricks]: registerDatabricksConnectionRouter,
[AppConnection.Humanitec]: registerHumanitecConnectionRouter,
[AppConnection.TerraformCloud]: registerTerraformCloudConnectionRouter,
@@ -0,0 +1,65 @@
import { z } from "zod";
import { readLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type";
import {
AzureAdCsCertificateAuthoritySchema,
CreateAzureAdCsCertificateAuthoritySchema,
UpdateAzureAdCsCertificateAuthoritySchema
} from "@app/services/certificate-authority/azure-ad-cs/azure-ad-cs-certificate-authority-schemas";
import { CaType } from "@app/services/certificate-authority/certificate-authority-enums";
import { registerCertificateAuthorityEndpoints } from "./certificate-authority-endpoints";
export const registerAzureAdCsCertificateAuthorityRouter = async (server: FastifyZodProvider) => {
registerCertificateAuthorityEndpoints({
caType: CaType.AZURE_AD_CS,
server,
responseSchema: AzureAdCsCertificateAuthoritySchema,
createSchema: CreateAzureAdCsCertificateAuthoritySchema,
updateSchema: UpdateAzureAdCsCertificateAuthoritySchema
});
server.route({
method: "GET",
url: "/:caId/templates",
config: {
rateLimit: readLimit
},
schema: {
hide: false,
description: "Get available certificate templates from Azure AD CS CA",
params: z.object({
caId: z.string().describe("Azure AD CS CA ID")
}),
querystring: z.object({
projectId: z.string().describe("Project ID")
}),
response: {
200: z.object({
templates: z.array(
z.object({
id: z.string().describe("Template identifier"),
name: z.string().describe("Template display name"),
description: z.string().optional().describe("Template description")
})
)
})
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const templates = await server.services.certificateAuthority.getAzureAdcsTemplates({
caId: req.params.caId,
projectId: req.query.projectId,
actor: req.permission.type,
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId
});
return { templates };
}
});
};
@@ -1,6 +1,7 @@
import { CaType } from "@app/services/certificate-authority/certificate-authority-enums";
import { registerAcmeCertificateAuthorityRouter } from "./acme-certificate-authority-router";
import { registerAzureAdCsCertificateAuthorityRouter } from "./azure-ad-cs-certificate-authority-router";
import { registerInternalCertificateAuthorityRouter } from "./internal-certificate-authority-router";
export * from "./internal-certificate-authority-router";
@@ -8,5 +9,6 @@ export * from "./internal-certificate-authority-router";
export const CERTIFICATE_AUTHORITY_REGISTER_ROUTER_MAP: Record<CaType, (server: FastifyZodProvider) => Promise<void>> =
{
[CaType.INTERNAL]: registerInternalCertificateAuthorityRouter,
[CaType.ACME]: registerAcmeCertificateAuthorityRouter
[CaType.ACME]: registerAcmeCertificateAuthorityRouter,
[CaType.AZURE_AD_CS]: registerAzureAdCsCertificateAuthorityRouter
};
@@ -112,7 +112,19 @@ export const registerPkiSubscriberRouter = async (server: FastifyZodProvider) =>
.transform((arr) => Array.from(new Set(arr)))
.describe(PKI_SUBSCRIBERS.CREATE.extendedKeyUsages),
enableAutoRenewal: z.boolean().optional().describe(PKI_SUBSCRIBERS.CREATE.enableAutoRenewal),
autoRenewalPeriodInDays: z.number().min(1).optional().describe(PKI_SUBSCRIBERS.CREATE.autoRenewalPeriodInDays)
autoRenewalPeriodInDays: z.number().min(1).optional().describe(PKI_SUBSCRIBERS.CREATE.autoRenewalPeriodInDays),
properties: z
.object({
azureTemplateType: z.string().optional().describe("Azure ADCS Certificate Template Type"),
organization: z.string().optional().describe("Organization (O)"),
organizationalUnit: z.string().optional().describe("Organizational Unit (OU)"),
country: z.string().length(2).optional().describe("Country (C) - Two letter country code"),
state: z.string().optional().describe("State/Province (ST)"),
locality: z.string().optional().describe("Locality (L)"),
emailAddress: z.string().email().optional().describe("Email Address")
})
.optional()
.describe("Additional subscriber properties and subject fields")
}),
response: {
200: sanitizedPkiSubscriber
@@ -199,7 +211,19 @@ export const registerPkiSubscriberRouter = async (server: FastifyZodProvider) =>
.optional()
.describe(PKI_SUBSCRIBERS.UPDATE.extendedKeyUsages),
enableAutoRenewal: z.boolean().optional().describe(PKI_SUBSCRIBERS.UPDATE.enableAutoRenewal),
autoRenewalPeriodInDays: z.number().min(1).optional().describe(PKI_SUBSCRIBERS.UPDATE.autoRenewalPeriodInDays)
autoRenewalPeriodInDays: z.number().min(1).optional().describe(PKI_SUBSCRIBERS.UPDATE.autoRenewalPeriodInDays),
properties: z
.object({
azureTemplateType: z.string().optional().describe("Azure ADCS Certificate Template Type"),
organization: z.string().optional().describe("Organization (O)"),
organizationalUnit: z.string().optional().describe("Organizational Unit (OU)"),
country: z.string().length(2).optional().describe("Country (C) - Two letter country code"),
state: z.string().optional().describe("State/Province (ST)"),
locality: z.string().optional().describe("Locality (L)"),
emailAddress: z.string().email().optional().describe("Email Address")
})
.optional()
.describe("Additional subscriber properties and subject fields")
}),
response: {
200: sanitizedPkiSubscriber
@@ -6,12 +6,14 @@ import { readLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type";
import { AcmeCertificateAuthoritySchema } from "@app/services/certificate-authority/acme/acme-certificate-authority-schemas";
import { AzureAdCsCertificateAuthoritySchema } from "@app/services/certificate-authority/azure-ad-cs/azure-ad-cs-certificate-authority-schemas";
import { CaType } from "@app/services/certificate-authority/certificate-authority-enums";
import { InternalCertificateAuthoritySchema } from "@app/services/certificate-authority/internal/internal-certificate-authority-schemas";
const CertificateAuthoritySchema = z.discriminatedUnion("type", [
InternalCertificateAuthoritySchema,
AcmeCertificateAuthoritySchema
AcmeCertificateAuthoritySchema,
AzureAdCsCertificateAuthoritySchema
]);
export const registerCaRouter = async (server: FastifyZodProvider) => {
@@ -52,19 +54,31 @@ export const registerCaRouter = async (server: FastifyZodProvider) => {
req.permission
);
const azureAdCsCas = await server.services.certificateAuthority.listCertificateAuthoritiesByProjectId(
{
projectId: req.query.projectId,
type: CaType.AZURE_AD_CS
},
req.permission
);
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
projectId: req.query.projectId,
event: {
type: EventType.GET_CAS,
metadata: {
caIds: [...(internalCas ?? []).map((ca) => ca.id), ...(acmeCas ?? []).map((ca) => ca.id)]
caIds: [
...(internalCas ?? []).map((ca) => ca.id),
...(acmeCas ?? []).map((ca) => ca.id),
...(azureAdCsCas ?? []).map((ca) => ca.id)
]
}
}
});
return {
certificateAuthorities: [...(internalCas ?? []), ...(acmeCas ?? [])]
certificateAuthorities: [...(internalCas ?? []), ...(acmeCas ?? []), ...(azureAdCsCas ?? [])]
};
}
});