diff --git a/src/lib/keyvault.ts b/src/lib/keyvault.ts index 1aceaf3..c83f3a3 100644 --- a/src/lib/keyvault.ts +++ b/src/lib/keyvault.ts @@ -1,7 +1,6 @@ import { TokenCredential } from '@azure/identity'; import { CertificateClient, - ImportCertificateOptions, KeyVaultCertificateWithPolicy, } from '@azure/keyvault-certificates'; import { SecretClient } from '@azure/keyvault-secrets'; @@ -48,16 +47,25 @@ export class KeyVaultStore { } async importCertificate(name: string, cert: string | Buffer, format: 'pem' | 'pfx' = 'pem', password?: string): Promise { - const options: ImportCertificateOptions = { - password, - policy: { - contentType: format === 'pfx' ? 'application/x-pkcs12' : 'application/x-pem-file', - issuerName: 'Unknown', - subject: 'CN=unknown', - }, - }; const certBuffer = typeof cert === 'string' ? Buffer.from(cert) : cert; - await this.certClient.importCertificate(name, certBuffer, options); + // The high-level CertificateClient spreads `policy` into import params but the + // generated serializer reads `certificatePolicy` — a key mismatch that silently + // drops content_type from the REST body. Call the internal client directly so + // secret_props.content_type reaches Azure (required for PFX; without it Azure + // defaults to PEM parsing and rejects binary PFX data). + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const internalClient = (this.certClient as any).client; + await internalClient.importCertificate(name, { + base64EncodedCertificate: format === 'pem' + ? certBuffer.toString('ascii') + : certBuffer.toString('base64'), + password, + certificatePolicy: { + secretProperties: { + contentType: format === 'pfx' ? 'application/x-pkcs12' : 'application/x-pem-file', + }, + }, + }, {}); } }