Files
git.stella-ops.org/docs/modules/vexlens/operations/deployment.md
StellaOps Bot efd6850c38 Add unit tests for VexLens normalizer, CPE parser, product mapper, and PURL parser
- Implemented comprehensive tests for VexLensNormalizer including format detection and normalization scenarios.
- Added tests for CpeParser covering CPE 2.3 and 2.2 formats, invalid inputs, and canonical key generation.
- Created tests for ProductMapper to validate parsing and matching logic across different strictness levels.
- Developed tests for PurlParser to ensure correct parsing of various PURL formats and validation of identifiers.
- Introduced stubs for Monaco editor and worker to facilitate testing in the web application.
- Updated project file for the test project to include necessary dependencies.
2025-12-06 16:28:12 +02:00

476 lines
10 KiB
Markdown

# VexLens Deployment Runbook
> Operational runbook for deploying and configuring VexLens consensus engine.
---
## 1) Prerequisites
### 1.1 Infrastructure Requirements
| Component | Requirement | Notes |
|-----------|-------------|-------|
| Runtime | .NET 10.0+ | LTS recommended |
| Database | MongoDB 6.0+ | For projections and issuer directory |
| Cache | Redis 7.0+ (optional) | For caching consensus results |
| Memory | 512MB minimum | 2GB recommended for production |
| CPU | 2 cores minimum | 4 cores for high throughput |
### 1.2 Dependencies
- **Excititor**: VEX document ingestion service
- **Authority**: OIDC token validation
- **Policy Engine**: (optional) For VEX-aware policy evaluation
---
## 2) Configuration
### 2.1 Environment Variables
```bash
# Core Settings
VEXLENS_CONSENSUS_DEFAULT_MODE=WeightedVote
VEXLENS_CONSENSUS_MINIMUM_CONFIDENCE=0.1
VEXLENS_CONSENSUS_CONFLICT_THRESHOLD=0.3
# Trust Settings
VEXLENS_TRUST_FRESHNESS_HALFLIFE_DAYS=90
VEXLENS_TRUST_MINIMUM_FRESHNESS=0.3
VEXLENS_TRUST_ALLOW_UNSIGNED=true
VEXLENS_TRUST_UNSIGNED_PENALTY=0.3
VEXLENS_TRUST_ALLOW_UNKNOWN_ISSUERS=true
VEXLENS_TRUST_UNKNOWN_ISSUER_PENALTY=0.5
# Storage
VEXLENS_STORAGE_MONGODB_CONNECTION_STRING=mongodb://localhost:27017
VEXLENS_STORAGE_MONGODB_DATABASE=vexlens
VEXLENS_STORAGE_PROJECTION_RETENTION_DAYS=365
VEXLENS_STORAGE_EVENT_RETENTION_DAYS=90
# Issuer Directory
VEXLENS_ISSUER_DIRECTORY_SOURCE=mongodb
VEXLENS_ISSUER_DIRECTORY_REFRESH_INTERVAL_MINUTES=60
# Observability
VEXLENS_OTEL_EXPORTER_ENDPOINT=http://otel-collector:4317
VEXLENS_OTEL_SERVICE_NAME=vexlens
```
### 2.2 Configuration File (vexlens.yaml)
```yaml
vexlens:
consensus:
defaultMode: WeightedVote
minimumConfidence: 0.1
conflictThreshold: 0.3
requireJustificationForNotAffected: false
trust:
freshnessHalfLifeDays: 90
minimumFreshness: 0.3
allowUnsigned: true
unsignedPenalty: 0.3
allowUnknownIssuers: true
unknownIssuerPenalty: 0.5
factorWeights:
IssuerBase: 0.25
SignatureStatus: 0.15
Freshness: 0.15
IssuerCategory: 0.10
IssuerTier: 0.10
StatusQuality: 0.10
TransparencyLog: 0.05
SourceMatch: 0.05
ProductAuthority: 0.05
storage:
mongodb:
connectionString: mongodb://localhost:27017
database: vexlens
projectionsCollection: consensus_projections
issuersCollection: issuers
projectionRetentionDays: 365
eventRetentionDays: 90
issuerDirectory:
source: mongodb
refreshIntervalMinutes: 60
seedFile: /etc/vexlens/issuers.json
observability:
metrics:
enabled: true
exporterEndpoint: http://otel-collector:4317
tracing:
enabled: true
samplingRatio: 0.1
logging:
level: Information
format: json
```
---
## 3) Deployment Steps
### 3.1 Docker Deployment
```bash
# Pull the image
docker pull stellaops/vexlens:latest
# Run with configuration
docker run -d \
--name vexlens \
-p 8080:8080 \
-v /etc/vexlens:/etc/vexlens:ro \
-e VEXLENS_STORAGE_MONGODB_CONNECTION_STRING=mongodb://mongo:27017 \
stellaops/vexlens:latest
```
### 3.2 Kubernetes Deployment
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: vexlens
namespace: stellaops
spec:
replicas: 2
selector:
matchLabels:
app: vexlens
template:
metadata:
labels:
app: vexlens
spec:
containers:
- name: vexlens
image: stellaops/vexlens:latest
ports:
- containerPort: 8080
env:
- name: VEXLENS_STORAGE_MONGODB_CONNECTION_STRING
valueFrom:
secretKeyRef:
name: vexlens-secrets
key: mongodb-connection-string
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "2Gi"
cpu: "2000m"
livenessProbe:
httpGet:
path: /health/live
port: 8080
initialDelaySeconds: 10
periodSeconds: 30
readinessProbe:
httpGet:
path: /health/ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
volumeMounts:
- name: config
mountPath: /etc/vexlens
readOnly: true
volumes:
- name: config
configMap:
name: vexlens-config
---
apiVersion: v1
kind: Service
metadata:
name: vexlens
namespace: stellaops
spec:
selector:
app: vexlens
ports:
- port: 80
targetPort: 8080
```
### 3.3 Helm Deployment
```bash
helm install vexlens stellaops/vexlens \
--namespace stellaops \
--set mongodb.connectionString=mongodb://mongo:27017 \
--set replicas=2 \
--set resources.requests.memory=512Mi \
--set resources.limits.memory=2Gi
```
---
## 4) Issuer Directory Setup
### 4.1 Seed Issuers File
Create `/etc/vexlens/issuers.json`:
```json
{
"issuers": [
{
"issuerId": "npm-security",
"name": "npm Security Team",
"category": "Vendor",
"trustTier": "Authoritative",
"keyFingerprints": [
{
"fingerprint": "ABCD1234EFGH5678",
"keyType": "Pgp",
"algorithm": "EdDSA"
}
],
"metadata": {
"description": "Official npm security advisories",
"uri": "https://www.npmjs.com/advisories"
}
},
{
"issuerId": "github-security",
"name": "GitHub Security Lab",
"category": "Aggregator",
"trustTier": "Trusted",
"metadata": {
"description": "GitHub Security Advisories",
"uri": "https://github.com/advisories"
}
}
]
}
```
### 4.2 Register Issuer via API
```bash
curl -X POST http://vexlens:8080/api/v1/vexlens/issuers \
-H "Content-Type: application/json" \
-H "X-StellaOps-Tenant: tenant-001" \
-d '{
"issuerId": "vendor-acme",
"name": "ACME Corporation",
"category": "Vendor",
"trustTier": "Authoritative",
"initialKeys": [
{
"fingerprint": "1234ABCD5678EFGH",
"keyType": "Pgp",
"algorithm": "RSA"
}
],
"metadata": {
"description": "ACME security advisories",
"uri": "https://security.acme.example.com"
}
}'
```
---
## 5) Health Checks
### 5.1 Liveness Probe
```bash
curl http://vexlens:8080/health/live
# Response: {"status": "Healthy"}
```
### 5.2 Readiness Probe
```bash
curl http://vexlens:8080/health/ready
# Response: {"status": "Healthy", "checks": {"mongodb": "Healthy", "issuerDirectory": "Healthy"}}
```
### 5.3 Detailed Health
```bash
curl http://vexlens:8080/health/detailed
# Full health check with component details
```
---
## 6) Monitoring
### 6.1 Key Metrics to Monitor
| Metric | Alert Threshold | Description |
|--------|-----------------|-------------|
| `vexlens.consensus.duration_seconds` | p99 > 5s | Consensus computation latency |
| `vexlens.consensus.conflicts_total` | rate > 100/min | High conflict rate |
| `vexlens.normalization.errors_total` | rate > 10/min | Normalization failures |
| `vexlens.projection.query_duration_seconds` | p99 > 1s | Slow projection queries |
### 6.2 Grafana Dashboard
Import the VexLens dashboard from `deploy/grafana/vexlens-dashboard.json`.
### 6.3 Alerting Rules
```yaml
groups:
- name: vexlens
rules:
- alert: VexLensHighLatency
expr: histogram_quantile(0.99, rate(vexlens_consensus_duration_seconds_bucket[5m])) > 5
for: 5m
labels:
severity: warning
annotations:
summary: "VexLens consensus latency is high"
- alert: VexLensHighConflictRate
expr: rate(vexlens_consensus_conflicts_total[5m]) > 100
for: 10m
labels:
severity: warning
annotations:
summary: "VexLens detecting high conflict rate"
- alert: VexLensNormalizationErrors
expr: rate(vexlens_normalization_errors_total[5m]) > 10
for: 5m
labels:
severity: critical
annotations:
summary: "VexLens normalization errors increasing"
```
---
## 7) Backup and Recovery
### 7.1 Backup Projections
```bash
# MongoDB backup
mongodump --uri="mongodb://localhost:27017" \
--db=vexlens \
--collection=consensus_projections \
--out=/backup/vexlens-$(date +%Y%m%d)
```
### 7.2 Backup Issuer Directory
```bash
# Export issuers to JSON
curl http://vexlens:8080/api/v1/vexlens/issuers?limit=1000 \
> /backup/issuers-$(date +%Y%m%d).json
```
### 7.3 Restore
```bash
# Restore MongoDB
mongorestore --uri="mongodb://localhost:27017" \
--db=vexlens \
/backup/vexlens-20251206/
# Re-seed issuers if needed
# Issuers are automatically loaded from seed file on startup
```
---
## 8) Scaling
### 8.1 Horizontal Scaling
VexLens is stateless for compute operations. Scale horizontally by adding replicas:
```bash
kubectl scale deployment vexlens --replicas=4 -n stellaops
```
### 8.2 Performance Tuning
```yaml
# For high-throughput deployments
vexlens:
consensus:
# Enable batch processing
batchSize: 100
batchTimeoutMs: 50
storage:
mongodb:
# Connection pool
maxConnectionPoolSize: 100
minConnectionPoolSize: 10
caching:
enabled: true
redis:
connectionString: redis://redis:6379
consensusTtlMinutes: 5
issuerTtlMinutes: 60
```
---
## 9) Troubleshooting
### 9.1 Common Issues
| Issue | Cause | Resolution |
|-------|-------|------------|
| Slow consensus | Many statements | Enable caching, increase batch size |
| High conflict rate | Inconsistent sources | Review issuer trust tiers |
| Normalization failures | Invalid VEX format | Check Excititor connector config |
| Low confidence scores | Missing signatures | Configure issuer keys |
### 9.2 Debug Logging
```bash
# Enable debug logging
export VEXLENS_OBSERVABILITY_LOGGING_LEVEL=Debug
```
### 9.3 Determinism Verification
```bash
# Run determinism harness
curl -X POST http://vexlens:8080/api/v1/vexlens/test/determinism \
-H "Content-Type: application/json" \
-d '{"vexContent": "..."}'
```
---
## 10) Upgrade Procedure
### 10.1 Rolling Upgrade
```bash
# Update image
kubectl set image deployment/vexlens vexlens=stellaops/vexlens:v1.2.0 -n stellaops
# Monitor rollout
kubectl rollout status deployment/vexlens -n stellaops
```
### 10.2 Database Migrations
VexLens uses automatic schema migrations. No manual intervention required for minor versions.
For major version upgrades:
1. Backup all data
2. Review migration notes in release changelog
3. Apply migrations: `vexlens migrate --apply`
4. Verify: `vexlens migrate --verify`