diff --git a/backend/src/ee/services/audit-log/audit-log-types.ts b/backend/src/ee/services/audit-log/audit-log-types.ts index 0b45544e3..bcc2a0770 100644 --- a/backend/src/ee/services/audit-log/audit-log-types.ts +++ b/backend/src/ee/services/audit-log/audit-log-types.ts @@ -371,6 +371,7 @@ export enum EventType { SIGN_CERTIFICATE_FROM_PROFILE = "sign-certificate-from-profile", ORDER_CERTIFICATE_FROM_PROFILE = "order-certificate-from-profile", RENEW_CERTIFICATE = "renew-certificate", + GET_CERTIFICATE_PROFILE_LATEST_ACTIVE_BUNDLE = "get-certificate-profile-latest-active-bundle", UPDATE_CERTIFICATE_RENEWAL_CONFIG = "update-certificate-renewal-config", DISABLE_CERTIFICATE_RENEWAL_CONFIG = "disable-certificate-renewal-config", ATTEMPT_CREATE_SLACK_INTEGRATION = "attempt-create-slack-integration", @@ -2752,6 +2753,17 @@ interface OrderCertificateFromProfile { }; } +interface GetCertificateProfileLatestActiveBundle { + type: EventType.GET_CERTIFICATE_PROFILE_LATEST_ACTIVE_BUNDLE; + metadata: { + certificateProfileId: string; + certificateId: string; + commonName: string; + profileName: string; + serialNumber: string; + }; +} + interface RenewCertificate { type: EventType.RENEW_CERTIFICATE; metadata: { @@ -4282,6 +4294,7 @@ export type Event = | DeleteCertificateProfile | GetCertificateProfile | ListCertificateProfiles + | GetCertificateProfileLatestActiveBundle | IssueCertificateFromProfile | SignCertificateFromProfile | OrderCertificateFromProfile diff --git a/backend/src/server/routes/index.ts b/backend/src/server/routes/index.ts index b94e97993..a0309eb3e 100644 --- a/backend/src/server/routes/index.ts +++ b/backend/src/server/routes/index.ts @@ -1178,6 +1178,10 @@ export const registerRoutes = async ( apiEnrollmentConfigDAL, estEnrollmentConfigDAL, acmeEnrollmentConfigDAL, + certificateBodyDAL, + certificateSecretDAL, + certificateAuthorityDAL, + certificateAuthorityCertDAL, permissionService, kmsService, projectDAL diff --git a/backend/src/server/routes/v1/certificate-profiles-router.ts b/backend/src/server/routes/v1/certificate-profiles-router.ts index 2173184fd..5792c5e83 100644 --- a/backend/src/server/routes/v1/certificate-profiles-router.ts +++ b/backend/src/server/routes/v1/certificate-profiles-router.ts @@ -498,6 +498,71 @@ export const registerCertificateProfilesRouter = async (server: FastifyZodProvid } }); + server.route({ + method: "GET", + url: "/:id/certificates/latest-active-bundle", + config: { + rateLimit: readLimit + }, + schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificateProfiles], + description: "Get latest active certificate bundle for a profile", + params: z.object({ + id: z.string().uuid() + }), + response: { + 200: z.object({ + certificate: z.string().nullable(), + certificateChain: z.string().nullable(), + privateKey: z.string().nullable(), + serialNumber: z.string().nullable() + }) + } + }, + onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), + handler: async (req) => { + const response = await server.services.certificateProfile.getLatestActiveCertificateBundle({ + actor: req.permission.type, + actorId: req.permission.id, + actorAuthMethod: req.permission.authMethod, + actorOrgId: req.permission.orgId, + profileId: req.params.id + }); + + if (!response) { + return { + certificate: null, + certificateChain: null, + privateKey: null, + serialNumber: null + }; + } + + await server.services.auditLog.createAuditLog({ + ...req.auditLogInfo, + projectId: response.certObj.projectId, + event: { + type: EventType.GET_CERTIFICATE_PROFILE_LATEST_ACTIVE_BUNDLE, + metadata: { + certificateProfileId: response.profile.id, + certificateId: response.certObj.id, + commonName: response.certObj.commonName, + profileName: response.profile.slug, + serialNumber: response.certObj.serialNumber + } + } + }); + + return { + certificate: response.certificate, + certificateChain: response.certificateChain, + privateKey: response.privateKey, + serialNumber: response.certObj.serialNumber + }; + } + }); + server.route({ method: "GET", url: "/:id/acme/eab-secret/reveal", diff --git a/backend/src/server/routes/v3/index.ts b/backend/src/server/routes/v3/index.ts index 47c3c2cb8..4ee4566c1 100644 --- a/backend/src/server/routes/v3/index.ts +++ b/backend/src/server/routes/v3/index.ts @@ -11,5 +11,5 @@ export const registerV3Routes = async (server: FastifyZodProvider) => { await server.register(registerUserRouter, { prefix: "/users" }); await server.register(registerDeprecatedSecretRouter, { prefix: "/secrets" }); await server.register(registerExternalMigrationRouter, { prefix: "/external-migration" }); - await server.register(registerCertificatesRouter, { prefix: "/certificates" }); + await server.register(registerCertificatesRouter, { prefix: "/pki/certificates" }); }; diff --git a/backend/src/services/certificate-profile/certificate-profile-dal.ts b/backend/src/services/certificate-profile/certificate-profile-dal.ts index 5296cb172..6415145ce 100644 --- a/backend/src/services/certificate-profile/certificate-profile-dal.ts +++ b/backend/src/services/certificate-profile/certificate-profile-dal.ts @@ -462,6 +462,24 @@ export const certificateProfileDALFactory = (db: TDbClient) => { } }; + const getLatestActiveCertificateForProfile = async (profileId: string, tx?: Knex) => { + try { + const now = new Date(); + + const certificate = await (tx || db)(TableName.Certificate) + .where("profileId", profileId) + .where("status", "active") + .where("notAfter", ">", now) + .whereNull("revokedAt") + .orderBy("createdAt", "desc") + .first(); + + return certificate; + } catch (error) { + throw new DatabaseError({ error, name: "Get latest active certificate by profile" }); + } + }; + const isProfileInUse = async (profileId: string, tx?: Knex) => { try { const doc = await (tx || db)(TableName.Certificate).where("profileId", profileId).count("*").first(); @@ -485,6 +503,7 @@ export const certificateProfileDALFactory = (db: TDbClient) => { countByProjectId, findByNameAndProjectId, getCertificatesByProfile, + getLatestActiveCertificateForProfile, isProfileInUse }; }; diff --git a/backend/src/services/certificate-profile/certificate-profile-service.test.ts b/backend/src/services/certificate-profile/certificate-profile-service.test.ts index ffca3c1cb..9d9ab5947 100644 --- a/backend/src/services/certificate-profile/certificate-profile-service.test.ts +++ b/backend/src/services/certificate-profile/certificate-profile-service.test.ts @@ -9,6 +9,10 @@ import type { TPermissionServiceFactory } from "@app/ee/services/permission/perm import { ForbiddenRequestError, NotFoundError } from "@app/lib/errors"; import { ActorType, AuthMethod } from "../auth/auth-type"; +import type { TCertificateBodyDALFactory } from "../certificate/certificate-body-dal"; +import type { TCertificateSecretDALFactory } from "../certificate/certificate-secret-dal"; +import type { TCertificateAuthorityCertDALFactory } from "../certificate-authority/certificate-authority-cert-dal"; +import type { TCertificateAuthorityDALFactory } from "../certificate-authority/certificate-authority-dal"; import type { TCertificateTemplateV2DALFactory } from "../certificate-template-v2/certificate-template-v2-dal"; import { TAcmeEnrollmentConfigDALFactory } from "../enrollment-config/acme-enrollment-config-dal"; import type { TApiEnrollmentConfigDALFactory } from "../enrollment-config/api-enrollment-config-dal"; @@ -178,6 +182,54 @@ describe("CertificateProfileService", () => { transaction: vi.fn() } as unknown as Pick; + const mockCertificateBodyDAL = { + create: vi.fn(), + findById: vi.fn(), + updateById: vi.fn(), + deleteById: vi.fn(), + transaction: vi.fn(), + find: vi.fn(), + findOne: vi.fn(), + update: vi.fn(), + delete: vi.fn() + } as unknown as TCertificateBodyDALFactory; + + const mockCertificateSecretDAL = { + create: vi.fn(), + findById: vi.fn(), + updateById: vi.fn(), + deleteById: vi.fn(), + transaction: vi.fn(), + find: vi.fn(), + findOne: vi.fn(), + update: vi.fn(), + delete: vi.fn() + } as unknown as TCertificateSecretDALFactory; + + const mockCertificateAuthorityDAL = { + create: vi.fn(), + findById: vi.fn(), + updateById: vi.fn(), + deleteById: vi.fn(), + transaction: vi.fn(), + find: vi.fn(), + findOne: vi.fn(), + update: vi.fn(), + delete: vi.fn() + } as unknown as TCertificateAuthorityDALFactory; + + const mockCertificateAuthorityCertDAL = { + create: vi.fn(), + findById: vi.fn(), + updateById: vi.fn(), + deleteById: vi.fn(), + transaction: vi.fn(), + find: vi.fn(), + findOne: vi.fn(), + update: vi.fn(), + delete: vi.fn() + } as unknown as TCertificateAuthorityCertDALFactory; + beforeEach(() => { vi.spyOn(ForbiddenError, "from").mockReturnValue({ throwUnlessCan: vi.fn() @@ -195,6 +247,10 @@ describe("CertificateProfileService", () => { apiEnrollmentConfigDAL: mockApiEnrollmentConfigDAL, estEnrollmentConfigDAL: mockEstEnrollmentConfigDAL, acmeEnrollmentConfigDAL: mockAcmeEnrollmentConfigDAL, + certificateBodyDAL: mockCertificateBodyDAL, + certificateSecretDAL: mockCertificateSecretDAL, + certificateAuthorityDAL: mockCertificateAuthorityDAL, + certificateAuthorityCertDAL: mockCertificateAuthorityCertDAL, permissionService: mockPermissionService, kmsService: mockKmsService, projectDAL: mockProjectDAL diff --git a/backend/src/services/certificate-profile/certificate-profile-service.ts b/backend/src/services/certificate-profile/certificate-profile-service.ts index 47d7f2b60..cb7f50cc3 100644 --- a/backend/src/services/certificate-profile/certificate-profile-service.ts +++ b/backend/src/services/certificate-profile/certificate-profile-service.ts @@ -4,6 +4,7 @@ import * as x509 from "@peculiar/x509"; import { ActionProjectType } from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { + ProjectPermissionCertificateActions, ProjectPermissionCertificateProfileActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; @@ -15,6 +16,11 @@ import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/ import { ActorAuthMethod, ActorType } from "../auth/auth-type"; import { isCertChainValid } from "../certificate/certificate-fns"; +import { TCertificateBodyDALFactory } from "../certificate/certificate-body-dal"; +import { getCertificateCredentials, isCertChainValid } from "../certificate/certificate-fns"; +import { TCertificateSecretDALFactory } from "../certificate/certificate-secret-dal"; +import { TCertificateAuthorityCertDALFactory } from "../certificate-authority/certificate-authority-cert-dal"; +import { TCertificateAuthorityDALFactory } from "../certificate-authority/certificate-authority-dal"; import { TCertificateTemplateV2DALFactory } from "../certificate-template-v2/certificate-template-v2-dal"; import { TAcmeEnrollmentConfigDALFactory } from "../enrollment-config/acme-enrollment-config-dal"; import { TApiEnrollmentConfigDALFactory } from "../enrollment-config/api-enrollment-config-dal"; @@ -142,6 +148,10 @@ type TCertificateProfileServiceFactoryDep = { apiEnrollmentConfigDAL: TApiEnrollmentConfigDALFactory; estEnrollmentConfigDAL: TEstEnrollmentConfigDALFactory; acmeEnrollmentConfigDAL: TAcmeEnrollmentConfigDALFactory; + certificateBodyDAL: Pick; + certificateSecretDAL: Pick; + certificateAuthorityDAL: Pick; + certificateAuthorityCertDAL: Pick; permissionService: Pick; kmsService: Pick; projectDAL: Pick; @@ -162,6 +172,8 @@ export const certificateProfileServiceFactory = ({ apiEnrollmentConfigDAL, estEnrollmentConfigDAL, acmeEnrollmentConfigDAL, + certificateBodyDAL, + certificateSecretDAL, permissionService, kmsService, projectDAL @@ -729,6 +741,106 @@ export const certificateProfileServiceFactory = ({ return certificates; }; + const getLatestActiveCertificateBundle = async ({ + actor, + actorId, + actorAuthMethod, + actorOrgId, + profileId + }: { + actor: ActorType; + actorId: string; + actorAuthMethod: ActorAuthMethod; + actorOrgId: string; + profileId: string; + }) => { + const profile = await certificateProfileDAL.findById(profileId); + if (!profile) { + throw new NotFoundError({ message: "Certificate profile not found" }); + } + + const { permission } = await permissionService.getProjectPermission({ + actor, + actorId, + projectId: profile.projectId, + actorAuthMethod, + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager + }); + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionCertificateProfileActions.Read, + ProjectPermissionSub.CertificateProfiles + ); + + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionCertificateActions.Read, + ProjectPermissionSub.Certificates + ); + + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionCertificateActions.ReadPrivateKey, + ProjectPermissionSub.Certificates + ); + + const cert = await certificateProfileDAL.getLatestActiveCertificateForProfile(profileId); + + if (!cert) { + return null; + } + + const certBody = await certificateBodyDAL.findOne({ certId: cert.id }); + + const certificateManagerKeyId = await getProjectKmsCertificateKeyId({ + projectId: cert.projectId, + projectDAL, + kmsService + }); + + const kmsDecryptor = await kmsService.decryptWithKmsKey({ + kmsId: certificateManagerKeyId + }); + const decryptedCert = await kmsDecryptor({ + cipherTextBlob: certBody.encryptedCertificate + }); + + const certObj = new x509.X509Certificate(decryptedCert); + const certificate = certObj.toString("pem"); + + const decryptedCertChain = await kmsDecryptor({ + cipherTextBlob: certBody.encryptedCertificateChain! + }); + + const certificateChain = decryptedCertChain.toString(); + + let privateKey = null; + try { + const { certPrivateKey } = await getCertificateCredentials({ + certId: cert.id, + projectId: cert.projectId, + certificateSecretDAL, + projectDAL, + kmsService + }); + privateKey = certPrivateKey; + } catch (error) { + // Private key might not exist for ACME certificates or other external workflows + // where the key is generated client-side + if (error instanceof NotFoundError) { + privateKey = null; + } else { + throw error; + } + } + + return { + certificate, + certificateChain, + privateKey, + profile, + certObj: cert + }; + }; + const getEstConfigurationByProfile = async ( params: | { @@ -854,6 +966,7 @@ export const certificateProfileServiceFactory = ({ listProfiles, deleteProfile, getProfileCertificates, + getLatestActiveCertificateBundle, getEstConfigurationByProfile, revealAcmeEabSecret }; diff --git a/backend/src/services/certificate-v3/certificate-v3-service.ts b/backend/src/services/certificate-v3/certificate-v3-service.ts index ff52a0786..bce5350c3 100644 --- a/backend/src/services/certificate-v3/certificate-v3-service.ts +++ b/backend/src/services/certificate-v3/certificate-v3-service.ts @@ -675,7 +675,7 @@ export const certificateV3ServiceFactory = ({ status: CertificateOrderStatus.VALID })), authorizations: [], - finalize: `/api/v3/certificates/orders/${orderId}/completed`, + finalize: `/api/v3/pki/certificates/orders/${orderId}/completed`, certificate: certificateResult.certificate, projectId: certificateResult.projectId, profileName: certificateResult.profileName diff --git a/docs/api-reference/endpoints/certificate-authorities/issue-cert.mdx b/docs/api-reference/endpoints/certificate-authorities/issue-cert.mdx deleted file mode 100644 index 045cada58..000000000 --- a/docs/api-reference/endpoints/certificate-authorities/issue-cert.mdx +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: "Issue certificate" -openapi: "POST /api/v1/pki/ca/{caId}/issue-certificate" ---- diff --git a/docs/api-reference/endpoints/certificate-authorities/sign-cert.mdx b/docs/api-reference/endpoints/certificate-authorities/sign-cert.mdx deleted file mode 100644 index 95c8d8c65..000000000 --- a/docs/api-reference/endpoints/certificate-authorities/sign-cert.mdx +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: "Sign certificate" -openapi: "POST /api/v1/pki/ca/{caId}/sign-certificate" ---- diff --git a/docs/api-reference/endpoints/certificate-profiles/get-latest-active-bundle.mdx b/docs/api-reference/endpoints/certificate-profiles/get-latest-active-bundle.mdx new file mode 100644 index 000000000..aa033418d --- /dev/null +++ b/docs/api-reference/endpoints/certificate-profiles/get-latest-active-bundle.mdx @@ -0,0 +1,4 @@ +--- +title: "Get Latest Active Certificate Bundle" +openapi: "GET /api/v1/pki/certificate-profiles/{id}/certificates/latest-active-bundle" +--- \ No newline at end of file diff --git a/docs/api-reference/endpoints/certificates/issue-certificate.mdx b/docs/api-reference/endpoints/certificates/issue-certificate.mdx index 90a79a4af..13a464b67 100644 --- a/docs/api-reference/endpoints/certificates/issue-certificate.mdx +++ b/docs/api-reference/endpoints/certificates/issue-certificate.mdx @@ -1,4 +1,4 @@ --- title: "Issue Certificate" -openapi: "POST /api/v1/pki/certificates/issue-certificate" +openapi: "POST /api/v3/pki/certificates/issue-certificate" --- diff --git a/docs/api-reference/endpoints/certificates/renew.mdx b/docs/api-reference/endpoints/certificates/renew.mdx index 3c8e03498..b44424369 100644 --- a/docs/api-reference/endpoints/certificates/renew.mdx +++ b/docs/api-reference/endpoints/certificates/renew.mdx @@ -1,4 +1,4 @@ --- title: "Renew Certificate" -openapi: "POST /api/v3/certificates/{certificateId}/renew" +openapi: "POST /api/v3/pki/certificates/{certificateId}/renew" --- \ No newline at end of file diff --git a/docs/api-reference/endpoints/certificates/sign-certificate.mdx b/docs/api-reference/endpoints/certificates/sign-certificate.mdx index 3132d5846..7291025fc 100644 --- a/docs/api-reference/endpoints/certificates/sign-certificate.mdx +++ b/docs/api-reference/endpoints/certificates/sign-certificate.mdx @@ -1,4 +1,4 @@ --- title: "Sign Certificate" -openapi: "POST /api/v1/pki/certificates/sign-certificate" +openapi: "POST /api/v3/pki/certificates/sign-certificate" --- diff --git a/docs/api-reference/endpoints/certificates/update-config.mdx b/docs/api-reference/endpoints/certificates/update-config.mdx index 1d92a0407..70520bf68 100644 --- a/docs/api-reference/endpoints/certificates/update-config.mdx +++ b/docs/api-reference/endpoints/certificates/update-config.mdx @@ -1,4 +1,4 @@ --- title: "Update Certificate Config" -openapi: "PATCH /api/v3/certificates/{certificateId}/config" +openapi: "PATCH /api/v3/pki/certificates/{certificateId}/config" --- \ No newline at end of file diff --git a/docs/docs.json b/docs/docs.json index dc96c9976..8cce3197d 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -2585,8 +2585,6 @@ "api-reference/endpoints/certificate-authorities/cert", "api-reference/endpoints/certificate-authorities/sign-intermediate", "api-reference/endpoints/certificate-authorities/import-cert", - "api-reference/endpoints/certificate-authorities/issue-cert", - "api-reference/endpoints/certificate-authorities/sign-cert", "api-reference/endpoints/certificate-authorities/crl" ] }, @@ -2646,7 +2644,8 @@ "api-reference/endpoints/certificate-profiles/get-by-id", "api-reference/endpoints/certificate-profiles/get-by-slug", "api-reference/endpoints/certificate-profiles/delete", - "api-reference/endpoints/certificate-profiles/list-certificates" + "api-reference/endpoints/certificate-profiles/list-certificates", + "api-reference/endpoints/certificate-profiles/get-latest-active-bundle" ] }, { diff --git a/docs/documentation/platform/pki/certificates/certificates.mdx b/docs/documentation/platform/pki/certificates/certificates.mdx index bc3698e6c..b30a53091 100644 --- a/docs/documentation/platform/pki/certificates/certificates.mdx +++ b/docs/documentation/platform/pki/certificates/certificates.mdx @@ -48,6 +48,12 @@ The resulting renewed certificate is stored in the platform and made available t Note that server-driven certificate renewal is only available for certificates issued via the [API enrollment method](/documentation/platform/pki/enrollment-methods/api) where key pairs are generated server-side. A certificate can be considered for auto-renewal at time of issuance if the **Enable Auto-Renewal By Default** option is selected on its [certificate profile](/documentation/platform/pki/certificates/profiles) or after issuance by toggling this option manually. + + For server-driven certificate renewal workflows, you can programmatically fetch the latest active certificate bundle for a certificate profile using the [Get Latest Active Certificate Bundle](/api-reference/endpoints/certificate-profiles/get-latest-active-bundle) API endpoint. + + This ensures you always retrieve the most current valid certificate, including any that have been automatically renewed, making it particularly useful for deployment pipelines and automation workflows where you don't want to track individual serial numbers. + + The following examples demonstrate different approaches to certificate renewal: - Using the ACME enrollment method, you may connect an ACME client like [certbot](https://certbot.eff.org/) to fetch back and renew certificates for Apache, Nginx, or other server. The ACME client will pursue a client-driven approach and submit certificate requests upon certificate expiration for you, saving renewed certificates back to the server's configuration. diff --git a/docs/documentation/platform/pki/enrollment-methods/api.mdx b/docs/documentation/platform/pki/enrollment-methods/api.mdx index cd657d7d4..dac7b6386 100644 --- a/docs/documentation/platform/pki/enrollment-methods/api.mdx +++ b/docs/documentation/platform/pki/enrollment-methods/api.mdx @@ -105,7 +105,7 @@ Here, select the certificate profile from step 1 that will be used to issue the ### Sample request ```bash Request - curl --location --request POST 'https://app.infisical.com/api/v3/certificates/issue-certificate' \ + curl --location --request POST 'https://app.infisical.com/api/v3/pki/certificates/issue-certificate' \ --header 'Authorization: Bearer ' \ --header 'Content-Type: application/json' \ --data-raw '{ @@ -151,7 +151,7 @@ Here, select the certificate profile from step 1 that will be used to issue the ### Sample request ```bash Request - curl --location --request POST 'https://app.infisical.com/api/v3/certificates/sign-certificate' \ + curl --location --request POST 'https://app.infisical.com/api/v3/pki/certificates/sign-certificate' \ --header 'Authorization: Bearer ' \ --header 'Content-Type: application/json' \ --data-raw '{ diff --git a/frontend/src/hooks/api/auditLogs/constants.tsx b/frontend/src/hooks/api/auditLogs/constants.tsx index 33bc2107d..b465474e8 100644 --- a/frontend/src/hooks/api/auditLogs/constants.tsx +++ b/frontend/src/hooks/api/auditLogs/constants.tsx @@ -268,7 +268,18 @@ export const eventToNameMap: { [K in EventType]: string } = { [EventType.PAM_RESOURCE_GET]: "PAM Resource Get", [EventType.PAM_RESOURCE_CREATE]: "PAM Resource Create", [EventType.PAM_RESOURCE_UPDATE]: "PAM Resource Update", - [EventType.PAM_RESOURCE_DELETE]: "PAM Resource Delete" + [EventType.PAM_RESOURCE_DELETE]: "PAM Resource Delete", + + [EventType.CREATE_CERTIFICATE_PROFILE]: "Create Certificate Profile", + [EventType.UPDATE_CERTIFICATE_PROFILE]: "Update Certificate Profile", + [EventType.DELETE_CERTIFICATE_PROFILE]: "Delete Certificate Profile", + [EventType.GET_CERTIFICATE_PROFILE]: "Get Certificate Profile", + [EventType.LIST_CERTIFICATE_PROFILES]: "List Certificate Profiles", + [EventType.ISSUE_CERTIFICATE_FROM_PROFILE]: "Issue Certificate From Profile", + [EventType.SIGN_CERTIFICATE_FROM_PROFILE]: "Sign Certificate From Profile", + [EventType.ORDER_CERTIFICATE_FROM_PROFILE]: "Order Certificate From Profile", + [EventType.GET_CERTIFICATE_PROFILE_LATEST_ACTIVE_BUNDLE]: + "Get Certificate Profile Latest Active Bundle" }; export const userAgentTypeToNameMap: { [K in UserAgentType]: string } = { diff --git a/frontend/src/hooks/api/auditLogs/enums.tsx b/frontend/src/hooks/api/auditLogs/enums.tsx index ea684a4bb..995d22624 100644 --- a/frontend/src/hooks/api/auditLogs/enums.tsx +++ b/frontend/src/hooks/api/auditLogs/enums.tsx @@ -260,5 +260,15 @@ export enum EventType { PAM_RESOURCE_GET = "pam-resource-get", PAM_RESOURCE_CREATE = "pam-resource-create", PAM_RESOURCE_UPDATE = "pam-resource-update", - PAM_RESOURCE_DELETE = "pam-resource-delete" + PAM_RESOURCE_DELETE = "pam-resource-delete", + + CREATE_CERTIFICATE_PROFILE = "create-certificate-profile", + UPDATE_CERTIFICATE_PROFILE = "update-certificate-profile", + DELETE_CERTIFICATE_PROFILE = "delete-certificate-profile", + GET_CERTIFICATE_PROFILE = "get-certificate-profile", + LIST_CERTIFICATE_PROFILES = "list-certificate-profiles", + ISSUE_CERTIFICATE_FROM_PROFILE = "issue-certificate-from-profile", + SIGN_CERTIFICATE_FROM_PROFILE = "sign-certificate-from-profile", + ORDER_CERTIFICATE_FROM_PROFILE = "order-certificate-from-profile", + GET_CERTIFICATE_PROFILE_LATEST_ACTIVE_BUNDLE = "get-certificate-profile-latest-active-bundle" } diff --git a/frontend/src/hooks/api/ca/mutations.tsx b/frontend/src/hooks/api/ca/mutations.tsx index 49a53dce7..e19069984 100644 --- a/frontend/src/hooks/api/ca/mutations.tsx +++ b/frontend/src/hooks/api/ca/mutations.tsx @@ -157,7 +157,7 @@ export const useCreateCertificateV3 = (options?: { projectId?: string }) => { return useMutation({ mutationFn: async (body) => { const { data } = await apiRequest.post( - "/api/v3/certificates/issue-certificate", + "/api/v3/pki/certificates/issue-certificate", body ); return data; @@ -185,7 +185,7 @@ export const useOrderCertificateWithProfile = () => { return useMutation({ mutationFn: async (body) => { const { data } = await apiRequest.post( - "/api/v3/certificates/order-certificate", + "/api/v3/pki/certificates/order-certificate", body ); return data; diff --git a/frontend/src/hooks/api/certificates/mutations.tsx b/frontend/src/hooks/api/certificates/mutations.tsx index eed1d9e5f..2ee470551 100644 --- a/frontend/src/hooks/api/certificates/mutations.tsx +++ b/frontend/src/hooks/api/certificates/mutations.tsx @@ -86,7 +86,7 @@ export const useRenewCertificate = () => { return useMutation({ mutationFn: async ({ certificateId }) => { const { data } = await apiRequest.post( - `/api/v3/certificates/${certificateId}/renew`, + `/api/v3/pki/certificates/${certificateId}/renew`, {} ); return data; @@ -119,7 +119,7 @@ export const useUpdateRenewalConfig = () => { >({ mutationFn: async ({ certificateId, renewBeforeDays, enableAutoRenewal }) => { const { data } = await apiRequest.patch<{ message: string; renewBeforeDays?: number }>( - `/api/v3/certificates/${certificateId}/config`, + `/api/v3/pki/certificates/${certificateId}/config`, { renewBeforeDays, enableAutoRenewal } ); return data;