Skip to content

Commit 59b2cb6

Browse files
committed
Init chelon repo
Signed-off-by: Scott R. Shinn <scott@atomicorp.com>
0 parents  commit 59b2cb6

13 files changed

Lines changed: 1582 additions & 0 deletions

ARCHITECTURE.md

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
# Blind Oracle: Remote Package Signing Service
2+
3+
## Overview
4+
The Blind Oracle is a secure, remote signing service that holds GPG private keys and signs RPM packages and repository metadata on behalf of build servers. Build servers never have access to private keys, significantly reducing the attack surface.
5+
6+
## Architecture
7+
8+
### Components
9+
10+
```
11+
┌─────────────────────────────────────────────────────────────┐
12+
│ Build Server (GitLab Runner) │
13+
│ │
14+
│ ┌──────────────┐ ┌─────────────────────────────────┐ │
15+
│ │ gitlab-build │─────▶│ sign-package.sh │ │
16+
│ │ -4.sh │ │ (Client Mode) │ │
17+
│ └──────────────┘ └─────────────────────────────────┘ │
18+
│ │ │
19+
│ │ HTTPS POST │
20+
│ │ {hash, dist, key_type} │
21+
└─────────────────────────────────┼────────────────────────────┘
22+
23+
24+
┌─────────────────────────────────────────────────────────────┐
25+
│ Blind Oracle Server │
26+
│ │
27+
│ ┌─────────────────────────────────────────────────────┐ │
28+
│ │ HTTP API (Flask/FastAPI) │ │
29+
│ │ - POST /sign/rpm │ │
30+
│ │ - POST /sign/repodata │ │
31+
│ │ - GET /health │ │
32+
│ └─────────────────────────────────────────────────────┘ │
33+
│ │ │
34+
│ ▼ │
35+
│ ┌─────────────────────────────────────────────────────┐ │
36+
│ │ Signing Engine │ │
37+
│ │ - Key selection (Legacy/Modern) │ │
38+
│ │ - GPG signing operations │ │
39+
│ │ - Audit logging │ │
40+
│ └─────────────────────────────────────────────────────┘ │
41+
│ │ │
42+
│ ▼ │
43+
│ ┌─────────────────────────────────────────────────────┐ │
44+
│ │ GPG Keyring (Offline Storage) │ │
45+
│ │ - Legacy Key (4520AFA9) │ │
46+
│ │ - Modern Key (CB2C73F04F3BE076) │ │
47+
│ │ - Passphrases in secure vault │ │
48+
│ └─────────────────────────────────────────────────────┘ │
49+
└─────────────────────────────────────────────────────────────┘
50+
```
51+
52+
## Security Model
53+
54+
### Threat Mitigation
55+
1. **Build Server Compromise**: Private keys never leave the Oracle
56+
2. **Network Interception**: HTTPS + API token authentication
57+
3. **Unauthorized Signing**: Token-based access control + audit logs
58+
4. **Key Compromise**: Master key offline, only signing subkeys on Oracle
59+
60+
### Authentication
61+
- API tokens per build server
62+
- Token rotation capability
63+
- Rate limiting per token
64+
65+
### Audit Trail
66+
- All signing requests logged with:
67+
- Timestamp
68+
- Requesting server (token ID)
69+
- Package hash
70+
- Key used
71+
- Success/failure
72+
73+
## API Specification
74+
75+
### POST /sign/rpm
76+
Sign an RPM package.
77+
78+
**Request:**
79+
```json
80+
{
81+
"package_hash": "sha256:abc123...",
82+
"distribution": "el10-x86_64",
83+
"key_type": "modern",
84+
"token": "secret-api-token"
85+
}
86+
```
87+
88+
**Response:**
89+
```json
90+
{
91+
"signature": "-----BEGIN PGP SIGNATURE-----...",
92+
"key_id": "CB2C73F04F3BE076",
93+
"timestamp": "2026-01-06T11:25:00Z"
94+
}
95+
```
96+
97+
### POST /sign/repodata
98+
Sign repository metadata (repomd.xml).
99+
100+
**Request:**
101+
```json
102+
{
103+
"repodata_hash": "sha256:def456...",
104+
"key_type": "modern",
105+
"token": "secret-api-token"
106+
}
107+
```
108+
109+
**Response:**
110+
```json
111+
{
112+
"signature": "-----BEGIN PGP SIGNATURE-----...",
113+
"key_id": "CB2C73F04F3BE076",
114+
"timestamp": "2026-01-06T11:25:00Z"
115+
}
116+
```
117+
118+
## Implementation Phases
119+
120+
### Phase 1: Local Prototype (Current)
121+
-`sign-package.sh` uses local GPG keys
122+
- ✅ Dual key selection logic
123+
- ✅ Deployed to GitLab runners
124+
125+
### Phase 2: Oracle Server (Next)
126+
- [ ] Create Flask/FastAPI service
127+
- [ ] Implement signing endpoints
128+
- [ ] Add authentication/authorization
129+
- [ ] Deploy to secure server
130+
- [ ] Audit logging
131+
132+
### Phase 3: Client Integration
133+
- [ ] Update `sign-package.sh` to detect Oracle mode
134+
- [ ] Implement HTTP client for signing requests
135+
- [ ] Fallback to local signing if Oracle unavailable
136+
- [ ] Token management
137+
138+
### Phase 4: Production Hardening
139+
- [ ] HTTPS with mutual TLS
140+
- [ ] Hardware Security Module (HSM) integration
141+
- [ ] High availability / redundancy
142+
- [ ] Monitoring and alerting
143+
- [ ] Key rotation automation
144+
145+
## Deployment Model
146+
147+
### Development/Testing
148+
- Oracle runs on `winona7` (local development)
149+
- Build servers use API token for testing
150+
151+
### Production
152+
- Oracle runs on dedicated, hardened server
153+
- Firewall rules: Only GitLab runners can access
154+
- Private keys stored in encrypted volume
155+
- Regular backups of audit logs
156+
157+
## File Structure
158+
```
159+
blind-oracle/
160+
├── ARCHITECTURE.md # This file
161+
├── SIGNING_STRATEGY.md # GPG key strategy (existing)
162+
├── server/
163+
│ ├── oracle-service.py # Main Flask/FastAPI app
164+
│ ├── signing_engine.py # GPG signing logic
165+
│ ├── auth.py # Token authentication
166+
│ ├── audit.py # Audit logging
167+
│ └── requirements.txt # Python dependencies
168+
├── client/
169+
│ ├── sign-package.sh # Updated with Oracle support
170+
│ └── oracle-client.py # Python client library
171+
├── deployment/
172+
│ ├── systemd/
173+
│ │ └── oracle.service # Systemd unit file
174+
│ ├── nginx/
175+
│ │ └── oracle.conf # Nginx reverse proxy config
176+
│ └── docker/
177+
│ └── Dockerfile # Container image
178+
└── tests/
179+
├── test_signing.py # Unit tests
180+
└── test_integration.py # Integration tests
181+
```
182+
183+
## Next Steps
184+
1. Implement basic Flask service with `/sign/rpm` endpoint
185+
2. Create Python signing engine using `gpg` library
186+
3. Update `sign-package.sh` to support Oracle mode
187+
4. Test end-to-end signing workflow
188+
5. Add authentication and audit logging

0 commit comments

Comments
 (0)