File size: 5,060 Bytes
ef6eb55
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# ADR-0004: Private Key Separation

**Status:** Accepted  
**Date:** 2026-08-18  
**Author:** SNAPKITTYWEST PAX-Coder Security Team

---

## Context

The Sovereign Node private key is the most sensitive cryptographic material in the system. It signs official releases, establishes prior-art timestamps, and proves PAX-Coder provenance.

If the private key is distributed to the public clone, assume it can eventually be extracted:
- Reversed from binaries
- Dumped from memory
- Recovered from CUDA/.so/.pyd files
- Extracted from encrypted constants

## Decision

The private Sovereign Node key MUST:

1. **Never be committed to git** β€” .gitignore enforces this
2. **Never be distributed in releases** β€” Only public key is published
3. **Never be embedded in binaries** β€” No compiled constants
4. **Never be in encrypted secrets** β€” No key-derivation in code
5. **Never be in environment variables** β€” Except for signing operations in secure environments

The public clone must contain ONLY:

```

node ID

public key (PEM)

public key fingerprint

release signatures

verification metadata

prior-art timestamps

```

The private key is held ONLY by the release signer and protected by access controls.

## Rules

```yaml

rules:

  - private Sovereign Node key MUST NOT be committed to git

  - private key MUST NOT appear in releases

  - private key MUST NOT be distributed in source tarballs

  - private key MUST NOT be embedded in binaries

  - private key MUST NOT be derived from environment configuration

  - private key MUST NOT be recoverable from public cryptographic material

  - .gitignore MUST explicitly block all private-key patterns

  - CI MUST scan for accidentally committed private keys

  - CI MUST reject commits containing private-key patterns

```

## Protected Patterns

CI MUST reject commits matching:

```

-----BEGIN.*PRIVATE

-----END.*PRIVATE

-----BEGIN.*KEY

-----BEGIN.*RSA

-----BEGIN.*EC

-----BEGIN.*OPENSSH

private_key.*=

secret_key.*=

PRIVATE_KEY.*=

AWS_SECRET_ACCESS_KEY

AZURE_CLIENT_SECRET

api_key.*secret

```

## Public Material Only

The clone MUST contain:

```

sovereign/node.json

  β”œβ”€ node_id

  β”œβ”€ algorithm

  β”œβ”€ public_key_hex

  β”œβ”€ created_at_utc

  β”œβ”€ repository

  β”œβ”€ git_commit

  └─ version



sovereign/node_pk.pem

  └─ [Public key in PEM format]



sovereign/release.json

  β”œβ”€ node_id

  β”œβ”€ node_public_key_hex

  β”œβ”€ signature_hex (signed by private key, but signature is public)

  β”œβ”€ git_commit

  β”œβ”€ release_version

  β”œβ”€ manifest_sha256

  └─ timestamp_utc



sovereign/manifest-*.json

  └─ [File hashes and release metadata]

```

MUST NOT contain:

```

.node_sk (private key binary)

node_sk.pem (private key PEM)

Any file with private key material

Any encrypted constants used to recover the key

```

## Key Storage & Management

Release signing happens in a secure environment:

```

Offline Environment

  β”œβ”€ private_key.pem

  β”œβ”€ git clone

  β”œβ”€ sovereign/generate_release.sh

  └─ Sign release

       β”œβ”€ Hash manifest

       β”œβ”€ Sign hash with private key

       └─ Generate release.json

```

The public release artifact contains:

```

release.json (public)

  β”œβ”€ public key

  β”œβ”€ signature (hex)

  β”œβ”€ manifest hash

  └─ timestamp

```

The private key is NOT transmitted or stored in the public repository.

## Key Rotation

When rotating to a new private key:

1. Generate new Sovereign Node key
2. Create rotation record with old public key signature
3. Document reason and timestamp
4. Do NOT delete old public key (preserve release history)
5. Mark old key as superseded

```yaml

rotation:

  old_node_id: pax-coder-1787047913

  new_node_id: pax-coder-1787048999

  rotation_reason: scheduled rotation

  rotation_timestamp: 2026-12-18T00:00:00Z

  signature_by_old_key: ...

```

## Tests Required

- `test_no_private_keys_in_repo`: Scan for accidentally committed keys
- `test_no_embedded_secrets`: Scan binaries for hardcoded keys
- `test_public_key_only_distribution`: Verify releases contain only public material
- `test_gitignore_coverage`: Verify all private-key patterns are ignored
- `test_ci_rejects_private_keys`: Verify CI blocks key commits

## CI Gate

```bash

#!/bin/bash

# Pre-commit hook

git diff --cached --name-only | xargs -I {} bash -c '

  if grep -l "PRIVATE\|BEGIN.*KEY\|secret_key" {} 2>/dev/null; then

    echo "ERROR: Private key material detected in: {}"

    exit 1

  fi

'

```

## Consequences

- Private key never leaks through version control
- Public clone contains only verifiable public material
- Key rotation does not break release history
- Compromise of one key does not affect other releases
- Private key management is manual and external to the repository

---

**Related ADRs:**
- ADR-0001: Public Clone Integrity
- ADR-0002: Authorization Boundary
- ADR-0006: Server Challenge Protocol