|
Download SECURITY_FIX_SUMMARY.md from Snapkitty/pax-coder: direct link, hf CLI and curl.
- Browser
- Download file 10.9 kB
-
https://huggingface.co/Snapkitty/pax-coder/resolve/main/SECURITY_FIX_SUMMARY.md
- Command line
-
hf download hf://Snapkitty/pax-coder/SECURITY_FIX_SUMMARY.md
-
curl -L -o SECURITY_FIX_SUMMARY.md https://huggingface.co/Snapkitty/pax-coder/resolve/main/SECURITY_FIX_SUMMARY.md
10.9 kB
| # PAX-Coder Security Fix Summary | |
| **Date:** 2026-08-18 | |
| **Issue:** Authority Key Separation (CRITICAL) | |
| **Status:** FIXED AND VERIFIED | |
| **Evidence:** 8/8 Mandatory Security Tests Pass | |
| --- | |
| ## What Was Fixed | |
| ### The Problem | |
| **Critical Issue:** The PAX-Coder authorization gate was using the **node public key** (`sovereign/node_pk.pem`) as the **authority verification key**. | |
| **Why This Was Wrong:** | |
| - NODE_PUBLIC_KEY identifies the node (locally generated) | |
| - AUTHORITY_PUBLIC_KEY signs authorizations (exists only on authority server) | |
| - These are two separate trust domains | |
| - Using node key for authority verification violates ADR-0010 | |
| ### The Fix | |
| **Separated trust domains:** | |
| ``` | |
| BEFORE (Wrong): | |
| Gate verifies capabilities using: node_pk.pem | |
| β This is the node's identity, not authority | |
| AFTER (Correct): | |
| Gate verifies capabilities using: authority_pk.pem | |
| β Authority has its own keypair | |
| β Separate from node identity | |
| β Authority private key never leaves server | |
| ``` | |
| --- | |
| ## What Was Implemented | |
| ### 1. Authority Keypair Separation | |
| **Created:** | |
| - `sovereign/generate_authority_key.sh` β Generate authority Ed25519 keypair | |
| - Generates: `authority_sk.pem` (private, off-repo) + `authority_pk.pem` (public, distributable) | |
| ### 2. Capability Signing | |
| **Created:** | |
| - `sovereign/sign_capability.sh` β Sign authorization records with authority private key | |
| - Uses: Canonical JSON + Ed25519 signature | |
| - Output: `JSON|SIGNATURE_HEX` (128 hex chars = 64 bytes) | |
| ### 3. Gate Update | |
| **Modified:** | |
| - `scripts/pax-coder-gate` (line 191) | |
| - Changed from: `AUTHORITY_PUBLIC_KEY_FILE="$SOVEREIGN_DIR/node_pk.pem"` | |
| - Changed to: `AUTHORITY_PUBLIC_KEY_FILE="$SOVEREIGN_DIR/authority_pk.pem"` | |
| ### 4. Comprehensive Test Suite | |
| **Created:** | |
| - `scripts/test_authority_key_separation.sh` β 8 mandatory security tests | |
| - All tests pass (8/8) | |
| ### 5. Documentation | |
| **Created:** | |
| - `docs/AUTHORITY_KEY_SEPARATION_AUDIT.md` β Complete security audit | |
| - `docs/AUTHORITY_KEY_DEPLOYMENT.md` β Operator deployment guide | |
| --- | |
| ## Security Tests (All Passing) | |
| ### Test Results | |
| ``` | |
| β Test 1: Valid authority signature verified with authority key = ACCEPT | |
| β Test 2: Same payload verified with node key = DENY | |
| β Test 3: Unrelated key signature = DENY | |
| β Test 4: Modified payload = DENY | |
| β Test 5: Authority signature + wrong node binding = DENY | |
| β Test 6: Node key cannot create authority signature = DENY | |
| β Test 7: Missing authority key = FAIL CLOSED | |
| β Test 8: Unauthorized key replacement = FAIL CLOSED | |
| Result: 8/8 PASS | |
| Status: EFFECTIVE | |
| ``` | |
| ### What Each Test Verifies | |
| | Test | Verifies | | |
| |------|----------| | |
| | 1 | Authority can sign and gate verifies with authority key | | |
| | 2 | Authority signature cannot verify with node key | | |
| | 3 | Unrelated key signatures are rejected | | |
| | 4 | Payload modifications break signature | | |
| | 5 | Node binding enforced separately from signature | | |
| | 6 | Node key cannot forge authority signature | | |
| | 7 | Missing authority key causes fail-closed | | |
| | 8 | Key replacement attempts are detected | | |
| --- | |
| ## Key Verification | |
| ### Key Separation Confirmed | |
| ```bash | |
| $ diff sovereign/authority_pk.pem sovereign/node_pk.pem | |
| 2c2 | |
| < MCowBQYDK2VwAyEAbobSuE8O58qP/T/JzusIrNUpmLLOmhmR4dqw0g8WVKI= | |
| --- | |
| > MCowBQYDK2VwAyEAbGZAjfWZnVpS3/TRwVPXohePta9LsnUvuHMgdRXcwkk= | |
| Files are different β | |
| ``` | |
| ### Key Hashes | |
| ``` | |
| Authority: a55e8d5423f22af8639168d1cfd5eaf8dcd100e68701ed4b275b34adb8320482 | |
| Node: 5875b9fd00ed1825779c10e3907917492e65f7d4b3c4855f05af3ae4756fc80c | |
| ``` | |
| Different hashes confirm distinct keypairs. | |
| --- | |
| ## Files Changed | |
| ### New Files (Added) | |
| ``` | |
| sovereign/generate_authority_key.sh | |
| ββ Generate authority Ed25519 keypair | |
| ββ Safe permissions (600 on private key) | |
| ββ Secure seed storage | |
| sovereign/sign_capability.sh | |
| ββ Sign authorizations with authority key | |
| ββ Canonical JSON normalization | |
| ββ 128-hex signature output | |
| scripts/test_authority_key_separation.sh | |
| ββ 8 mandatory security tests | |
| ββ All tests pass | |
| ββ Comprehensive verification | |
| docs/AUTHORITY_KEY_SEPARATION_AUDIT.md | |
| ββ Complete security audit | |
| ββ Test results documented | |
| ββ Trust architecture explained | |
| docs/AUTHORITY_KEY_DEPLOYMENT.md | |
| ββ Operator deployment guide | |
| ββ Key provisioning steps | |
| ββ Troubleshooting guide | |
| ``` | |
| ### Modified Files | |
| ``` | |
| scripts/pax-coder-gate | |
| ββ Line 191: Changed key source | |
| ββ From: node_pk.pem | |
| ββ To: authority_pk.pem | |
| .gitignore | |
| ββ Explicit authority key patterns | |
| ββ Prevents accidental commits | |
| ββ authority_sk.pem explicitly denied | |
| sovereign/authorization.json | |
| ββ Restored to ACTIVE status | |
| ββ For testing purposes | |
| docs/CRITICAL_ARCHITECTURE_ISSUE_FOUND.md | |
| ββ Updated status: FIXED | |
| ββ Points to new audit document | |
| ``` | |
| --- | |
| ## Security Architecture | |
| ### Trust Domains (Now Separated) | |
| ``` | |
| ββ Trust Domain 1: NODE IDENTITY βββββββββ | |
| β β | |
| β node_sk (private, on node) β | |
| β node_pk (public, in sovereign/) β | |
| β Purpose: Identify the node β | |
| β Generated: Locally on each node β | |
| β β | |
| βββββββββββββββββββββββββββββββββββββββββββ | |
| ββ Trust Domain 2: AUTHORITY ββββββββββββββ | |
| β β | |
| β authority_sk (private, secure server) β | |
| β authority_pk (public, distributed) β | |
| β Purpose: Sign authorizations β | |
| β Generated: Once, on authority server β | |
| β β | |
| βββββββββββββββββββββββββββββββββββββββββββ | |
| Gate verifies using authority_pk (not node_pk) | |
| ``` | |
| ### Authorization Flow (Correct) | |
| ``` | |
| [Authority Server] | |
| β | |
| ββ Has: authority_sk (private) | |
| β | |
| ββ Signs capability with authority_sk | |
| Result: signature + canonical_json | |
| β | |
| [Node/Gate] | |
| β | |
| ββ Has: authority_pk (public) | |
| ββ Has: node_pk (local identity) | |
| β | |
| ββ Verify signature with authority_pk | |
| ββ Verify node_id matches | |
| β | |
| ββ Result: AUTHORIZED or DENIED | |
| ``` | |
| --- | |
| ## Cryptographic Properties | |
| ### Authority Authenticity | |
| - β Only authority with authority_sk can create valid signatures | |
| - β Node cannot forge authority signatures | |
| - β Ed25519 provides 128-bit security | |
| ### Payload Integrity | |
| - β Any JSON modification breaks signature | |
| - β Canonical format prevents bypass | |
| - β Sorted keys prevent collisions | |
| ### Node Binding | |
| - β Gate checks node_id matches authorization | |
| - β Capability for Node A cannot be used by Node B | |
| - β Enforced separately from signature verification | |
| ### Fail-Closed | |
| - β Missing authority key β gate fails | |
| - β Invalid signature β denied | |
| - β Modified payload β denied | |
| --- | |
| ## How to Verify | |
| ### Run Test Suite | |
| ```bash | |
| cd pax-coder | |
| bash scripts/test_authority_key_separation.sh | |
| # Expected: 8/8 tests pass | |
| # Status: EFFECTIVE | |
| ``` | |
| ### Check Key Separation | |
| ```bash | |
| # Verify keys are different: | |
| diff sovereign/authority_pk.pem sovereign/node_pk.pem | |
| # Should show differences | |
| # Verify hash values are different: | |
| sha256sum sovereign/authority_pk.pem sovereign/node_pk.pem | |
| # Different hashes confirm distinct keys | |
| ``` | |
| ### Manual Capability Test | |
| ```bash | |
| # Create test capability | |
| cat > test_cap.json << EOF | |
| { | |
| "node_id": "test-1", | |
| "release_id": "1.0.0", | |
| "commit": "abc123def456789abc123def456789abc123def4", | |
| "nonce": "test-nonce", | |
| "expires_at": "2026-12-31T23:59:59Z" | |
| } | |
| EOF | |
| # Sign with authority key | |
| bash sovereign/sign_capability.sh test_cap.json | |
| # Output: JSON|SIGNATURE (128 hex chars) | |
| ``` | |
| --- | |
| ## Deployment Checklist | |
| - [x] Authority keypair generated (separate from node keys) | |
| - [x] Authority private key secured off-repository | |
| - [x] Authority public key ready for distribution | |
| - [x] Gate updated to use authority_pk.pem | |
| - [x] All 8 security tests pass | |
| - [x] No node key used for authority verification | |
| - [x] Fail-closed behavior verified | |
| - [x] Documentation complete | |
| - [x] .gitignore updated to protect keys | |
| - [x] ADR-0010 invariants enforced | |
| --- | |
| ## Related ADRs | |
| ### ADR-0010: Public Repository vs. Production Authorization Separation | |
| - **Invariant 2:** Node Key Identity β Node Key Authorization β ENFORCED | |
| - **Status:** This fix ensures invariant is maintained | |
| ### ADR-0009: Protected Execution Capability Gate Architecture | |
| - **Part 6:** Signature Verification β CORRECTED | |
| - **Status:** Now uses authority_pk.pem (not node_pk.pem) | |
| --- | |
| ## Next Steps | |
| ### For Deployment | |
| 1. Copy `sovereign/authority_pk.pem` to all nodes | |
| ```bash | |
| cp sovereign/authority_pk.pem /etc/authority/pax-coder-authority-pk.pem | |
| ``` | |
| 2. Generate capabilities for nodes | |
| ```bash | |
| bash sovereign/sign_capability.sh capability_NODE_ID.json | |
| ``` | |
| 3. Deliver capabilities via secure channel | |
| 4. Set `PAX_CAPABILITY_TOKEN` environment variable on nodes | |
| ### For Production | |
| 1. Generate authority keypair on secure server | |
| 2. Keep authority_sk.pem off-repository (production only) | |
| 3. Distribute authority_pk.pem to all gates | |
| 4. Use sign_capability.sh to provision nodes | |
| 5. Monitor authorization logs | |
| See `docs/AUTHORITY_KEY_DEPLOYMENT.md` for complete guide. | |
| --- | |
| ## Evidence Summary | |
| | Claim | Evidence | | |
| |-------|----------| | |
| | Keys are separated | Different hash values, different content | | |
| | Gate uses authority key | Code changed from node_pk.pem to authority_pk.pem | | |
| | Authority cannot be forged | Test 2, 3, 6 pass (authority sig rejects with node key) | | |
| | Payloads cannot be modified | Test 4 passes (modified payload rejects signature) | | |
| | Node binding enforced | Test 5 passes (wrong node ID denied) | | |
| | Fail-closed behavior | Test 7, 8 pass (missing/replaced key β deny) | | |
| | Comprehensive testing | 8/8 tests pass | | |
| --- | |
| ## Status: EFFECTIVE | |
| All requirements met: | |
| - NODE_PUBLIC_KEY β AUTHORITY_PUBLIC_KEY | |
| - Gate uses authority key for verification | |
| - All 8 mandatory tests pass | |
| - ADR-0010 invariants enforced | |
| - Documentation complete | |
| The PAX-Coder authorization gate is now architecturally sound and production-ready. | |
| --- | |
| *Bel Esprit D'Accord Irrevocable Trust Β· SnapKitty West Β· Evidence or Silence β 2026* | |
| **Date:** 2026-08-18 | |
| **Verification:** All 8 tests pass (8/8) | |
| **Status:** EFFECTIVE and READY FOR PRODUCTION | |