save progress
This commit is contained in:
348
docs/modules/airgap/architecture.md
Normal file
348
docs/modules/airgap/architecture.md
Normal file
@@ -0,0 +1,348 @@
|
||||
# component_architecture_airgap.md - **Stella Ops AirGap** (2025Q4)
|
||||
|
||||
> Air-gapped deployment controller, importer, and time anchor services.
|
||||
|
||||
> **Scope.** Implementation-ready architecture for **AirGap**: the controller, importer, and time anchor subsystems enabling StellaOps operation in disconnected/air-gapped environments with sealed-mode state management.
|
||||
|
||||
---
|
||||
|
||||
## 0) Mission & boundaries
|
||||
|
||||
**Mission.** Enable **fully offline, air-gapped operation** of StellaOps with sealed-mode state management, bundle-based updates, and cryptographic time anchors for staleness detection.
|
||||
|
||||
**Boundaries.**
|
||||
|
||||
* AirGap **does not** connect to external networks in sealed mode.
|
||||
* AirGap **does not** generate vulnerability data. It imports pre-packaged bundles.
|
||||
* Bundle verification is **mandatory**. Unsigned or tampered bundles are rejected.
|
||||
* Time anchors are **cryptographically verified** using Roughtime or RFC3161.
|
||||
|
||||
---
|
||||
|
||||
## 1) Solution & project layout
|
||||
|
||||
```
|
||||
src/AirGap/
|
||||
├─ StellaOps.AirGap.Controller/ # Seal/unseal state machine, status APIs
|
||||
│ ├─ Services/
|
||||
│ │ ├─ ISealingController.cs # Sealing state interface
|
||||
│ │ ├─ SealingController.cs # State machine implementation
|
||||
│ │ └─ StatusService.cs # Health and status endpoints
|
||||
│ └─ Models/
|
||||
│ ├─ SealState.cs # sealed | unsealed | transitioning
|
||||
│ └─ SealTransition.cs # Transition metadata
|
||||
│
|
||||
├─ StellaOps.AirGap.Importer/ # Bundle verification and import
|
||||
│ ├─ Services/
|
||||
│ │ ├─ IBundleVerifier.cs # DSSE/TUF verification
|
||||
│ │ ├─ BundleVerifier.cs # Verification implementation
|
||||
│ │ ├─ ICatalogImporter.cs # Catalog update interface
|
||||
│ │ └─ CatalogImporter.cs # Import orchestration
|
||||
│ └─ Models/
|
||||
│ ├─ ImportBundle.cs # Bundle metadata
|
||||
│ └─ ImportResult.cs # Import outcome
|
||||
│
|
||||
├─ StellaOps.AirGap.Time/ # Time anchor verification
|
||||
│ ├─ Services/
|
||||
│ │ ├─ ITimeAnchorService.cs # Time anchor interface
|
||||
│ │ ├─ RoughtimeAnchor.cs # Roughtime implementation
|
||||
│ │ └─ Rfc3161Anchor.cs # RFC3161 timestamp
|
||||
│ └─ Models/
|
||||
│ ├─ TimeAnchor.cs # Anchor record
|
||||
│ └─ StalenessResult.cs # Staleness calculation
|
||||
│
|
||||
├─ StellaOps.AirGap.Policy/ # Air-gap specific policy rules
|
||||
│ ├─ StellaOps.AirGap.Policy/
|
||||
│ ├─ StellaOps.AirGap.Policy.Analyzers/
|
||||
│ └─ StellaOps.AirGap.Policy.Tests/
|
||||
│
|
||||
├─ __Libraries/
|
||||
│ ├─ StellaOps.AirGap.Bundle/ # Bundle format and parsing
|
||||
│ └─ StellaOps.AirGap.Persistence/ # State persistence
|
||||
│
|
||||
├─ __Tests/ # Test projects
|
||||
│
|
||||
├─ scripts/ # Operational scripts
|
||||
│
|
||||
└─ AGENTS.md # Guild charter
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2) External dependencies
|
||||
|
||||
* **PostgreSQL** - State persistence, import history
|
||||
* **Authority** - Scope enforcement (`airgap:seal`, `airgap:status:read`)
|
||||
* **Cryptography** - Bundle signature verification
|
||||
* **Object storage** - Bundle staging and quarantine
|
||||
|
||||
---
|
||||
|
||||
## 3) Contracts & data model
|
||||
|
||||
### 3.1 Seal State
|
||||
|
||||
```csharp
|
||||
public enum SealState
|
||||
{
|
||||
Unsealed, // Normal operation, network allowed
|
||||
Transitioning, // Sealing or unsealing in progress
|
||||
Sealed // Air-gapped, no network egress
|
||||
}
|
||||
|
||||
public sealed record SealStatus
|
||||
{
|
||||
public required SealState State { get; init; }
|
||||
public required DateTimeOffset LastTransition { get; init; }
|
||||
public required string TransitionedBy { get; init; }
|
||||
public DateTimeOffset? SealedSince { get; init; }
|
||||
public TimeAnchor? LastTimeAnchor { get; init; }
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 Import Bundle
|
||||
|
||||
```json
|
||||
{
|
||||
"bundleId": "airgap-2025-01-15-abc123",
|
||||
"bundleType": "advisory-update",
|
||||
"version": "2025.01.15.001",
|
||||
"createdAt": "2025-01-15T10:30:00Z",
|
||||
"contents": [
|
||||
{
|
||||
"type": "concelier-snapshot",
|
||||
"digest": "sha256:abc123...",
|
||||
"path": "data/concelier-2025-01-15.tar.zst"
|
||||
},
|
||||
{
|
||||
"type": "trivy-db",
|
||||
"digest": "sha256:def456...",
|
||||
"path": "data/trivy-db-2025-01-15.tar.gz"
|
||||
}
|
||||
],
|
||||
"signature": {
|
||||
"keyId": "sha256:sigkey...",
|
||||
"algorithm": "ecdsa-p256",
|
||||
"value": "base64..."
|
||||
},
|
||||
"timeAnchor": {
|
||||
"source": "roughtime",
|
||||
"timestamp": "2025-01-15T10:25:00Z",
|
||||
"proof": "base64..."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 Time Anchor
|
||||
|
||||
```csharp
|
||||
public sealed record TimeAnchor
|
||||
{
|
||||
public required string Source { get; init; } // roughtime, rfc3161
|
||||
public required DateTimeOffset Timestamp { get; init; }
|
||||
public required byte[] Proof { get; init; } // Cryptographic proof
|
||||
public required string[] Servers { get; init; } // Servers used
|
||||
public required bool Verified { get; init; }
|
||||
}
|
||||
|
||||
public sealed record StalenessResult
|
||||
{
|
||||
public required TimeSpan Age { get; init; }
|
||||
public required bool IsStale { get; init; }
|
||||
public required TimeSpan StalenessThreshold { get; init; }
|
||||
public string? Warning { get; init; }
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4) REST API (Controller + Importer)
|
||||
|
||||
All under `/api/v1/airgap`. Auth: **OpTok** with airgap scopes.
|
||||
|
||||
### Controller APIs
|
||||
|
||||
```
|
||||
GET /status → { state, lastTransition, timeAnchor }
|
||||
POST /seal → { transitionId, status: "transitioning" }
|
||||
POST /unseal → { transitionId, status: "transitioning" }
|
||||
GET /transitions/{id} → { transition details }
|
||||
```
|
||||
|
||||
### Importer APIs
|
||||
|
||||
```
|
||||
POST /bundles/upload multipart → { bundleId, status: "pending" }
|
||||
POST /bundles/{id}/verify → { valid: bool, details }
|
||||
POST /bundles/{id}/import → { importId, status: "importing" }
|
||||
GET /bundles/{id}/status → { status, progress, errors }
|
||||
GET /bundles → { bundles: BundleSummary[] }
|
||||
```
|
||||
|
||||
### Time APIs
|
||||
|
||||
```
|
||||
GET /time/anchor → { anchor: TimeAnchor, staleness }
|
||||
POST /time/anchor { source, proof } → { anchor, verified }
|
||||
GET /time/staleness → { staleness: StalenessResult }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5) Configuration (YAML)
|
||||
|
||||
```yaml
|
||||
AirGap:
|
||||
Controller:
|
||||
InitialState: "unsealed"
|
||||
TransitionTimeoutSeconds: 300
|
||||
RequireApproval: true
|
||||
|
||||
Importer:
|
||||
StagingPath: "/data/airgap/staging"
|
||||
QuarantinePath: "/data/airgap/quarantine"
|
||||
MaxBundleSizeMb: 10240
|
||||
TrustRoots:
|
||||
- "sha256:abc123..." # StellaOps signing key
|
||||
AllowedBundleTypes:
|
||||
- "advisory-update"
|
||||
- "trivy-db"
|
||||
- "policy-pack"
|
||||
|
||||
Time:
|
||||
StalenessThresholdHours: 168 # 7 days
|
||||
RoughtimeServers:
|
||||
- "roughtime.cloudflare.com"
|
||||
- "roughtime.google.com"
|
||||
Rfc3161Servers:
|
||||
- "http://timestamp.digicert.com"
|
||||
RequireMultipleServers: true
|
||||
MinServerQuorum: 2
|
||||
|
||||
Quarantine:
|
||||
TtlDays: 30
|
||||
MaxQuotaMb: 51200
|
||||
|
||||
Postgres:
|
||||
ConnectionString: "Host=postgres;Database=airgap;..."
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6) Sealing State Machine
|
||||
|
||||
```
|
||||
┌──────────────┐
|
||||
│ Unsealed │
|
||||
└──────┬───────┘
|
||||
│ seal()
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ Transitioning│
|
||||
└──────┬───────┘
|
||||
│ complete
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ Sealed │
|
||||
└──────┬───────┘
|
||||
│ unseal()
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ Transitioning│
|
||||
└──────┬───────┘
|
||||
│ complete
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ Unsealed │
|
||||
└──────────────┘
|
||||
```
|
||||
|
||||
### Transition Actions
|
||||
|
||||
**Seal transition:**
|
||||
1. Verify pending work is complete
|
||||
2. Capture final time anchor
|
||||
3. Disable network egress
|
||||
4. Update state to Sealed
|
||||
|
||||
**Unseal transition:**
|
||||
1. Verify network connectivity
|
||||
2. Refresh time anchor
|
||||
3. Enable network egress
|
||||
4. Update state to Unsealed
|
||||
|
||||
---
|
||||
|
||||
## 7) Bundle Import Flow
|
||||
|
||||
```
|
||||
1. Upload bundle to staging
|
||||
└─ Validate manifest structure
|
||||
|
||||
2. Verify bundle
|
||||
├─ Check signature against trust roots
|
||||
├─ Verify content digests
|
||||
└─ Validate time anchor
|
||||
|
||||
3. Import bundle
|
||||
├─ Extract contents
|
||||
├─ Update target catalogs (Concelier, Trivy, etc.)
|
||||
└─ Record import in history
|
||||
|
||||
4. Cleanup or quarantine
|
||||
├─ Success: Remove from staging
|
||||
└─ Failure: Move to quarantine with TTL
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8) Security & compliance
|
||||
|
||||
* **Signature verification**: All bundles must be signed
|
||||
* **Trust roots**: Configurable trust root keys
|
||||
* **Quarantine**: Failed imports isolated with TTL
|
||||
* **Audit trail**: All imports and state changes logged
|
||||
* **Scope enforcement**: Authority scopes for all operations
|
||||
* **Rollback prevention**: Version monotonicity enforced
|
||||
|
||||
---
|
||||
|
||||
## 9) Performance targets
|
||||
|
||||
* **Seal/unseal transition**: < 30s
|
||||
* **Bundle verification**: < 10s for 1GB bundle
|
||||
* **Bundle import**: < 60s for typical advisory update
|
||||
* **Time anchor verification**: < 5s
|
||||
|
||||
---
|
||||
|
||||
## 10) Observability
|
||||
|
||||
**Metrics:**
|
||||
* `airgap.state{state=sealed|unsealed|transitioning}`
|
||||
* `airgap.bundles.imported_total{type,result}`
|
||||
* `airgap.bundles.quarantined_total{reason}`
|
||||
* `airgap.time.staleness_seconds`
|
||||
* `airgap.time.anchor_age_seconds`
|
||||
|
||||
**Tracing:** Spans for transitions, imports, verifications.
|
||||
|
||||
---
|
||||
|
||||
## 11) Testing matrix
|
||||
|
||||
* **Seal/unseal tests**: State machine transitions
|
||||
* **Bundle tests**: Verification and import flows
|
||||
* **Quarantine tests**: Failed import handling
|
||||
* **Time tests**: Staleness calculations, anchor verification
|
||||
* **Integration tests**: Full offline workflow simulation
|
||||
|
||||
---
|
||||
|
||||
## Related Documentation
|
||||
|
||||
* Evidence reconciliation: `./evidence-reconciliation.md`
|
||||
* Exporter coordination: `./exporter-cli-coordination.md`
|
||||
* Mirror DSSE plan: `./mirror-dsse-plan.md`
|
||||
* Offline Kit: `../../24_OFFLINE_KIT.md`
|
||||
* Time anchor schema: `../../airgap/time-anchor-schema.md`
|
||||
Reference in New Issue
Block a user