🏷️ CA Trust Flags System - Specification
Date: 2025-10-02 Status: 🚧 IN DEVELOPMENT Version: 1.0
📋 Overview
System of cumulative trust flags for Certificate Authorities (CAs) to provide visual security and operational indicators in the PKI system.
Design Philosophy: - Cumulative flags within categories (not exclusive enum) - Auto-detection where possible (minimize manual tagging) - Visual badges for dashboard quick assessment - Audit trail for flag changes
🔐 Category: Security Level (Mutually Exclusive)
Only ONE security flag per CA at any time.
| Flag | Badge | Color | Description | Auto-Detection Rule |
|---|---|---|---|---|
very_secure |
🟢 VERY SECURE | Green | Has always been internal and has never been without a password. |
trust_origin == 'internal' AND NEVER_WITHOUT_PASSWORD |
secure |
🟡 SECURE | Yellow | Is internal but was once without a password, OR has been imported/exported but has never been without a password. |
(trust_origin == 'internal' AND WAS_WITHOUT_PASSWORD) OR (trust_origin != 'internal' AND NEVER_WITHOUT_PASSWORD) |
normal |
🟠 NORMAL | Orange | Has been imported/exported and was once without a password. |
trust_origin != 'internal' AND WAS_WITHOUT_PASSWORD |
compromised |
🔴 COMPROMISED | Red | Key compromised - revocation required | Manual flag OR security incident detection |
State Transitions:
- A CA's security level is dynamically calculated based on its origin and password history.
- The compromised state is a manual override and is irreversible.
- NEVER_WITHOUT_PASSWORD: The CA was created with password protection and has never had it removed.
- WAS_WITHOUT_PASSWORD: The CA was created without password protection or has had it removed at some point.
Core Principle: Trust is a One-Way Street ⚠️ A Certificate Authority's security level can NEVER be upgraded. It is dynamically calculated based on its history (origin and password status). Once a CA has been in a less secure state (e.g., exported, or without a password), it can never regain a higher trust level, even if conditions change (e.g., a password is added). This prevents rewriting history and ensures a reliable trust assessment.
📦 Category: Origin (Mutually Exclusive)
Only ONE origin flag per CA at any time.
| Flag | Badge | Color | Description | Trigger |
|---|---|---|---|---|
internal |
🏠 INTERNAL | Blue | Generated internally by PKIaaS | Default on CA creation |
imported |
📥 IMPORTED | Purple | Imported from external system | Import of external CA cert + key |
exported |
📤 EXPORTED | Orange | Private key exported externally | Download of private key (PKCS#12, PEM) |
State Transitions:
[Creation] → internal
internal + export private key → exported
[Import CA] → imported
Notes:
- Once exported, stays exported forever (key left the system)
- imported means we don't know full key history (trust lower)
- Can't go back to internal once exported or imported
🔄 Category: Lifecycle (Cumulative)
Multiple lifecycle flags can be active simultaneously.
| Flag | Badge | Color | Description | Trigger |
|---|---|---|---|---|
rotated |
🔄 ROTATED | Cyan | CA has been renewed/rotated | CA rotation performed |
cross_signed |
⚡ CROSS-SIGNED | Yellow | Cross-signed with another CA | Cross-signing established |
retired |
💤 RETIRED | Gray | CA retired (not revoked) | Manual retirement or end-of-life |
Examples:
- A CA can be both rotated AND cross_signed
- A CA can be retired but still valid for verification
⚙️ Category: Operational (Cumulative) - FUTURE
Proposed for future implementation:
| Flag | Badge | Description | Trigger |
|---|---|---|---|
hsm_backed |
🔒 HSM | Private key in Hardware Security Module | NitroKey/HSM integration |
air_gapped |
🌐 AIR-GAPPED | Offline root CA (no recent signing) | No certificate signed in 30+ days |
high_volume |
📈 HIGH-VOLUME | High certificate issuance volume | > 1000 certificates issued |
auto_renewal |
🔁 AUTO-RENEW | Auto-renewal enabled | auto_renewal_enabled=true |
manual_approval |
✋ APPROVAL | Requires manual approval | approval_mode=manual |
acme_enabled |
🤖 ACME | ACME server enabled | acme_public_enabled=true |
mfa_required |
🛡️ MFA | Multi-factor auth required | MFA policy enabled |
offline_root |
🔐 OFFLINE | Offline root CA (never online) | Root CA + never signed anything |
🎯 Category: Compliance (Cumulative) - FUTURE
Proposed for compliance tracking:
| Flag | Badge | Description |
|---|---|---|
audited |
✅ AUDITED | Recent external audit passed |
gdpr_compliant |
📜 GDPR | GDPR compliance verified |
soc2_compliant |
📋 SOC2 | SOC2 Type II certified |
hipaa_compliant |
🏥 HIPAA | HIPAA compliance verified |
💾 Database Schema
CertificateAuthorities Table - New Columns
-- Security flags (mutually exclusive)
trust_security_level VARCHAR(20) DEFAULT 'secure'
CHECK (trust_security_level IN ('very_secure', 'secure', 'compromised'))
-- Origin flags (mutually exclusive)
trust_origin VARCHAR(20) DEFAULT 'internal'
CHECK (trust_origin IN ('internal', 'imported', 'exported'))
-- Lifecycle flags (cumulative - JSON array)
trust_lifecycle_flags JSON DEFAULT '[]'
-- Example: ["rotated", "cross_signed"]
-- Operational flags (cumulative - JSON array) - FUTURE
trust_operational_flags JSON DEFAULT '[]'
-- Compliance flags (cumulative - JSON array) - FUTURE
trust_compliance_flags JSON DEFAULT '[]'
-- Metadata
trust_flags_last_updated_at TIMESTAMP
trust_flags_audit_log JSON DEFAULT '[]'
-- Track who changed what flag when
🎨 UI/UX Guidelines
Dashboard CA List
┌─────────────────────────────────────────────────────────────────┐
│ Root CA - RDEM Systems SAS │
│ 🟢 VERY SECURE 🏠 INTERNAL 💤 RETIRED │
│ Expires: 2034-10-02 │ 3 certificates │ Status: Retired │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ Intermediate CA - Web Servers │
│ 🟡 SECURE 📤 EXPORTED 🔄 ROTATED ⚡ CROSS-SIGNED │
│ Expires: 2027-10-02 │ 1,247 certificates │ Status: Active │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ Test CA - Development │
│ 🔴 COMPROMISED 🏠 INTERNAL │
│ Expires: 2025-12-01 │ 23 certificates │ Status: ⚠️ ACTION │
└─────────────────────────────────────────────────────────────────┘
CA Details Page
Trust & Security Status
Security Level: 🟢 VERY SECURE
Password-protected from creation
Never downgraded to secure mode
Origin: 🏠 INTERNAL
Generated by PKIaaS on 2024-09-15
Private key never exported
Lifecycle: 🔄 ROTATED ⚡ CROSS-SIGNED
- Rotated on 2025-01-10
- Cross-signed with "Old Root CA" on 2025-01-10
Last Updated: 2025-10-02 08:00:00 by admin@example.com
Badge Color Scheme
Security:
- 🟢 Green → very_secure (best)
- 🟡 Yellow → secure (standard)
- 🔴 Red → compromised (critical)
Origin:
- 🏠 Blue → internal (most trusted)
- 📥 Purple → imported (medium trust)
- 📤 Orange → exported (lower trust)
Lifecycle:
- 🔄 Cyan → rotated
- ⚡ Yellow → cross_signed
- 💤 Gray → retired
🔄 Auto-Detection Logic
On CA Creation
$ca->trust_security_level = $password ? 'very_secure' : 'secure';
$ca->trust_origin = 'internal';
$ca->trust_lifecycle_flags = [];
On Password Set
// If CA was created without password, it stays 'secure'
if ($ca->trust_security_level === 'secure') {
// Do NOT upgrade to very_secure
// Just enable password protection
$ca->password_protected_encryption = true;
}
On Private Key Export
$ca->trust_origin = 'exported';
$ca->logTrustFlagChange('origin', 'internal', 'exported', 'Private key exported to PKCS#12');
On CA Rotation
$ca->addLifecycleFlag('rotated');
$ca->addLifecycleFlag('cross_signed'); // If cross-signing performed
On Compromise Detection
$ca->trust_security_level = 'compromised';
$ca->logSecurityIncident('CA marked as compromised: ' . $reason);
// Trigger alert to admins
📊 Audit Trail
Every trust flag change is logged:
{
"timestamp": "2025-10-02T08:15:00Z",
"user_id": 1,
"user_email": "admin@example.com",
"flag_type": "security",
"old_value": "very_secure",
"new_value": "secure",
"reason": "Password protection removed by admin",
"ip_address": "192.168.1.100"
}
🚀 Implementation Phases
Phase 1: Core Flags (THIS SPRINT) ✅
- Security flags:
very_secure,secure,compromised - Origin flags:
internal,imported,exported - Lifecycle flags:
rotated,cross_signed,retired - Dashboard badges display
- Auto-detection on creation/export
Phase 2: Operational Flags
- HSM integration detection
- Air-gapped detection
- High-volume detection
- ACME/auto-renewal badges
Phase 3: Compliance & Advanced
- Compliance flags (GDPR, SOC2, HIPAA)
- MFA requirements
- Advanced audit reporting
🔒 Security Considerations
- Immutable Downgrades: Once
exportedorimported, can't go back tointernal - No Upgrades:
securecan never becomevery_secure(prevents false sense of security) - Compromise Flag: Irreversible once set (requires CA replacement)
- Audit Log: All flag changes tracked with user/timestamp/reason
📚 References
- RFC 5280: X.509 Certificate and CRL Profile
- CA/Browser Forum Baseline Requirements
- NIST SP 800-57: Key Management Guidelines
- WebTrust Principles and Criteria for CAs
Document Owner: PKIaaS Development Team Last Updated: 2025-10-02 Status: Ready for implementation Phase 1