Certificate Management
X.509 certificates are essential for AS2 message security, providing encryption and digital signature capabilities. AS2aaS provides comprehensive certificate management at both account and tenant levels, supporting master certificates for operational efficiency and tenant-specific certificates for specialized requirements.
Certificate Types
Master Certificates (Account-Level)
Shared across all tenants in an account for operational efficiency:
- Identity Certificates: Account-level signing and encryption certificates
- Partner Certificates: Master partner certificates inherited by tenants
- Cost Efficiency: Single certificate procurement and renewal process
- Centralized Management: Unified certificate lifecycle management
Tenant Certificates
Tenant-specific certificates for specialized requirements:
- Tenant Identity: Tenant-specific signing and encryption certificates
- Tenant Partners: Partner certificates for tenant-only relationships
- Custom Requirements: Certificates for specific tenant security needs
Certificate Usage by Type
Identity Certificates
Your organization's certificates used for:
- Signing outbound messages (proves message authenticity)
- Decrypting inbound messages (private key decryption)
- Available at: Account level (shared) or tenant level (specific)
Partner Certificates
Trading partners' public certificates used for:
- Encrypting outbound messages (using partner's public key)
- Verifying inbound message signatures (using partner's public key)
- Available at: Account level (master partners) or tenant level (tenant partners)
Certificate Operations
List Certificates
List Tenant Certificates
GET /v1/certificates
List Account Master Certificates
GET /v1/accounts/{account}/certificates
Query Parameters:
type
(string) - Filter by type:identity
,partner
active
(boolean) - Filter by active statusexpires_soon
(boolean) - Certificates expiring within 30 dayspartner_id
(string) - Filter by specific partnerscope
(string) - Filter by scope:account
,tenant
(tenant endpoint only)
Response (200):
{
"data": [
{
"id": "cert_000001",
"name": "Account Master Identity Certificate",
"type": "identity",
"usage": "signing",
"scope": "account",
"subject": "CN=My Company AS2, O=My Company Inc, C=US",
"issuer": "CN=AS2aaS CA, O=AS2aaS Inc",
"serial_number": "123456789abcdef",
"fingerprint": "SHA256:ab:cd:ef:12:34:56:78:90:ab:cd:ef:12:34:56:78:90:ab:cd:ef:12:34:56:78:90:ab:cd",
"active": true,
"tenant_usage_count": 5,
"expires_at": "2025-01-01T00:00:00Z",
"created_at": "2024-01-01T10:00:00Z"
},
{
"id": "cert_000002",
"name": "McKesson Master Partner Certificate",
"type": "partner",
"usage": "encryption",
"scope": "account",
"partner_id": "prt_000001",
"subject": "CN=McKesson AS2, O=McKesson Corporation, C=US",
"issuer": "CN=McKesson CA, O=McKesson Corporation",
"serial_number": "987654321fedcba",
"fingerprint": "SHA256:12:34:56:78:90:ab:cd:ef:12:34:56:78:90:ab:cd:ef:12:34:56:78:90:ab:cd:ef:12:34",
"active": true,
"tenant_usage_count": 3,
"expires_at": "2025-06-01T00:00:00Z",
"created_at": "2024-01-01T10:00:00Z"
},
{
"id": "cert_000003",
"name": "East Coast Tenant Identity Certificate",
"type": "identity",
"usage": "signing",
"scope": "tenant",
"tenant_id": "tnt_000001",
"subject": "CN=East Coast Division AS2, O=My Company Inc, C=US",
"issuer": "CN=AS2aaS CA, O=AS2aaS Inc",
"serial_number": "456789abcdef123",
"fingerprint": "SHA256:cd:ef:12:34:56:78:90:ab:cd:ef:12:34:56:78:90:ab:cd:ef:12:34:56:78:90:ab:cd:ef",
"active": true,
"expires_at": "2025-03-01T00:00:00Z",
"created_at": "2024-01-15T10:00:00Z"
}
],
"pagination": {
"current_page": 1,
"last_page": 1,
"per_page": 20,
"total": 2
}
}
Upload Certificate
Upload Tenant Certificate
POST /v1/certificates
Upload Account Master Certificate
POST /v1/accounts/{account}/certificates
Request (multipart/form-data):
Tenant Identity Certificate
curl -X POST https://api.as2aas.com/v1/certificates \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "name=East Coast Identity Certificate" \
-F "type=identity" \
-F "usage=signing" \
-F "[email protected]" \
-F "[email protected]" \
-F "password=cert-password"
Account Master Identity Certificate
curl -X POST https://api.as2aas.com/v1/accounts/acc_000001/certificates \
-H "Authorization: Bearer YOUR_ACCOUNT_API_KEY" \
-F "name=Account Master Identity Certificate" \
-F "type=identity" \
-F "usage=signing" \
-F "[email protected]" \
-F "[email protected]" \
-F "password=cert-password"
Response (201):
{
"message": "Certificate uploaded successfully",
"data": {
"id": "cert_000003",
"name": "My Identity Certificate",
"type": "identity",
"usage": "signing",
"subject": "CN=My Company AS2, O=My Company Inc",
"fingerprint": "SHA256:ab:cd:ef:12...",
"active": false,
"expires_at": "2025-01-01T00:00:00Z",
"created_at": "2024-01-15T10:30:00Z"
}
}
Get Certificate Details
GET /v1/certificates/{certificate_id}
Delete Certificate
DELETE /v1/certificates/{certificate_id}
Activate Certificate
POST /v1/certificates/{certificate_id}/activate
Certificate Formats
Supported Formats
- PEM (recommended) - Base64 encoded with headers
- DER - Binary format
- PKCS#12 - Combined certificate and private key
- PKCS#7 - Certificate chain format
PEM Format Example
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAKoK/OvD/XaUMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
...
-----END CERTIFICATE-----
Partner Certificate Management
Upload Partner Certificate
POST /v1/partners/{partner_id}/certificates
Request:
curl -X POST https://api.as2aas.com/v1/partners/prt_000001/certificates \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "name=Partner Encryption Certificate" \
-F "usage=encryption" \
-F "[email protected]"
List Partner Certificates
GET /v1/partners/{partner_id}/certificates
Activate Partner Certificate
POST /v1/partners/{partner_id}/certificates/{certificate_id}/activate
Remove Partner Certificate
DELETE /v1/partners/{partner_id}/certificates/{certificate_id}
Certificate Scoping and Inheritance
Account-Level (Master) Certificates
Master certificates are shared across all tenants in an account:
- Automatic Inheritance: All tenants automatically inherit master certificates
- Operational Efficiency: Single certificate management for multiple tenants
- Cost Savings: One certificate renewal process instead of per-tenant
- Centralized Control: Account-level certificate policies and lifecycle
Tenant-Level Certificates
Tenant-specific certificates override or supplement master certificates:
- Tenant Isolation: Certificates scoped to specific tenant operations
- Custom Requirements: Specialized certificates for unique tenant needs
- Override Capability: Tenant certificates take precedence over master certificates
- Granular Control: Tenant-specific certificate policies
Certificate Resolution Priority
When determining which certificate to use for AS2 operations:
- Tenant-specific certificate (highest priority)
- Account master certificate (inherited)
- Default system certificate (fallback)
Certificate Inheritance Example
{
"account_certificates": [
{
"id": "cert_master_001",
"name": "Account Master Identity",
"type": "identity",
"usage": "signing",
"scope": "account",
"inherited_by_tenants": ["tnt_001", "tnt_002", "tnt_003"]
}
],
"tenant_certificates": [
{
"id": "cert_tenant_001",
"name": "East Coast Custom Identity",
"type": "identity",
"usage": "signing",
"scope": "tenant",
"tenant_id": "tnt_001",
"overrides": "cert_master_001"
}
]
}
Certificate Usage
For Message Encryption
Using Master Certificates
Outbound Messages:
- Upload partner's public certificate at account level
- All tenants inherit this certificate automatically
- AS2aaS encrypts messages using partner's public key
- Partner decrypts using their private key
Using Tenant Certificates
Outbound Messages:
- Upload partner's public certificate at tenant level
- Only specific tenant uses this certificate
- Tenant certificate overrides master certificate if both exist
Inbound Messages:
- Upload your identity certificate (private key) at account or tenant level
- Partner encrypts message using your public key
- AS2aaS decrypts using your private key (account master or tenant-specific)
For Digital Signatures
Outbound Messages:
- Upload your identity certificate (private key) at appropriate level
- AS2aaS signs message using your private key
- Partner verifies signature using your public key
Inbound Messages:
- Upload partner's public certificate at appropriate level
- Partner signs message using their private key
- AS2aaS verifies signature using partner's public key
Certificate Lifecycle
Certificate Status
Status | Description |
---|---|
pending | Uploaded but not yet activated |
active | Currently in use for AS2 operations |
inactive | Deactivated but retained |
expired | Past expiration date |
Expiry Management
Check Expiring Certificates:
GET /v1/certificates?expires_soon=true
Expiry Webhook Event:
{
"event": "certificate.expiring",
"data": {
"id": "cert_000001",
"name": "Partner Certificate",
"type": "partner",
"subject": "CN=Partner AS2",
"expires_at": "2024-02-15T00:00:00Z",
"days_until_expiry": 30
},
"timestamp": "2024-01-15T10:30:00Z"
}
Certificate Renewal
// Monitor and renew certificates
async function checkCertificateExpiry() {
const expiring = await as2.certificates.list({ expires_soon: true });
for (const cert of expiring.data) {
if (cert.days_until_expiry <= 30) {
await notifyAdmin(`Certificate ${cert.name} expires in ${cert.days_until_expiry} days`);
if (cert.type === 'identity') {
await generateNewIdentityCertificate(cert);
} else {
await requestPartnerCertificateUpdate(cert.partner_id);
}
}
}
}
Certificate Validation
Validate Certificate
POST /v1/certificates/{certificate_id}/validate
Response (200):
{
"valid": true,
"checks": [
{
"name": "Format Validation",
"status": "pass",
"message": "Certificate is in valid PEM format"
},
{
"name": "Expiry Check",
"status": "pass",
"message": "Certificate is valid until 2025-01-01"
},
{
"name": "Key Usage",
"status": "pass",
"message": "Certificate supports required key usage"
},
{
"name": "Chain Validation",
"status": "pass",
"message": "Certificate chain is valid"
}
],
"details": {
"subject": "CN=My Company AS2",
"issuer": "CN=AS2aaS CA",
"valid_from": "2024-01-01T00:00:00Z",
"valid_until": "2025-01-01T00:00:00Z",
"key_size": 2048,
"signature_algorithm": "SHA256withRSA"
}
}
Security Best Practices
Certificate Security
- Private Key Protection: Store private keys securely
- Regular Rotation: Renew certificates annually
- Strong Algorithms: Use SHA256 or higher
- Key Size: Use 2048-bit minimum, 4096-bit for high security
- Certificate Validation: Verify certificates before activation
Certificate Storage
AS2aaS securely stores certificates with:
- Encryption at rest using AES-256
- Access controls limited to your tenant
- Audit logging for all certificate operations
- Secure deletion when certificates are removed
Integration Examples
Automated Certificate Management
// Comprehensive certificate management
class CertificateManager {
constructor(as2Client) {
this.as2 = as2Client;
}
async uploadPartnerCertificate(partnerId, certFile, usage = 'encryption') {
const formData = new FormData();
formData.append('name', `Partner ${usage} Certificate`);
formData.append('usage', usage);
formData.append('certificate', certFile);
const cert = await this.as2.partners.uploadCertificate(partnerId, formData);
// Validate certificate
const validation = await this.as2.certificates.validate(cert.id);
if (!validation.valid) {
throw new Error(`Certificate validation failed: ${validation.message}`);
}
// Activate certificate
await this.as2.certificates.activate(cert.id);
return cert;
}
async monitorExpiry() {
const expiring = await this.as2.certificates.list({ expires_soon: true });
for (const cert of expiring.data) {
if (cert.days_until_expiry <= 7) {
await this.urgentRenewalAlert(cert);
} else if (cert.days_until_expiry <= 30) {
await this.renewalReminder(cert);
}
}
}
}
Certificate Chain Validation
// Validate complete certificate chain
async function validateCertificateChain(certificateId) {
const validation = await as2.certificates.validate(certificateId);
const issues = validation.checks
.filter(check => check.status !== 'pass')
.map(check => check.message);
if (issues.length > 0) {
console.warn('Certificate issues found:', issues);
return false;
}
console.log('Certificate validation passed');
return true;
}
Error Handling
Common Certificate Errors
Error Code | Description | Resolution |
---|---|---|
INVALID_FORMAT | Certificate format not supported | Use PEM or DER format |
EXPIRED_CERTIFICATE | Certificate has expired | Upload new certificate |
INVALID_KEY_USAGE | Certificate doesn't support required usage | Check certificate key usage extensions |
CHAIN_INCOMPLETE | Certificate chain is incomplete | Include intermediate certificates |
PRIVATE_KEY_MISMATCH | Private key doesn't match certificate | Verify key pair matches |
Certificate Error Response
{
"error": {
"type": "certificate_error",
"code": "EXPIRED_CERTIFICATE",
"message": "Certificate expired on 2024-01-10T00:00:00Z",
"details": {
"certificate_id": "cert_000001",
"subject": "CN=Partner AS2",
"expired_at": "2024-01-10T00:00:00Z",
"days_expired": 5
}
}
}
Certificate Workflows
New Partner Setup
async function setupNewPartner(partnerData) {
// 1. Create partner
const partner = await as2.partners.create({
name: partnerData.name,
as2_id: partnerData.as2_id,
url: partnerData.endpoint,
encrypt: true,
sign: true
});
// 2. Upload partner's encryption certificate
if (partnerData.encryptionCert) {
await as2.certificates.upload({
partner_id: partner.id,
name: `${partner.name} Encryption`,
type: 'partner',
usage: 'encryption',
certificate: partnerData.encryptionCert
});
}
// 3. Upload partner's signing certificate (if different)
if (partnerData.signingCert && partnerData.signingCert !== partnerData.encryptionCert) {
await as2.certificates.upload({
partner_id: partner.id,
name: `${partner.name} Signing`,
type: 'partner',
usage: 'signing',
certificate: partnerData.signingCert
});
}
return partner;
}
Certificate Renewal
async function renewCertificate(certificateId) {
const cert = await as2.certificates.get(certificateId);
if (cert.type === 'identity') {
// Generate new identity certificate
const newCert = await as2.certificates.generateIdentity({
common_name: cert.subject.match(/CN=([^,]+)/)[1],
organization: cert.subject.match(/O=([^,]+)/)?.[1],
country: cert.subject.match(/C=([^,]+)/)?.[1],
key_size: 2048,
validity_days: 365
});
// Activate new certificate
await as2.certificates.activate(newCert.id);
// Deactivate old certificate
await as2.certificates.deactivate(certificateId);
return newCert;
} else {
// Partner certificate - request new one from partner
throw new Error('Partner certificates must be renewed by the partner');
}
}
Certificate Download
Download Certificate
GET /v1/certificates/{certificate_id}/download
Query Parameters:
format
(string) -pem
,der
,pkcs12
include_chain
(boolean) - Include certificate chainpassword
(string) - Password for PKCS12 format
Response: Certificate file with appropriate Content-Type
Download Public Key Only
GET /v1/certificates/{certificate_id}/public-key
Returns just the public key portion of the certificate.
Certificate Information
Get Certificate Info
GET /v1/certificates/{certificate_id}/info
Response (200):
{
"data": {
"subject": {
"common_name": "My Company AS2",
"organization": "My Company Inc",
"country": "US"
},
"issuer": {
"common_name": "AS2aaS CA",
"organization": "AS2aaS Inc"
},
"validity": {
"not_before": "2024-01-01T00:00:00Z",
"not_after": "2025-01-01T00:00:00Z",
"days_remaining": 351
},
"key_info": {
"algorithm": "RSA",
"size": 2048,
"usage": ["digital_signature", "key_encipherment"]
},
"extensions": {
"key_usage": ["digital_signature", "key_encipherment"],
"extended_key_usage": ["client_auth", "server_auth"],
"subject_alt_names": ["email:[email protected]"]
},
"fingerprints": {
"sha1": "12:34:56:78:90:ab:cd:ef",
"sha256": "ab:cd:ef:12:34:56:78:90:ab:cd:ef:12:34:56:78:90:ab:cd:ef:12:34:56:78:90:ab:cd"
}
}
}
Certificate Monitoring
Expiry Monitoring
GET /v1/certificates/expiry-report
Response (200):
{
"data": {
"expiring_soon": [
{
"id": "cert_000001",
"name": "Partner Certificate",
"expires_at": "2024-02-15T00:00:00Z",
"days_remaining": 30
}
],
"expired": [],
"total_certificates": 5,
"health_score": 100
}
}
Certificate Events
Webhook Events:
certificate.uploaded
- New certificate uploadedcertificate.activated
- Certificate activated for usecertificate.expiring
- Certificate expires within 30 dayscertificate.expired
- Certificate has expiredcertificate.validation_failed
- Certificate validation failed
Troubleshooting
Common Issues
Certificate Upload Fails
- Check file format (PEM recommended)
- Verify certificate and private key match
- Ensure certificate is not expired
- Check file size limits (10MB max)
Message Encryption Fails
- Verify partner's encryption certificate is uploaded and active
- Check encryption algorithm compatibility
- Ensure certificate supports encryption key usage
Signature Verification Fails
- Verify partner's signing certificate is uploaded
- Check signature algorithm matches partner's capability
- Ensure certificate chain is complete
Debug Certificate Issues
# Get detailed certificate information
GET /v1/certificates/{certificate_id}/debug
Returns detailed validation results, key usage information, and compatibility checks.
Getting Help
For certificate issues:
- Use certificate validation to identify specific problems
- Check expiry dates and renewal requirements
- Verify certificate formats and key usage
- Contact support with certificate ID for investigation
Advanced Features
Certificate Templates
Create reusable certificate templates for consistent partner onboarding:
{
"name": "Standard Partner Template",
"subject_template": "CN={{partner_name}} AS2, O={{partner_org}}, C=US",
"key_size": 2048,
"validity_days": 365,
"key_usage": ["digital_signature", "key_encipherment"]
}
Bulk Certificate Operations
// Upload multiple partner certificates
async function bulkUploadCertificates(certificateList) {
const results = [];
for (const certData of certificateList) {
try {
const cert = await as2.certificates.upload(certData);
await as2.certificates.activate(cert.id);
results.push({ success: true, certificate: cert });
} catch (error) {
results.push({ success: false, error: error.message, data: certData });
}
}
return results;
}
Certificate Backup
// Backup all certificates
async function backupCertificates() {
const certificates = await as2.certificates.list({ per_page: 100 });
for (const cert of certificates.data) {
if (cert.type === 'identity') {
// Download and backup identity certificates
const certData = await as2.certificates.download(cert.id, { format: 'pkcs12' });
await saveToSecureStorage(`backup-${cert.id}.p12`, certData);
}
}
}