Vaultx.Secrets.PKI.Certificates (Vaultx v0.7.0)

View Source

Enterprise certificate lifecycle management for HashiCorp Vault PKI.

This module provides comprehensive certificate lifecycle management for enterprise PKI deployments, including automated certificate issuance, CSR processing, revocation management, and certificate tracking. It supports industry-standard certificate formats and advanced PKI workflows.

Enterprise Certificate Capabilities

Automated Certificate Issuance

  • Role-based certificate issuance with policy enforcement
  • Automated certificate generation with private keys
  • Multiple certificate formats (PEM, DER, PKCS#8, PKCS#12)
  • Automatic certificate chain construction and validation
  • Custom certificate extensions and advanced constraints

Certificate Signing Services

  • Professional CSR processing and validation
  • Role-based policy application to signed certificates
  • Self-issued certificate signing for special use cases
  • Verbatim certificate signing for advanced scenarios
  • Batch certificate signing for operational efficiency

Certificate Lifecycle Management

  • Certificate revocation with comprehensive reason codes
  • Automated certificate renewal and replacement workflows
  • Certificate metadata tracking and audit trails
  • Automated certificate cleanup and maintenance operations
  • Certificate expiration monitoring and alerting

Industry-Standard Formats

  • PEM format (default, human-readable text)
  • DER format (binary, compact encoding)
  • PKCS#8 format for private key storage
  • PKCS#12 format for certificate bundles
  • Certificate bundles with complete trust chains

Usage Examples

# Issue a certificate based on a role
{:ok, cert} = Certificates.issue("web-server", %{
  common_name: "example.com",
  alt_names: "www.example.com,api.example.com",
  ttl: "30d"
})

# Sign a certificate signing request
{:ok, cert} = Certificates.sign("web-server", csr_pem, %{
  common_name: "example.com",
  ttl: "90d"
})

# Revoke a certificate
:ok = Certificates.revoke("39:dd:2e:90:b7:23:1f:8d")

# Read certificate information
{:ok, cert_pem} = Certificates.read("39:dd:2e:90:b7:23:1f:8d")

# List all certificates
{:ok, serials} = Certificates.list()

Certificate Validation

The module performs comprehensive validation including:

  • Domain name validation against role policies
  • Certificate validity period constraints
  • Key usage and extended key usage validation
  • Subject alternative name (SAN) validation
  • Certificate chain validation and trust verification

Security Considerations

Certificate Issuance

  • Validate all certificate requests against role policies
  • Implement proper domain ownership verification
  • Use appropriate certificate validity periods
  • Enable certificate transparency logging when required
  • Implement certificate pinning for critical services

Private Key Management

  • Generate private keys within Vault when possible
  • Use strong key sizes and modern algorithms
  • Implement proper key escrow and backup procedures
  • Rotate private keys regularly
  • Secure private key transmission and storage

Certificate Revocation

  • Implement timely certificate revocation procedures
  • Maintain accurate certificate revocation lists (CRLs)
  • Use OCSP for real-time revocation checking
  • Monitor for certificate compromise indicators
  • Implement automated revocation for expired certificates

API Compliance

Fully implements HashiCorp Vault PKI certificate management:

Summary

Functions

Issue a new certificate based on a role.

List all certificates.

Read a certificate by serial number.

Revoke a certificate by serial number.

Revoke a certificate using its private key.

Sign a certificate signing request (CSR).

Functions

issue(role_name, opts \\ %{}, pki_opts \\ [])

@spec issue(String.t(), map(), keyword()) ::
  {:ok, map()} | {:error, Vaultx.Base.Error.t()}

Issue a new certificate based on a role.

Issues a new certificate using the specified role configuration. The certificate is generated with a new private key unless specified otherwise.

Parameters

  • role_name - Name of the certificate role to use
  • opts - Certificate options (common_name, alt_names, ttl, etc.)
  • pki_opts - PKI engine options (mount_path, timeout, etc.)

Returns

  • {:ok, certificate_info} - Certificate information including certificate, private key, and metadata
  • {:error, error} - Error information

Examples

# Issue a basic certificate
{:ok, cert} = Certificates.issue("web-server", %{
  common_name: "example.com",
  ttl: "30d"
})

# Issue a certificate with SANs
{:ok, cert} = Certificates.issue("web-server", %{
  common_name: "example.com",
  alt_names: "www.example.com,api.example.com",
  ip_sans: "192.168.1.100",
  ttl: "90d",
  format: "pem_bundle"
})

list(pki_opts \\ [])

@spec list(keyword()) :: {:ok, [String.t()]} | {:error, Vaultx.Base.Error.t()}

List all certificates.

Retrieves a list of all certificate serial numbers in the PKI engine.

Parameters

  • pki_opts - PKI engine options

Returns

  • {:ok, serial_numbers} - List of certificate serial numbers
  • {:error, error} - Error information

Examples

{:ok, serials} = Certificates.list()

read(serial_number, pki_opts \\ [])

@spec read(
  String.t(),
  keyword()
) :: {:ok, String.t()} | {:error, Vaultx.Base.Error.t()}

Read a certificate by serial number.

Retrieves the certificate with the specified serial number in PEM format.

Parameters

  • serial_number - Certificate serial number (hex format with colons)
  • pki_opts - PKI engine options

Returns

  • {:ok, certificate} - PEM-encoded certificate
  • {:error, error} - Error information

Examples

{:ok, cert_pem} = Certificates.read("39:dd:2e:90:b7:23:1f:8d")

revoke(serial_number, pki_opts \\ [])

@spec revoke(
  String.t(),
  keyword()
) :: :ok | {:error, Vaultx.Base.Error.t()}

Revoke a certificate by serial number.

Revokes the specified certificate and adds it to the certificate revocation list (CRL). The certificate will no longer be considered valid by clients that check the CRL.

Parameters

  • serial_number - Certificate serial number (hex format with colons)
  • pki_opts - PKI engine options

Returns

  • :ok - Certificate revoked successfully
  • {:error, error} - Error information

Examples

# Revoke a certificate
:ok = Certificates.revoke("39:dd:2e:90:b7:23:1f:8d")

revoke_with_key(certificate, private_key, pki_opts \\ [])

@spec revoke_with_key(String.t(), String.t(), keyword()) ::
  :ok | {:error, Vaultx.Base.Error.t()}

Revoke a certificate using its private key.

Revokes a certificate by providing its private key for authentication. This method can be used when the certificate serial number is not known but the private key is available.

Parameters

  • certificate - PEM-encoded certificate to revoke
  • private_key - PEM-encoded private key for authentication
  • pki_opts - PKI engine options

Returns

  • :ok - Certificate revoked successfully
  • {:error, error} - Error information

Examples

cert_pem = File.read!("cert.pem")
key_pem = File.read!("key.pem")
:ok = Certificates.revoke_with_key(cert_pem, key_pem)

sign(role_name, csr, opts \\ %{}, pki_opts \\ [])

@spec sign(String.t(), String.t(), map(), keyword()) ::
  {:ok, map()} | {:error, Vaultx.Base.Error.t()}

Sign a certificate signing request (CSR).

Signs a provided CSR using the specified role configuration. The CSR must be in PEM format and contain valid certificate request information.

Parameters

  • role_name - Name of the certificate role to use for signing
  • csr - PEM-encoded certificate signing request
  • opts - Additional certificate options
  • pki_opts - PKI engine options

Returns

  • {:ok, certificate_info} - Signed certificate information
  • {:error, error} - Error information

Examples

# Sign a CSR
{:ok, cert} = Certificates.sign("web-server", csr_pem, %{
  common_name: "example.com",
  ttl: "30d"
})

sign_verbatim(csr, opts \\ %{}, pki_opts \\ [])

@spec sign_verbatim(String.t(), map(), keyword()) ::
  {:ok, map()} | {:error, Vaultx.Base.Error.t()}

Sign a certificate verbatim.

Signs a certificate with the exact parameters specified in the CSR, without applying role-based constraints. This is useful for advanced certificate signing scenarios where full control is needed.

Parameters

  • csr - PEM-encoded certificate signing request
  • opts - Certificate options
  • pki_opts - PKI engine options

Returns

  • {:ok, certificate_info} - Signed certificate information
  • {:error, error} - Error information

Examples

{:ok, cert} = Certificates.sign_verbatim(csr_pem, %{
  ttl: "30d",
  format: "pem"
})