Files
git.stella-ops.org/docs/airgap/symbol-bundles.md
StellaOps Bot 233873f620
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Signals CI & Image / signals-ci (push) Has been cancelled
Signals Reachability Scoring & Events / reachability-smoke (push) Has been cancelled
Signals Reachability Scoring & Events / sign-and-upload (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Reachability Corpus Validation / validate-corpus (push) Has been cancelled
Reachability Corpus Validation / validate-ground-truths (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Reachability Corpus Validation / determinism-check (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled
Notify Smoke Test / Notify Unit Tests (push) Has been cancelled
Notify Smoke Test / Notifier Service Tests (push) Has been cancelled
Notify Smoke Test / Notification Smoke Test (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
up
2025-12-14 15:50:38 +02:00

317 lines
8.1 KiB
Markdown

# Symbol Bundles for Air-Gapped Installations
**Reference:** SYMS-BUNDLE-401-014
This document describes how to create, verify, and deploy deterministic symbol bundles for air-gapped StellaOps installations.
## Overview
Symbol bundles package debug symbols (PDBs, DWARF, etc.) into a single archive with:
- **Deterministic ordering** for reproducible builds
- **BLAKE3 hashes** for content verification
- **DSSE signatures** for authenticity
- **Rekor checkpoints** for transparency log integration
- **Merkle inclusion proofs** for offline verification
## Bundle Structure
```
bundle-name-1.0.0.symbols.zip
├── manifest.json # Bundle manifest with all metadata
├── symbols/
│ ├── {debug-id-1}/
│ │ ├── myapp.exe.symbols # Symbol blob
│ │ └── myapp.exe.symbols.json # Symbol manifest
│ ├── {debug-id-2}/
│ │ ├── libcrypto.so.symbols
│ │ └── libcrypto.so.symbols.json
│ └── ...
```
## Creating a Bundle
### Prerequisites
1. Collect symbol manifests from CI builds or ingest tools
2. Ensure all manifests follow the `*.symbols.json` naming convention
3. Have signing keys available (if signing is required)
### Build Command
```bash
# Basic bundle creation
stella symbols bundle \
--name "product-symbols" \
--version "1.0.0" \
--source ./symbols-dir \
--output ./bundles
# With signing and Rekor submission
stella symbols bundle \
--name "product-symbols" \
--version "1.0.0" \
--source ./symbols-dir \
--output ./bundles \
--sign \
--key ./signing-key.pem \
--key-id "release-key-2025" \
--rekor \
--rekor-url https://rekor.sigstore.dev
# Filter by platform
stella symbols bundle \
--name "linux-symbols" \
--version "1.0.0" \
--source ./symbols-dir \
--output ./bundles \
--platform linux-x64
```
### Bundle Options
| Option | Description |
|--------|-------------|
| `--name` | Bundle name (required) |
| `--version` | Bundle version in SemVer format (required) |
| `--source` | Source directory containing symbol manifests (required) |
| `--output` | Output directory for bundle archive (required) |
| `--platform` | Filter symbols by platform (e.g., linux-x64, win-x64) |
| `--tenant` | Filter symbols by tenant ID |
| `--sign` | Sign bundle with DSSE |
| `--key` | Path to signing key (PEM-encoded private key) |
| `--key-id` | Key ID for DSSE signature |
| `--algorithm` | Signing algorithm (ecdsa-p256, ed25519, rsa-pss-sha256) |
| `--rekor` | Submit to Rekor transparency log |
| `--rekor-url` | Rekor server URL |
| `--format` | Archive format: zip (default) or tar.gz |
| `--compression` | Compression level (0-9, default: 6) |
## Verifying a Bundle
### Online Verification
```bash
stella symbols verify --bundle ./product-symbols-1.0.0.symbols.zip
```
### Offline Verification
For air-gapped environments, include the Rekor public key:
```bash
stella symbols verify \
--bundle ./product-symbols-1.0.0.symbols.zip \
--public-key ./signing-public-key.pem \
--rekor-offline \
--rekor-key ./rekor-public-key.pem
```
### Verification Output
```
Bundle verification successful!
Bundle ID: a1b2c3d4e5f6g7h8
Name: product-symbols-1.0.0.symbols
Version: 1.0.0
Signature: valid (ecdsa-p256)
Hash verification: 42/42 valid
```
## Extracting Symbols
### Full Extraction
```bash
stella symbols extract \
--bundle ./product-symbols-1.0.0.symbols.zip \
--output ./extracted-symbols
```
### Platform-Filtered Extraction
```bash
stella symbols extract \
--bundle ./product-symbols-1.0.0.symbols.zip \
--output ./linux-symbols \
--platform linux-x64
```
### Manifests Only
```bash
stella symbols extract \
--bundle ./product-symbols-1.0.0.symbols.zip \
--output ./manifests-only \
--manifests-only
```
## Inspecting Bundles
```bash
# Basic info
stella symbols inspect --bundle ./product-symbols-1.0.0.symbols.zip
# With entry listing
stella symbols inspect --bundle ./product-symbols-1.0.0.symbols.zip --entries
```
## Bundle Manifest Schema
The bundle manifest (`manifest.json`) follows this schema:
```json
{
"schemaVersion": "stellaops.symbols.bundle/v1",
"bundleId": "blake3-hash-of-content",
"name": "product-symbols",
"version": "1.0.0",
"createdAt": "2025-12-14T10:30:00Z",
"platform": null,
"tenantId": null,
"entries": [
{
"debugId": "abc123def456",
"codeId": "...",
"binaryName": "myapp.exe",
"platform": "win-x64",
"format": "pe",
"manifestHash": "blake3...",
"blobHash": "blake3...",
"blobSizeBytes": 102400,
"archivePath": "symbols/abc123def456/myapp.exe.symbols",
"symbolCount": 5000
}
],
"totalSizeBytes": 10485760,
"signature": {
"signed": true,
"algorithm": "ecdsa-p256",
"keyId": "release-key-2025",
"dsseDigest": "sha256:...",
"signedAt": "2025-12-14T10:30:00Z",
"publicKey": "-----BEGIN PUBLIC KEY-----..."
},
"rekorCheckpoint": {
"rekorUrl": "https://rekor.sigstore.dev",
"logEntryId": "...",
"logIndex": 12345678,
"integratedTime": "2025-12-14T10:30:01Z",
"rootHash": "sha256:...",
"treeSize": 987654321,
"inclusionProof": {
"logIndex": 12345678,
"rootHash": "sha256:...",
"treeSize": 987654321,
"hashes": ["sha256:...", "sha256:..."]
},
"logPublicKey": "-----BEGIN PUBLIC KEY-----..."
},
"hashAlgorithm": "blake3"
}
```
## Air-Gap Deployment Workflow
### 1. Create Bundle (Online Environment)
```bash
# On the online build server
stella symbols bundle \
--name "release-v2.0.0-symbols" \
--version "2.0.0" \
--source /build/symbols \
--output /export \
--sign --key /keys/release.pem \
--rekor
```
### 2. Transfer to Air-Gapped Environment
Copy the following files to the air-gapped environment:
- `release-v2.0.0-symbols-2.0.0.symbols.zip`
- `release-v2.0.0-symbols-2.0.0.manifest.json`
- `signing-public-key.pem` (if not already present)
- `rekor-public-key.pem` (for Rekor offline verification)
### 3. Verify (Air-Gapped Environment)
```bash
# On the air-gapped server
stella symbols verify \
--bundle ./release-v2.0.0-symbols-2.0.0.symbols.zip \
--public-key ./signing-public-key.pem \
--rekor-offline \
--rekor-key ./rekor-public-key.pem
```
### 4. Extract and Deploy
```bash
# Extract to symbols server directory
stella symbols extract \
--bundle ./release-v2.0.0-symbols-2.0.0.symbols.zip \
--output /var/stellaops/symbols \
--verify
```
## Determinism Guarantees
Symbol bundles are deterministic:
1. **Entry ordering**: Entries sorted by debug ID, then binary name (lexicographic)
2. **Hash algorithm**: BLAKE3 for all content hashes
3. **Timestamps**: UTC ISO-8601 format
4. **JSON serialization**: Canonical form (no whitespace, sorted keys)
5. **Archive entries**: Sorted by path within archive
This ensures that given the same input manifests, the same bundle (excluding signatures) is produced.
## CI Integration
### GitHub Actions Example
```yaml
- name: Build symbol bundle
run: |
stella symbols bundle \
--name "${{ github.repository }}-symbols" \
--version "${{ github.ref_name }}" \
--source ./build/symbols \
--output ./dist \
--sign --key ${{ secrets.SIGNING_KEY }} \
--rekor
- name: Upload bundle artifact
uses: actions/upload-artifact@v4
with:
name: symbol-bundle
path: ./dist/*.symbols.zip
```
## Troubleshooting
### "No symbol manifests found"
Ensure manifests follow the `*.symbols.json` naming convention and are not DSSE envelopes (`*.dsse.json`).
### "Signature verification failed"
Check that:
1. The public key matches the signing key
2. The bundle has not been modified after signing
3. The key ID matches what was used during signing
### "Rekor inclusion proof invalid"
For offline verification:
1. Ensure the Rekor public key is current
2. The checkpoint was created when the log was online
3. The tree size hasn't changed since the checkpoint
## Related Documentation
- [Offline Kit Guide](../24_OFFLINE_KIT.md)
- [Symbol Server Architecture](../modules/scanner/architecture.md)
- [DSSE Signing Guide](../modules/signer/architecture.md)
- [Rekor Integration](../modules/attestor/architecture.md)