244 lines
6.1 KiB
Markdown
244 lines
6.1 KiB
Markdown
# Rekor Transparency Log Budget Policy
|
|
|
|
**Last Updated**: 2025-12-20
|
|
**Owner**: Attestor Team
|
|
**Sprint**: SPRINT_3500_0003_0003
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
This document defines the budget policy for Rekor transparency log submissions. The policy balances transparency requirements with rate limits and cost considerations.
|
|
|
|
---
|
|
|
|
## Submission Tiers
|
|
|
|
### Tier 1: Graph-Level Attestations (Default)
|
|
|
|
**Scope**: One DSSE envelope per scan containing the call graph digest.
|
|
|
|
**Frequency**:
|
|
- Submitted automatically for every completed scan
|
|
- Includes: `CallGraphSnapshot.GraphDigest`, scan metadata, scanner version
|
|
|
|
**Payload Size**: ~2-5 KB per submission
|
|
|
|
**Rate Budget**:
|
|
- Default: 100 submissions/hour per tenant
|
|
- Burst: 200 submissions/hour (10-minute window)
|
|
|
|
**Configuration**:
|
|
```yaml
|
|
attestor:
|
|
rekor:
|
|
enabled: true
|
|
tier: graph-only
|
|
budget:
|
|
hourlyLimit: 100
|
|
burstLimit: 200
|
|
burstWindow: "00:10:00"
|
|
```
|
|
|
|
---
|
|
|
|
### Tier 2: Edge Bundle Attestations (On Escalation)
|
|
|
|
**Scope**: Detailed edge bundles submitted for escalated findings.
|
|
|
|
**Triggers**:
|
|
- CVE with CVSS >= 9.0 and reachable status
|
|
- Security team escalation request
|
|
- Policy engine gate failure with `require_proof: true`
|
|
|
|
**Frequency**:
|
|
- Only on explicit escalation
|
|
- Subject to daily budget cap
|
|
|
|
**Payload Size**: ~10-50 KB per bundle (varies with graph size)
|
|
|
|
**Rate Budget**:
|
|
- Default: 50 bundles/day per tenant
|
|
- No burst allowance
|
|
|
|
**Configuration**:
|
|
```yaml
|
|
attestor:
|
|
rekor:
|
|
edgeBundles:
|
|
enabled: true
|
|
dailyLimit: 50
|
|
triggers:
|
|
- cvssThreshold: 9.0
|
|
- policyGate: require_proof
|
|
- manualEscalation: true
|
|
```
|
|
|
|
---
|
|
|
|
## Budget Enforcement
|
|
|
|
### Rate Limiting
|
|
|
|
The Attestor module enforces rate limits via the `RekorSubmissionQueue`:
|
|
|
|
1. **Admission**: Requests exceeding budget are queued with backpressure
|
|
2. **Retry**: Failed submissions retry with exponential backoff
|
|
3. **Overflow**: Excess requests are stored locally for later submission
|
|
|
|
### Quota Tracking
|
|
|
|
Quotas are tracked per tenant in `attestor.rekor_quotas`:
|
|
|
|
```sql
|
|
CREATE TABLE attestor.rekor_quotas (
|
|
tenant_id UUID PRIMARY KEY,
|
|
hourly_count INT NOT NULL DEFAULT 0,
|
|
daily_bundle_count INT NOT NULL DEFAULT 0,
|
|
last_reset_hour TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
last_reset_day DATE NOT NULL DEFAULT CURRENT_DATE
|
|
);
|
|
```
|
|
|
|
### Alerts
|
|
|
|
| Metric | Threshold | Action |
|
|
|--------|-----------|--------|
|
|
| `attestor_rekor_queue_depth` | > 1000 | Page on-call |
|
|
| `attestor_rekor_submissions_rejected` | > 100/hour | Investigate quota abuse |
|
|
| `attestor_rekor_budget_utilization` | > 80% | Notify tenant admin |
|
|
|
|
---
|
|
|
|
## Air-Gap Considerations
|
|
|
|
In air-gapped deployments, Rekor submissions are:
|
|
|
|
1. **Queued Locally**: Stored in `attestor.rekor_offline_queue`
|
|
2. **Bundled on Export**: Included in offline kit as pending attestations
|
|
3. **Submitted on Connect**: When connectivity restored, queue drains
|
|
|
|
### Offline Queue Schema
|
|
|
|
```sql
|
|
CREATE TABLE attestor.rekor_offline_queue (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
tier TEXT NOT NULL CHECK (tier IN ('graph', 'edge')),
|
|
payload BYTEA NOT NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
priority INT NOT NULL DEFAULT 0
|
|
);
|
|
```
|
|
|
|
---
|
|
|
|
## Monitoring
|
|
|
|
### Key Metrics
|
|
|
|
| Metric | Description | Labels |
|
|
|--------|-------------|--------|
|
|
| `attestor_rekor_submissions_total` | Total Rekor submissions | tier, status |
|
|
| `attestor_rekor_submission_latency_seconds` | Submission latency histogram | tier |
|
|
| `attestor_rekor_queue_depth` | Current queue depth | tier |
|
|
| `attestor_rekor_budget_remaining` | Remaining hourly budget | tenant |
|
|
|
|
### Grafana Dashboard
|
|
|
|
Import dashboard ID: `stellaops-attestor-rekor` from the StellaOps dashboard gallery.
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
**Q: Submissions are being rejected with 429**
|
|
- Check `attestor_rekor_budget_remaining` metric
|
|
- Review tenant's hourly submission rate
|
|
- Consider increasing budget if legitimate spike
|
|
|
|
**Q: Offline queue growing unbounded**
|
|
- Verify network connectivity to Rekor
|
|
- Check `attestor_rekor_submission_errors` for root cause
|
|
- Consider manual drain if transient issue resolved
|
|
|
|
**Q: Edge bundles not being submitted**
|
|
- Verify escalation triggers are configured
|
|
- Check policy engine gate configuration
|
|
- Review `attestor_rekor_edge_bundle_triggers` logs
|
|
|
|
---
|
|
|
|
## Configuration Reference
|
|
|
|
### Full Configuration Schema
|
|
|
|
```yaml
|
|
attestor:
|
|
rekor:
|
|
# Enable Rekor integration
|
|
enabled: true
|
|
|
|
# Rekor server URL (default: public Sigstore Rekor)
|
|
serverUrl: "https://rekor.sigstore.dev"
|
|
|
|
# Log version: Auto or V2 (V2 uses tile-based Sunlight format)
|
|
version: Auto
|
|
|
|
# Log ID for multi-log environments (hex-encoded SHA-256)
|
|
logId: "c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d"
|
|
|
|
# Tile base URL for V2 (optional, defaults to {serverUrl}/tile/)
|
|
tileBaseUrl: ""
|
|
|
|
|
|
# Submission tier: graph-only | with-edges
|
|
tier: graph-only
|
|
|
|
# Budget configuration
|
|
budget:
|
|
# Hourly limit for graph attestations
|
|
hourlyLimit: 100
|
|
|
|
# Burst allowance
|
|
burstLimit: 200
|
|
burstWindow: "00:10:00"
|
|
|
|
# Daily limit for edge bundles
|
|
edgeBundleDailyLimit: 50
|
|
|
|
# Retry configuration
|
|
retry:
|
|
maxAttempts: 3
|
|
initialDelay: "00:00:05"
|
|
maxDelay: "00:05:00"
|
|
backoffMultiplier: 2.0
|
|
|
|
# Offline mode
|
|
offline:
|
|
queueEnabled: true
|
|
maxQueueSize: 10000
|
|
drainOnConnect: true
|
|
|
|
# Edge bundle triggers
|
|
edgeBundles:
|
|
enabled: true
|
|
triggers:
|
|
- cvssThreshold: 9.0
|
|
- policyGate: require_proof
|
|
- manualEscalation: true
|
|
```
|
|
|
|
---
|
|
|
|
## Related Documentation
|
|
|
|
- [Rekor Verification Technical Design](../modules/attestor/rekor-verification-design.md) - Full technical design including v2 tile support
|
|
- [Attestor AGENTS.md](../../src/Attestor/StellaOps.Attestor/AGENTS.md)
|
|
- [Scanner Score Proofs API](../api/scanner-score-proofs-api.md)
|
|
- [Offline Kit Specification](../OFFLINE_KIT.md)
|
|
- [Sigstore Rekor Documentation](https://docs.sigstore.dev/rekor/overview/)
|
|
- [C2SP tlog-tiles Specification](https://c2sp.org/tlog-tiles) - Tile-based transparency log format (v2)
|