PKI URL Management Architecture
This document describes the comprehensive URL management system for PKI services in PKIaaS, including dynamic URL generation, configuration optimization, and standards compliance.
Overview
PKIaaS implements a centralized URL management system that automatically generates all PKI service URLs from a single base configuration, ensuring consistency, maintainability, and standards compliance across all certificate-related protocols.
Architecture Principles
Single Source of Truth
All PKI URLs are generated from one configuration parameter:
PKI_PUBLIC_URL=https://pki.your-domain.com
This eliminates configuration redundancy and ensures consistency across all services.
Dynamic Generation
URLs are generated dynamically based on context: - CA-specific URLs for CRL distribution points - Protocol-specific URLs for OCSP, SCEP, EST, ACME - Resource-specific URLs for certificates, orders, authorizations
Standards Compliance
All generated URLs follow RFC specifications: - RFC 5280: Certificate extensions with proper distribution points - RFC 6960: OCSP responder URLs - RFC 8894: SCEP service endpoints - RFC 7030: EST service discovery - RFC 8555: ACME directory structure
URL Generation System
Core Helper Class
The PkiUrlHelper class provides centralized URL generation:
class PkiUrlHelper
{
// Base URL management
public static function getBaseUrl(): string
// Protocol-specific URLs
public static function getCrlUrl(CertificateAuthority $ca): string
public static function getOcspUrl(): string
public static function getScepUrl(): string
public static function getEstUrl(string $operation = ''): string
public static function getAcmeDirectoryUrl(): string
// Dynamic resource URLs
public static function getAcmeOrderUrl(string $orderId): string
public static function getAcmeChallengeUrl(string $challengeId): string
// Service discovery
public static function getServiceUrls(): array
}
URL Patterns
Certificate Lifecycle URLs
| Service | Pattern | Example | Context |
|---|---|---|---|
| CRL per CA | {base}/api/v1/crl/{ca_id} |
https://pki.domain.com/api/v1/crl/123 |
CA-specific revocation lists |
| OCSP | {base}/api/v1/ocsp |
https://pki.domain.com/api/v1/ocsp |
Certificate validation |
| AIA | {base}/api/v1/ca/{ca_id}/certificate |
https://pki.domain.com/api/v1/ca/123/certificate |
CA certificate access |
Enrollment Protocol URLs
| Protocol | Pattern | Example | Purpose |
|---|---|---|---|
| SCEP | {base}/api/v1/scep |
https://pki.domain.com/api/v1/scep |
Device enrollment |
| EST Base | {base}/api/v1/est |
https://pki.domain.com/api/v1/est |
Enterprise enrollment |
| EST Operation | {base}/api/v1/est/{op} |
https://pki.domain.com/api/v1/est/cacerts |
Specific EST operations |
ACME Protocol URLs
| Endpoint | Pattern | Example | RFC 8555 |
|---|---|---|---|
| Directory | {base}/api/v1/acme/directory |
https://pki.domain.com/api/v1/acme/directory |
✅ Required |
| New Nonce | {base}/api/v1/acme/new-nonce |
https://pki.domain.com/api/v1/acme/new-nonce |
✅ Required |
| New Account | {base}/api/v1/acme/new-account |
https://pki.domain.com/api/v1/acme/new-account |
✅ Required |
| New Order | {base}/api/v1/acme/new-order |
https://pki.domain.com/api/v1/acme/new-order |
✅ Required |
| Authorization | {base}/api/v1/acme/authz/{id} |
https://pki.domain.com/api/v1/acme/authz/auth-123 |
Dynamic |
| Challenge | {base}/api/v1/acme/chall/{id} |
https://pki.domain.com/api/v1/acme/chall/chall-456 |
Dynamic |
| Finalize | {base}/api/v1/acme/finalize/{id} |
https://pki.domain.com/api/v1/acme/finalize/order-789 |
Dynamic |
Certificate Extensions Integration
CRL Distribution Points
Automatically generated per CA:
CRL Distribution Points:
- URI: https://pki.domain.com/api/v1/crl/123
Authority Information Access
Generated with proper CA hierarchy:
Authority Information Access:
- OCSP: https://pki.domain.com/api/v1/ocsp
- CA Issuers: https://pki.domain.com/api/v1/ca/456/certificate
Implementation in CryptoService
private function buildCertificateExtensions(array $config, $ca = null): array
{
// CRL Distribution Points (generated dynamically from CA)
if ($ca) {
$crlUrls = PkiUrlHelper::getCrlDistributionPoints($ca);
$extensions['id-ce-cRLDistributionPoints'] = [
// Proper ASN.1 structure with dynamic URLs
];
}
// Authority Information Access (AIA) - generated dynamically
if ($ca) {
$aiaData = PkiUrlHelper::getAuthorityInfoAccess($ca);
$extensions['id-pe-authorityInfoAccess'] = [
// Proper AIA structure with OCSP and CA Issuer URLs
];
}
}
ACME Directory Implementation
RFC 8555 Compliant Directory
The ACME directory is generated with all required endpoints:
{
"newNonce": "https://pki.domain.com/api/v1/acme/new-nonce",
"newAccount": "https://pki.domain.com/api/v1/acme/new-account",
"newOrder": "https://pki.domain.com/api/v1/acme/new-order",
"revokeCert": "https://pki.domain.com/api/v1/acme/revoke-cert",
"keyChange": "https://pki.domain.com/api/v1/acme/key-change",
"meta": {
"termsOfService": "https://pki.domain.com/api/v1/acme/terms-of-service",
"website": "https://pki.domain.com",
"caaIdentities": ["pki.domain.com"],
"externalAccountRequired": false
}
}
Dynamic Resource URLs
For ACME protocol operations that require resource-specific URLs:
// Order management
$orderUrl = PkiUrlHelper::getAcmeOrderUrl($orderId);
// -> https://pki.domain.com/api/v1/acme/order/12345
// Challenge handling
$challengeUrl = PkiUrlHelper::getAcmeChallengeUrl($challengeId);
// -> https://pki.domain.com/api/v1/acme/chall/http-01-67890
// Certificate retrieval
$certUrl = PkiUrlHelper::getAcmeCertificateUrl($orderId);
// -> https://pki.domain.com/api/v1/acme/cert/12345
Configuration Management
Simplified Configuration
Before (Redundant)
PKI_PUBLIC_URL=https://pki.domain.com
CRL_DISTRIBUTION_BASE_URL=https://pki.domain.com/api/v1/crl # Redundant
PKI_OCSP_RESPONDER_URL=https://pki.domain.com/api/v1/ocsp # Redundant
After (Optimized)
PKI_PUBLIC_URL=https://pki.domain.com
# All other URLs generated automatically
Fallback Strategy
public static function getBaseUrl(): string
{
$baseUrl = config('pki.public_base_url');
if (!$baseUrl) {
$baseUrl = config('app.url'); // Fallback to APP_URL
}
return rtrim($baseUrl, '/');
}
Service Discovery
Comprehensive Service URLs
The system provides complete service discovery:
$serviceUrls = PkiUrlHelper::getServiceUrls();
/*
[
'base_url' => 'https://pki.domain.com',
'ocsp' => 'https://pki.domain.com/api/v1/ocsp',
'scep' => 'https://pki.domain.com/api/v1/scep',
'est' => 'https://pki.domain.com/api/v1/est',
'acme' => 'https://pki.domain.com/api/v1/acme/directory',
'acme_directory' => [/* Full ACME directory structure */],
'api' => 'https://pki.domain.com/api/v1'
]
*/
Testing and Validation
Comprehensive Testing Commands
Test All PKI URLs
php artisan pki:test-urls
Output:
=== Base Service URLs ===
base_url: https://pki.domain.com
ocsp: https://pki.domain.com/api/v1/ocsp
scep: https://pki.domain.com/api/v1/scep
est: https://pki.domain.com/api/v1/est
acme: https://pki.domain.com/api/v1/acme/directory
=== URLs for CA: Root CA (ID: 1) ===
CRL URL: https://pki.domain.com/api/v1/crl/1
Authority Info Access:
- OCSP: https://pki.domain.com/api/v1/ocsp
Test ACME Directory
php artisan acme:test-directory --test-connectivity
Output:
=== ACME Directory Structure ===
✓ newNonce: https://pki.domain.com/api/v1/acme/new-nonce
✓ newAccount: https://pki.domain.com/api/v1/acme/new-account
✓ newOrder: https://pki.domain.com/api/v1/acme/new-order
✓ revokeCert: https://pki.domain.com/api/v1/acme/revoke-cert
✓ keyChange: https://pki.domain.com/api/v1/acme/key-change
=== RFC 8555 Compliance ===
✓ RFC 8555 Compliance: PASSED
All required ACME directory endpoints are present.
Security Considerations
HTTPS Enforcement
private static function normalizeUrl(string $url): string
{
// Ensure HTTPS in production
if (app()->environment('production') && !str_starts_with($url, 'https://')) {
$url = str_replace('http://', 'https://', $url);
}
return rtrim($url, '/');
}
URL Validation
All generated URLs are validated for: - Proper URI format - HTTPS enforcement in production - Consistent base URL usage - Path normalization
Benefits
Operational Benefits
- Single Configuration Point: Only
PKI_PUBLIC_URLneeds to be configured - Consistency: All URLs generated from the same base, eliminating conflicts
- Maintainability: Domain changes require only one configuration update
- Standards Compliance: All URLs follow RFC specifications automatically
Development Benefits
- Centralized Management: All URL logic in one helper class
- Type Safety: Strong typing for all URL generation methods
- Testing: Comprehensive test coverage for all URL patterns
- Documentation: Self-documenting URL structures
Deployment Benefits
- Environment Flexibility: Easy transition between environments
- Load Balancer Ready: URLs work correctly behind load balancers
- CDN Compatible: Proper URL structures for CDN integration
- Multi-Instance: Supports multi-instance Docker deployments
Integration Examples
Certificate Generation
// Generate certificate with proper extensions
$ca = CertificateAuthority::find(1);
$config = [
'subject' => ['CN' => 'example.com'],
'ca' => $ca // URLs generated automatically
];
$extensions = $this->buildCertificateExtensions($config, $ca);
// CRL Distribution Points and AIA automatically populated
ACME Client Integration
// ACME client discovers all endpoints
$directory = PkiUrlHelper::getAcmeDirectory();
$client = new AcmeClient($directory['newAccount'], $directory['newOrder']);
Certificate Validation
// Certificate includes proper validation URLs
$ocspUrl = PkiUrlHelper::getOcspUrl();
$crlUrl = PkiUrlHelper::getCrlUrl($certificate->certificateAuthority);
// Client can validate certificate using generated URLs
This comprehensive URL management system ensures PKIaaS provides consistent, maintainable, and standards-compliant URLs for all PKI operations while minimizing configuration complexity and operational overhead.
Vous n'avez pas envie de la manager ?
Découvrir notre offre PKI As A Service