fix tests. new product advisories enhancements

This commit is contained in:
master
2026-01-25 19:11:36 +02:00
parent c70e83719e
commit 6e687b523a
504 changed files with 40610 additions and 3785 deletions

View File

@@ -0,0 +1,35 @@
{
"version": 1,
"rekor": {
"url": "https://rekor.sigstore.dev",
"tile_base_url": "https://rekor.sigstore.dev/tile/",
"log_id": "c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d",
"public_key_target": "rekor-key-v1"
},
"fulcio": {
"url": "https://fulcio.sigstore.dev",
"root_cert_target": "fulcio-root-2026Q1"
},
"ct_log": {
"url": "https://ctfe.sigstore.dev",
"public_key_target": "ctfe-key-v1"
},
"timestamp_authority": {
"url": "https://tsa.sigstore.dev",
"cert_chain_target": "tsa-chain-2026Q1"
},
"overrides": {
"staging": {
"rekor_url": "https://rekor.sigstage.dev",
"fulcio_url": "https://fulcio.sigstage.dev"
},
"airgap": {
"rekor_url": "https://rekor.internal:8080",
"fulcio_url": "https://fulcio.internal:8081"
}
},
"metadata": {
"updated_at": "2026-01-25T00:00:00Z",
"note": "Production Sigstore endpoints - January 2026"
}
}

View File

@@ -0,0 +1,122 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://stella-ops.org/schemas/sigstore-services/v1",
"title": "Sigstore Services Map",
"description": "Service discovery map for Sigstore infrastructure endpoints. Distributed via TUF for dynamic endpoint management without client reconfiguration.",
"type": "object",
"required": ["version", "rekor"],
"properties": {
"version": {
"type": "integer",
"minimum": 1,
"description": "Schema version for forward compatibility"
},
"rekor": {
"type": "object",
"description": "Rekor transparency log configuration",
"required": ["url"],
"properties": {
"url": {
"type": "string",
"format": "uri",
"description": "Primary Rekor API endpoint"
},
"tile_base_url": {
"type": "string",
"format": "uri",
"description": "Optional tile endpoint (defaults to {url}/tile/)"
},
"log_id": {
"type": "string",
"pattern": "^[a-f0-9]{64}$",
"description": "SHA-256 hash of log public key (hex-encoded)"
},
"public_key_target": {
"type": "string",
"description": "TUF target name for Rekor public key"
}
}
},
"fulcio": {
"type": "object",
"description": "Fulcio certificate authority configuration",
"properties": {
"url": {
"type": "string",
"format": "uri",
"description": "Fulcio API endpoint"
},
"root_cert_target": {
"type": "string",
"description": "TUF target name for Fulcio root certificate"
}
}
},
"ct_log": {
"type": "object",
"description": "Certificate Transparency log configuration",
"properties": {
"url": {
"type": "string",
"format": "uri",
"description": "CT log API endpoint"
},
"public_key_target": {
"type": "string",
"description": "TUF target name for CT log public key"
}
}
},
"timestamp_authority": {
"type": "object",
"description": "Timestamp authority configuration",
"properties": {
"url": {
"type": "string",
"format": "uri",
"description": "TSA endpoint"
},
"cert_chain_target": {
"type": "string",
"description": "TUF target name for TSA certificate chain"
}
}
},
"overrides": {
"type": "object",
"description": "Site-local endpoint overrides by environment",
"additionalProperties": {
"type": "object",
"properties": {
"rekor_url": {
"type": "string",
"format": "uri"
},
"fulcio_url": {
"type": "string",
"format": "uri"
},
"ct_log_url": {
"type": "string",
"format": "uri"
}
}
}
},
"metadata": {
"type": "object",
"description": "Additional metadata",
"properties": {
"updated_at": {
"type": "string",
"format": "date-time",
"description": "Last update timestamp"
},
"note": {
"type": "string",
"description": "Human-readable note about this configuration"
}
}
}
}
}

View File

@@ -0,0 +1,73 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://docs.stella-ops.org/events/attestor.logged@1.json",
"title": "Attestor Logged Event",
"description": "Emitted when an attestation is logged to a transparency log",
"type": "object",
"required": ["eventId", "kind", "version", "tenant", "ts", "payload"],
"properties": {
"eventId": {
"type": "string",
"format": "uuid",
"description": "Unique event identifier"
},
"kind": {
"const": "attestor.logged",
"description": "Event kind"
},
"version": {
"const": "1",
"description": "Schema version"
},
"tenant": {
"type": "string",
"description": "Tenant identifier"
},
"ts": {
"type": "string",
"format": "date-time",
"description": "Event timestamp in ISO 8601 format"
},
"actor": {
"type": "string",
"description": "Service or user that triggered the event"
},
"payload": {
"type": "object",
"required": ["attestationId", "imageDigest", "imageName"],
"properties": {
"attestationId": {
"type": "string",
"description": "Unique attestation identifier"
},
"imageDigest": {
"type": "string",
"description": "Image digest (sha256)"
},
"imageName": {
"type": "string",
"description": "Full image name with tag"
},
"predicateType": {
"type": "string",
"description": "In-toto predicate type URI"
},
"logIndex": {
"type": "integer",
"description": "Transparency log index"
},
"links": {
"type": "object",
"properties": {
"attestation": { "type": "string", "format": "uri" },
"rekor": { "type": "string", "format": "uri" }
}
}
}
},
"attributes": {
"type": "object",
"additionalProperties": { "type": "string" }
}
}
}

View File

@@ -0,0 +1,78 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://docs.stella-ops.org/events/scanner.report.ready@1.json",
"title": "Scanner Report Ready Event",
"description": "Emitted when a scan report is generated and ready for download",
"type": "object",
"required": ["eventId", "kind", "version", "tenant", "ts", "payload"],
"properties": {
"eventId": {
"type": "string",
"format": "uuid",
"description": "Unique event identifier"
},
"kind": {
"const": "scanner.report.ready",
"description": "Event kind"
},
"version": {
"const": "1",
"description": "Schema version"
},
"tenant": {
"type": "string",
"description": "Tenant identifier"
},
"ts": {
"type": "string",
"format": "date-time",
"description": "Event timestamp in ISO 8601 format"
},
"actor": {
"type": "string",
"description": "Service or user that triggered the event"
},
"payload": {
"type": "object",
"required": ["reportId", "scanId", "imageDigest", "imageName"],
"properties": {
"reportId": {
"type": "string",
"description": "Unique report identifier"
},
"scanId": {
"type": "string",
"description": "Related scan identifier"
},
"imageDigest": {
"type": "string",
"description": "Image digest (sha256)"
},
"imageName": {
"type": "string",
"description": "Full image name with tag"
},
"format": {
"type": "string",
"enum": ["cyclonedx", "spdx", "sarif"],
"description": "Report format"
},
"size": {
"type": "integer",
"description": "Report size in bytes"
},
"links": {
"type": "object",
"properties": {
"report": { "type": "string", "format": "uri" },
"download": { "type": "string", "format": "uri" }
}
}
}
},
"attributes": {
"type": "object",
"additionalProperties": { "type": "string" }
}
}
}

View File

@@ -0,0 +1,87 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://docs.stella-ops.org/events/scanner.scan.completed@1.json",
"title": "Scanner Scan Completed Event",
"description": "Emitted when a container image scan completes",
"type": "object",
"required": ["eventId", "kind", "version", "tenant", "ts", "payload"],
"properties": {
"eventId": {
"type": "string",
"format": "uuid",
"description": "Unique event identifier"
},
"kind": {
"const": "scanner.scan.completed",
"description": "Event kind"
},
"version": {
"const": "1",
"description": "Schema version"
},
"tenant": {
"type": "string",
"description": "Tenant identifier"
},
"ts": {
"type": "string",
"format": "date-time",
"description": "Event timestamp in ISO 8601 format"
},
"actor": {
"type": "string",
"description": "Service or user that triggered the event"
},
"payload": {
"type": "object",
"required": ["scanId", "imageDigest", "imageName", "verdict"],
"properties": {
"scanId": {
"type": "string",
"description": "Unique scan identifier"
},
"imageDigest": {
"type": "string",
"description": "Image digest (sha256)"
},
"imageName": {
"type": "string",
"description": "Full image name with tag"
},
"verdict": {
"type": "string",
"enum": ["pass", "fail"],
"description": "Scan verdict"
},
"findingsCount": {
"type": "integer",
"description": "Total number of findings"
},
"vulnerabilities": {
"type": "object",
"properties": {
"critical": { "type": "integer" },
"high": { "type": "integer" },
"medium": { "type": "integer" },
"low": { "type": "integer" }
}
},
"scanDurationMs": {
"type": "integer",
"description": "Scan duration in milliseconds"
},
"links": {
"type": "object",
"properties": {
"findings": { "type": "string", "format": "uri" },
"sbom": { "type": "string", "format": "uri" }
}
}
}
},
"attributes": {
"type": "object",
"additionalProperties": { "type": "string" }
}
}
}

View File

@@ -0,0 +1,73 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://docs.stella-ops.org/events/scheduler.rescan.delta@1.json",
"title": "Scheduler Rescan Delta Event",
"description": "Emitted when a scheduled rescan detects vulnerability changes",
"type": "object",
"required": ["eventId", "kind", "version", "tenant", "ts", "payload"],
"properties": {
"eventId": {
"type": "string",
"format": "uuid",
"description": "Unique event identifier"
},
"kind": {
"const": "scheduler.rescan.delta",
"description": "Event kind"
},
"version": {
"const": "1",
"description": "Schema version"
},
"tenant": {
"type": "string",
"description": "Tenant identifier"
},
"ts": {
"type": "string",
"format": "date-time",
"description": "Event timestamp in ISO 8601 format"
},
"actor": {
"type": "string",
"description": "Service or user that triggered the event"
},
"payload": {
"type": "object",
"required": ["scheduleId", "deltaId"],
"properties": {
"scheduleId": {
"type": "string",
"description": "Schedule identifier"
},
"deltaId": {
"type": "string",
"description": "Delta report identifier"
},
"imagesAffected": {
"type": "integer",
"description": "Number of images affected"
},
"newVulnerabilities": {
"type": "integer",
"description": "Number of new vulnerabilities detected"
},
"resolvedVulnerabilities": {
"type": "integer",
"description": "Number of resolved vulnerabilities"
},
"links": {
"type": "object",
"properties": {
"schedule": { "type": "string", "format": "uri" },
"delta": { "type": "string", "format": "uri" }
}
}
}
},
"attributes": {
"type": "object",
"additionalProperties": { "type": "string" }
}
}
}

View File

@@ -0,0 +1,219 @@
# Compliance Attestation Form
**Document Version:** 1.0.0
**Last Updated:** 2026-01-25
This document describes the compliance attestation process for Stella Ops Community
Plugin Grant users. For a fillable template, see `templates/self-attestation-form.md`.
---
## 1. Purpose
The compliance attestation process allows organizations to demonstrate compliance
with the Stella Ops Community Plugin Grant without enabling telemetry or undergoing
formal audit. It provides a trust-based mechanism for license compliance verification.
---
## 2. Who Should Attest
Annual attestation is recommended for:
- Organizations using Stella Ops in production
- Deployments approaching free tier limits (2+ environments, 500+ scans/day)
- Organizations with data governance policies prohibiting telemetry
- MSPs managing customer deployments
Attestation is **not required** for:
- Non-production or evaluation use
- Single-environment deployments well within limits
- Organizations with active telemetry enabled
---
## 3. Attestation Components
### 3.1 Operator Information
| Field | Description | Example |
|-------|-------------|---------|
| Organization Name | Legal entity name | Acme Corporation |
| Contact Name | Primary compliance contact | Jane Smith |
| Contact Email | Email for compliance communications | compliance@acme.com |
| Installation ID | From admin dashboard (optional) | inst_abc123xyz |
| Attestation Date | Date form completed | 2026-01-25 |
### 3.2 Usage Declaration
Declare current usage levels:
**Environment Count:**
- [ ] 1 Environment
- [ ] 2 Environments
- [ ] 3 Environments (maximum free tier)
- [ ] More than 3 Environments (requires commercial license)
**Scan Volume (peak 24-hour period in past year):**
- [ ] Under 100 scans/day
- [ ] 100-499 scans/day
- [ ] 500-999 scans/day (maximum free tier)
- [ ] Over 999 scans/day (requires commercial license)
### 3.3 Distribution Declaration
If redistributing Stella Ops or Plugins:
- [ ] We do not redistribute Stella Ops or Plugins
- [ ] We redistribute with LICENSE and NOTICE files preserved
- [ ] We redistribute Plugins only (not core Stella Ops)
- [ ] We include this Addendum verbatim in all distributions
- [ ] We do not offer Stella Ops as a competing managed service
### 3.4 SaaS/MSP Declaration
Select the applicable scenario:
- [ ] **Internal Use Only:** Stella Ops is used only by our employees/contractors
- [ ] **MSP Single-Tenant:** We host isolated instances for customers (license details below)
- [ ] **Not Applicable:** We do not provide hosted services
If MSP Single-Tenant, specify:
- Number of customer instances: ___
- License type per instance:
- [ ] Each customer has own license
- [ ] Our commercial license covers all instances
- [ ] Mix (specify below)
---
## 4. Certification Statement
By submitting this attestation, the undersigned certifies that:
1. The information provided is accurate to the best of their knowledge
2. The organization's use of Stella Ops complies with BUSL-1.1 and the Community
Plugin Grant
3. They have authority to make this attestation on behalf of the organization
4. They understand that false attestation may result in license termination
---
## 5. Submission Process
### Step 1: Download Template
Copy the template from `docs/legal/templates/self-attestation-form.md`
### Step 2: Complete Form
Fill in all required fields. Use "N/A" for non-applicable sections.
### Step 3: Internal Review
Have appropriate internal stakeholders review:
- Legal/Compliance team
- IT/Platform team (for technical accuracy)
- Management (for authorization)
### Step 4: Submit
Send completed form to: compliance@stella-ops.org
**Subject line:** `Compliance Attestation - [Organization Name] - [Year]`
### Step 5: Confirmation
- Acknowledgment within 10 business days
- Confirmation letter issued if attestation accepted
- Follow-up questions if clarification needed
---
## 6. Renewal
### 6.1 Annual Renewal
Attestation should be renewed annually:
- **Preferred:** Within 30 days of attestation anniversary
- **Grace period:** 60 days after anniversary
- **Reminder:** stella-ops.org will send reminder 30 days before due date
### 6.2 Material Changes
Submit updated attestation within 30 days if:
- Environment count increases
- Scan volume regularly exceeds 80% of limit
- Organization structure changes (merger, acquisition)
- Deployment model changes (internal to MSP)
---
## 7. Record Retention
### 7.1 Attestor Retention
Organizations should retain:
- Copy of submitted attestation
- Supporting documentation (usage reports, dashboard screenshots)
- Confirmation letter from stella-ops.org
**Recommended retention period:** 5 years
### 7.2 stella-ops.org Retention
stella-ops.org retains:
- Submitted attestations: 5 years
- Confirmation letters: Indefinitely
- Supporting communications: 3 years
---
## 8. Frequently Asked Questions
### Q: Is attestation mandatory?
**A:** No. Attestation is voluntary and recommended. It provides documented evidence
of compliance in case of future questions.
### Q: What if our usage changes after attesting?
**A:** Submit an updated attestation within 30 days of material changes. Good-faith
updates are appreciated and do not trigger penalties.
### Q: Can we attest for multiple installations?
**A:** Yes. Use one form per installation, or contact compliance@stella-ops.org for
a consolidated form for large deployments.
### Q: What happens if we can't attest to compliance?
**A:** Contact sales@stella-ops.org to discuss commercial licensing options. There's
no penalty for recognizing a need to upgrade.
### Q: Is the attestation legally binding?
**A:** The attestation is a representation of fact. Knowingly false attestation may
result in license termination. However, good-faith errors with prompt correction
are not penalized.
---
## 9. Contact
**Attestation submissions:**
compliance@stella-ops.org
**Questions about the process:**
legal@stella-ops.org
**Commercial licensing:**
sales@stella-ops.org
---
## See Also
- `templates/self-attestation-form.md` - Fillable template
- `ENFORCEMENT_TELEMETRY_POLICY.md` - Audit and telemetry details
- `LICENSE-ADDENDUM-COMMUNITY-PLUGIN-GRANT.md` - Full legal terms
---
*Document maintained by: Legal + Compliance Team*
*Last review: 2026-01-25*

View File

@@ -0,0 +1,299 @@
# Enforcement and Telemetry Policy
**Document Version:** 1.0.0
**Last Updated:** 2026-01-25
This document describes how stella-ops.org verifies compliance with the Community
Plugin Grant and free tier limits, including audit rights, telemetry options, and
privacy safeguards.
---
## 1. Compliance Philosophy
Stella Ops is committed to:
1. **Trust-based compliance** - We assume good faith from our users
2. **Minimal intrusion** - Verification should not burden legitimate users
3. **Privacy by design** - No collection of customer content or sensitive data
4. **Transparency** - Clear documentation of what we collect and why
---
## 2. Audit Rights
### 2.1 When Audits May Occur
stella-ops.org reserves the right to request compliance verification:
- **Frequency:** No more than once per calendar year per licensee
- **Notice:** Minimum 30 days written notice
- **Scope:** Limited to verification of Environment count and Scan volume
- **Trigger:** Audits may be initiated based on:
- Routine sampling of licensees
- Credible reports of non-compliance
- Self-reported concerns from licensees
### 2.2 Audit Process
**Step 1: Notice**
- Written notice via email to registered contact
- Specifies audit scope and requested documentation
- Provides minimum 30-day response window
**Step 2: Documentation Request**
- Licensee provides requested information:
- Number of active Environments
- Scan volume metrics (e.g., from Stella Ops admin dashboard)
- Deployment architecture summary
- No access to scan content, vulnerabilities, or business data required
**Step 3: Review**
- stella-ops.org reviews submitted documentation
- May request clarification on ambiguous items
- Typically completed within 15 business days
**Step 4: Resolution**
- Compliant: Written confirmation provided
- Minor variance: Grace period to remediate
- Significant non-compliance: Commercial license discussion
### 2.3 Audit Safeguards
All audits are conducted with:
- **Confidentiality:** All submitted information treated as confidential business
information under mutual NDA
- **Data protection:** GDPR-compliant handling of any personal data
- **Limited retention:** Audit documentation retained for maximum 3 years
- **No content access:** We never request access to scan results, source code,
or customer business data
---
## 3. Voluntary Telemetry
### 3.1 Telemetry Overview
Stella Ops provides an **optional** telemetry endpoint for users who wish to
automate compliance reporting.
**Key principles:**
- **Strictly opt-in:** Disabled by default
- **Aggregate metrics only:** No detailed scan data
- **Privacy-respecting:** No PII or customer content
- **User-controlled:** Can be disabled at any time
### 3.2 What Telemetry Collects (When Enabled)
| Metric | Description | Purpose |
|--------|-------------|---------|
| `installation_id` | Anonymous installation identifier | Deduplicate reports |
| `environment_count` | Number of active environments | License compliance |
| `scan_count_24h` | Scans in rolling 24-hour period | License compliance |
| `version` | Stella Ops version | Compatibility/support |
| `timestamp` | Report timestamp | Time-series analysis |
### 3.3 What Telemetry Does NOT Collect
- Scan results or vulnerability data
- Customer names or identifiers
- IP addresses (beyond transport layer)
- Source code or artifact contents
- User credentials or tokens
- Business-sensitive configuration
### 3.4 Enabling/Disabling Telemetry
**To enable:**
```yaml
# In stella-ops.yaml
telemetry:
enabled: true
endpoint: https://telemetry.stella-ops.org/v1/report
```
**To disable (default):**
```yaml
telemetry:
enabled: false
```
**Environment variable override:**
```bash
STELLAOPS_TELEMETRY_ENABLED=false
```
### 3.5 Telemetry Data Handling
- **Transmission:** TLS 1.3 encrypted
- **Storage:** Aggregated and anonymized within 24 hours
- **Retention:** Raw reports retained for maximum 90 days
- **Access:** Limited to license compliance team
- **No sale:** Never sold or shared with third parties
---
## 4. Self-Attestation
### 4.1 Overview
As an alternative to telemetry, licensees may provide annual self-attestation
of compliance. This is the recommended approach for organizations with strict
data governance requirements.
### 4.2 Attestation Process
1. **Download form:** `docs/legal/templates/self-attestation-form.md`
2. **Complete attestation:** Fill in required fields
3. **Submit:** Email to compliance@stella-ops.org
4. **Confirmation:** Receive acknowledgment within 10 business days
### 4.3 Attestation Frequency
- **Annual:** Submit once per calendar year
- **Upon request:** May be requested as part of audit
- **Voluntary updates:** Submit anytime if circumstances change
### 4.4 False Attestation
Knowingly providing false attestation information may result in:
- Immediate termination of license rights
- Requirement to obtain commercial license
- Potential legal action for license violation
---
## 5. Compliance Verification Methods
### 5.1 Recommended: Built-in Dashboard
Stella Ops includes a compliance dashboard at `/admin/compliance`:
```
Compliance Status
─────────────────
License Type: Community (Free Tier)
Environments: 2 of 3 (within limit)
Scans (24h): 456 of 999 (within limit)
Status: COMPLIANT
```
This dashboard can be used to:
- Monitor current usage against limits
- Generate compliance reports for audit
- Export metrics for self-attestation
### 5.2 API-Based Verification
Compliance metrics are available via API:
```bash
curl -H "Authorization: Bearer $ADMIN_TOKEN" \
https://your-instance/api/v1/admin/compliance/metrics
```
Response:
```json
{
"environment_count": 2,
"environment_limit": 3,
"scan_count_24h": 456,
"scan_limit_24h": 999,
"compliant": true,
"timestamp": "2026-01-25T14:30:00Z"
}
```
### 5.3 Log-Based Verification
For organizations that prefer log analysis:
```bash
# Extract compliance metrics from logs
grep "compliance_check" /var/log/stellaops/audit.log | tail -1
```
---
## 6. Remediation
### 6.1 Exceeding Limits
If you discover you've exceeded free tier limits:
1. **Immediate:** Usage may be throttled (see `30_QUOTA_ENFORCEMENT_FLOW1.md`)
2. **Short-term:** Reduce environments or scan volume to return to compliance
3. **Long-term:** Obtain commercial license for ongoing needs
### 6.2 Grace Period
For good-faith limit exceedances:
- **First occurrence:** 30-day grace period to remediate
- **Repeated occurrence:** 15-day grace period
- **Intentional abuse:** No grace period; commercial license required immediately
### 6.3 Commercial License Transition
If you need to exceed free tier limits:
- Contact sales@stella-ops.org
- Licenses can be backdated to cover grace period
- No penalty for good-faith users who remediate promptly
---
## 7. Privacy Commitments
stella-ops.org commits to the following privacy principles:
### 7.1 Data Minimization
We collect only the minimum data necessary for license compliance verification.
### 7.2 Purpose Limitation
Compliance data is used only for license verification, never for marketing or
sold to third parties.
### 7.3 User Control
- Telemetry is opt-in only
- Self-attestation is always available as alternative
- Users can request deletion of any collected data
### 7.4 GDPR Compliance
For EU users:
- Data Processing Agreement (DPA) available upon request
- Right to access, rectify, and delete data
- Data stored in EU-based infrastructure when EU endpoint selected
### 7.5 Contact
For privacy-related inquiries:
- Email: privacy@stella-ops.org
- DPO: dpo@stella-ops.org (EU users)
---
## 8. Questions and Support
**Compliance questions:**
- Email: compliance@stella-ops.org
**Technical questions about telemetry:**
- Documentation: `docs/admin/telemetry.md`
- Support: support@stella-ops.org
**Commercial licensing:**
- Email: sales@stella-ops.org
---
## See Also
- `LICENSE-ADDENDUM-COMMUNITY-PLUGIN-GRANT.md` - Full legal terms
- `docs/legal/30_QUOTA_ENFORCEMENT_FLOW1.md` - Quota enforcement behavior
- `docs/legal/templates/self-attestation-form.md` - Attestation form
- `docs/admin/telemetry.md` - Technical telemetry configuration
---
*Document maintained by: Legal + Privacy Office*
*Last review: 2026-01-25*

View File

@@ -1,4 +1,4 @@
# Legal FAQ <EFBFBD> Free-Tier Quota & BUSL-1.1 Additional Use Grant
# Legal FAQ - Free-Tier Quota & BUSL-1.1 Additional Use Grant
> **Operational behaviour (limits, counters, delays) is documented in**
> [`30_QUOTA_ENFORCEMENT_FLOW1.md`](30_QUOTA_ENFORCEMENT_FLOW1.md).
@@ -6,6 +6,12 @@
> service or embedding it into another product while the free-tier limits are
> in place.
> **Plugin developers:** See [`PLUGIN_DEVELOPER_FAQ.md`](PLUGIN_DEVELOPER_FAQ.md)
> for plugin-specific licensing questions.
>
> **MSPs and SaaS providers:** See [`SAAS_MSP_GUIDANCE.md`](SAAS_MSP_GUIDANCE.md)
> for detailed hosting scenarios.
---
## 1 ? Does enforcing a quota violate BUSL-1.1?
@@ -45,7 +51,7 @@ obtained. Proprietary integration code does not have to be disclosed.
The BUSL-1.1 Additional Use Grant prohibits providing Stella Ops as a hosted or
managed service to third parties. SaaS/hosted use requires a commercial license.
## 5 <20> Is e-mail collection for the JWT legal?
## 5 <20> Is e-mail collection for the JWT legal?
* **Purpose limitation (GDPR Art. 5-1 b):** address is used only to deliver the
JWT or optional release notes.
@@ -58,10 +64,23 @@ Hence the token workflow adheres to GDPR principles.
---
## 6 <20> Change-log
---
## See Also
- [`PLUGIN_DEVELOPER_FAQ.md`](PLUGIN_DEVELOPER_FAQ.md) - Plugin development and distribution questions
- [`SAAS_MSP_GUIDANCE.md`](SAAS_MSP_GUIDANCE.md) - SaaS and MSP hosting scenarios
- [`ENFORCEMENT_TELEMETRY_POLICY.md`](ENFORCEMENT_TELEMETRY_POLICY.md) - Audit and telemetry details
- [`COMPLIANCE_ATTESTATION_FORM.md`](COMPLIANCE_ATTESTATION_FORM.md) - Self-attestation process
- [`LICENSE-ADDENDUM-COMMUNITY-PLUGIN-GRANT.md`](../../LICENSE-ADDENDUM-COMMUNITY-PLUGIN-GRANT.md) - Full addendum text
---
## 6 - Change-log
| Version | Date | Notes |
|---------|------|-------|
| **3.1** | 2026-01-25 | Added cross-references to Community Plugin Grant documentation. |
| **3.0** | 2026-01-20 | Updated for BUSL-1.1 Additional Use Grant. |
| **2.1** | 2026-01-20 | Updated for Apache-2.0 licensing (superseded by BUSL-1.1 in v3.0). |
| **2.0** | 2025-07-16 | Removed runtime quota details; linked to new authoritative overview. |

View File

@@ -126,6 +126,41 @@ The following are considered **aggregation**, not derivation:
**Rationale:** These components communicate via network protocols, APIs, or standard interfaces and are not linked into StellaOps binaries.
### 3.5 Plugin Distribution (Community Plugin Grant)
The Community Plugin Grant Addendum (`LICENSE-ADDENDUM-COMMUNITY-PLUGIN-GRANT.md`)
provides additional terms for plugin development and distribution.
**When distributing StellaOps Plugins:**
```
Plugin Distribution
+-- Plugin code (your license)
+-- Attribution to StellaOps
+-- If derivative work:
+-- LICENSE (BUSL-1.1)
+-- LICENSE-ADDENDUM-COMMUNITY-PLUGIN-GRANT.md
+-- NOTICE.md
```
**Requirements by Plugin Type:**
| Plugin Type | License | Attribution | Include LICENSE | Include Addendum |
|-------------|---------|-------------|-----------------|------------------|
| API-only (no StellaOps code) | Your choice | Recommended | No | No |
| Includes StellaOps code | BUSL-1.1 | Required | Yes | Yes |
| Bundled with StellaOps | BUSL-1.1 | Required | Yes | Yes |
| Competing managed service | Commercial | N/A | N/A | N/A |
**Not Allowed Without Commercial License:**
- Redistributing plugins as part of a competing managed service offering
- White-labeling StellaOps functionality through plugins
- Embedding plugins in multi-tenant SaaS offerings to third parties
**See Also:**
- `docs/legal/PLUGIN_DEVELOPER_FAQ.md` - Detailed plugin licensing FAQ
- `docs/legal/SAAS_MSP_GUIDANCE.md` - SaaS and MSP hosting scenarios
---
## 4. Specific Dependency Analysis
@@ -289,8 +324,18 @@ Sample configuration files (`etc/*.yaml.sample`) are:
- [Apache 2.0 FAQ](https://www.apache.org/foundation/license-faq.html)
- [SPDX License List](https://spdx.org/licenses/)
- [REUSE Best Practices](https://reuse.software/tutorial/)
- [BUSL-1.1 License Text](https://spdx.org/licenses/BUSL-1.1.html)
---
## 9. Related Documents
- `LICENSE-ADDENDUM-COMMUNITY-PLUGIN-GRANT.md` - Community Plugin Grant Addendum
- `docs/legal/PLUGIN_DEVELOPER_FAQ.md` - Plugin developer FAQ
- `docs/legal/SAAS_MSP_GUIDANCE.md` - SaaS and MSP guidance
- `docs/legal/ENFORCEMENT_TELEMETRY_POLICY.md` - Audit and compliance policy
---
*Document maintained by: Legal + Security Guild*
*Last review: 2026-01-20*
*Last review: 2026-01-25*

View File

@@ -0,0 +1,291 @@
# Plugin Developer FAQ
**Document Version:** 1.0.0
**Last Updated:** 2026-01-25
This FAQ addresses common questions from plugin developers working with the Stella Ops
Community Plugin Grant. For the full legal terms, see `LICENSE-ADDENDUM-COMMUNITY-PLUGIN-GRANT.md`
in the repository root.
---
## General Questions
### Q1: What constitutes a "Plugin" under the Community Plugin Grant?
**A:** A Plugin is a separately packaged extension that interfaces with Stella Ops using
documented public plugin APIs or integration points. This includes:
**Examples of Plugins:**
- Custom vulnerability connectors (e.g., integrating a proprietary vulnerability database)
- CI/CD integrations (e.g., Jenkins, GitLab CI, Azure DevOps plugins)
- Output formatters (e.g., custom report templates, dashboard integrations)
- Notification connectors (e.g., Slack, Teams, PagerDuty integrations)
- Scanner analyzers (e.g., language-specific dependency parsers)
- Policy gates (e.g., custom compliance rules)
**NOT Plugins (derivative works requiring BUSL-1.1 compliance):**
- Modifications to Stella Ops core source code
- Forks that include modified Stella Ops components
- Extensions that copy substantial portions of Stella Ops internals
### Q2: Can I sell my plugin commercially?
**A:** Yes. You may develop and sell plugins commercially under license terms of your
choosing (including proprietary terms), provided:
1. Your plugin does not include, copy, or modify Stella Ops source code; AND
2. You comply with the attribution requirements (see Q4).
Your commercial plugin license is entirely separate from the BUSL-1.1 license covering
Stella Ops itself.
### Q3: Do I need to open-source my plugin?
**A:** No. Plugins that interface with Stella Ops through public APIs do not need to be
open-sourced. You may use any license you choose, including proprietary licenses.
**Exception:** If your plugin includes, copies, or modifies any portion of Stella Ops
source code, it becomes a derivative work subject to BUSL-1.1.
### Q4: What attribution is required when distributing a plugin?
**A:** When distributing a plugin, you should:
1. **Acknowledge compatibility:** State that your plugin is designed for use with
Stella Ops (e.g., "Compatible with Stella Ops Suite")
2. **Include license reference:** If your plugin distribution includes any Stella Ops
components (even configuration samples), include the LICENSE and NOTICE files
3. **Link to source:** Provide a link to the Stella Ops source repository
(https://git.stella-ops.org)
**Minimum attribution example:**
```
This plugin is designed for use with Stella Ops Suite.
Stella Ops is licensed under BUSL-1.1. See https://git.stella-ops.org
```
---
## Usage Limits
### Q5: What counts as an "Environment"?
**A:** An Environment is a logically separated workspace within a Stella Ops installation.
The free tier allows up to 3 Environments per installation.
**Each of these counts as one Environment:**
- A "Development" environment for testing scans
- A "Staging" environment for pre-production validation
- A "Production" environment for live deployments
- A tenant/workspace in a multi-tenant setup
- A project or team workspace with isolated configuration
**These do NOT count as separate Environments:**
- High-availability replicas of the same environment
- Read replicas or cache nodes
- Backup/disaster recovery instances (if not actively used)
**Example scenarios:**
| Scenario | Environment Count |
|----------|------------------|
| Single dev laptop installation | 1 |
| Dev + Staging + Prod for one team | 3 |
| Two separate teams, each with Dev + Prod | 4 (requires commercial license) |
| MSP hosting 5 isolated customer instances | 5 (requires commercial license) |
### Q6: What counts as a "Scan"?
**A:** A Scan is one completed execution of Stella Ops' vulnerability or artifact analysis
pipeline that produces a new result. The free tier allows up to 999 Scans per calendar day.
**Counts as a Scan:**
- First-time scan of a container image (new hash)
- Re-scan of a modified image (hash changed)
- SBOM generation for a new artifact
- VEX statement generation for new findings
**Does NOT count as a Scan:**
- Cache hits (retrieving previously scanned results)
- Viewing existing scan reports
- Policy evaluation on cached data
- API queries for existing results
**Deduplication:** Stella Ops uses hash-based deduplication. Scanning the same artifact
multiple times only counts as one Scan if the hash hasn't changed.
### Q7: What happens if my users exceed the free limits?
**A:** If users of your plugin exceed the free tier limits (3 Environments or 999 Scans/day):
1. **They need a commercial license** - The user (not the plugin developer) is responsible
for licensing compliance
2. **Your plugin continues to work** - There's no technical enforcement in the plugin itself
3. **Quota enforcement is server-side** - Stella Ops may introduce delays after limits
are exceeded (see `docs/legal/30_QUOTA_ENFORCEMENT_FLOW1.md`)
As a plugin developer, you should:
- Document the free tier limits in your plugin documentation
- Recommend users contact stella-ops.org for commercial licensing if they exceed limits
- Not build quota circumvention into your plugin
---
## Bundling & Distribution
### Q8: Can I bundle Stella Ops core with my plugin?
**A:** This depends on how you bundle:
**Allowed (aggregation):**
- Shipping your plugin alongside Stella Ops as separate components
- Docker Compose files that reference Stella Ops images
- Helm charts that deploy Stella Ops as a dependency
- Installation scripts that download Stella Ops separately
**Requires BUSL-1.1 compliance (derivative work):**
- Embedding Stella Ops source code into your plugin
- Modifying Stella Ops binaries and redistributing
- Creating a single binary that includes Stella Ops components
**Requires commercial license:**
- Bundling into a competing managed service offering
- White-labeling Stella Ops functionality
### Q9: Can I create a plugin that modifies Stella Ops behavior at runtime?
**A:** Yes, if the modification uses documented extension points:
**Allowed:**
- Plugins that register custom handlers via plugin APIs
- Extensions that add new endpoints or processing steps
- Integrations that intercept and transform data via documented hooks
**Not allowed without BUSL-1.1 derivative work compliance:**
- Runtime patching of Stella Ops binaries
- Monkey-patching internal classes or methods
- Replacing core components at runtime
The key distinction is whether you're using **documented public APIs** (allowed) vs.
**undocumented internal behavior** (derivative work).
---
## Commercial Considerations
### Q10: Can my plugin be used with Stella Ops commercial/SaaS offerings?
**A:** Yes. Plugins designed for the Community Plugin Grant are compatible with commercial
Stella Ops deployments. Commercial customers may use community plugins subject to their
commercial license terms.
### Q11: Do I need Licensor approval to publish a plugin?
**A:** No. You do not need approval from stella-ops.org to:
- Develop plugins
- Publish plugins (open source or commercial)
- List plugins in third-party marketplaces
However, stella-ops.org may maintain an official plugin registry with quality/security
standards for listed plugins.
### Q12: Can MSPs provide plugins to their managed customers?
**A:** Yes, with these considerations:
1. **Plugin distribution:** MSPs can freely distribute plugins to customers
2. **Stella Ops licensing:** Each customer deployment must comply with BUSL-1.1:
- Within free tier limits; OR
- Covered by MSP's commercial license; OR
- Customer has their own commercial license
See `docs/legal/SAAS_MSP_GUIDANCE.md` for detailed MSP scenarios.
---
## Edge Cases
### Q13: Does the Community Plugin Grant apply to unofficial API integrations?
**A:** The grant specifically covers plugins using "documented public plugin APIs or
integration points." For unofficial or undocumented APIs:
- Using undocumented APIs is at your own risk (they may change without notice)
- The Community Plugin Grant still applies if you're not modifying source code
- Relying on internal implementation details may create a derivative work
**Recommendation:** Use documented APIs for stable, supported integration.
### Q14: Can I fork Stella Ops and call it something else?
**A:** Forking is allowed under BUSL-1.1, but:
1. **BUSL-1.1 applies to the fork** - Production use requires compliance with the
Additional Use Grant or a commercial license
2. **Attribution required** - You must preserve LICENSE, NOTICE, and copyright notices
3. **No trademark use** - You may not use Stella Ops trademarks for your fork
4. **Change Date applies** - After the Change Date (2030-01-20), the fork converts to
Apache-2.0
### Q15: What if my plugin becomes popular and used beyond free tier limits?
**A:** Success is good! If your plugin enables usage beyond free tier limits:
1. **Users are responsible for licensing** - Not you as the plugin developer
2. **Consider partnership** - Contact stella-ops.org about potential partnership or
revenue sharing arrangements
3. **Document clearly** - Ensure your plugin documentation explains licensing requirements
### Q16: Can I host a free scanning service for the community using my plugin?
**A:** The BUSL-1.1 restriction specifically targets "public multi-tenant **paid** hosting."
Non-commercial, free-of-charge hosting for community benefit may be eligible for the
Community Program.
**Potentially eligible:**
- Free scanning for open source projects
- Academic/educational free access
- Non-profit services for other non-profits
**Not eligible (requires commercial license):**
- "Free tier" that upsells to paid services
- Free scanning bundled with paid consulting
- Any scenario where the free service drives commercial revenue
**Process:** Apply to the Community Program at community@stella-ops.org. Approval is
not automatic and is evaluated based on genuine community benefit.
See `docs/legal/SAAS_MSP_GUIDANCE.md` Section 4.3 for detailed guidance.
---
## Getting Help
**Technical questions about plugin development:**
- Documentation: `docs/plugins/`
- Community forum: https://community.stella-ops.org
**Licensing questions:**
- Email: legal@stella-ops.org
- FAQ: This document and `docs/legal/LEGAL_FAQ_QUOTA.md`
**Commercial licensing:**
- Email: sales@stella-ops.org
- Website: https://stella-ops.org/pricing
---
## See Also
- `LICENSE-ADDENDUM-COMMUNITY-PLUGIN-GRANT.md` - Full legal terms
- `docs/legal/LEGAL_FAQ_QUOTA.md` - Quota and free tier FAQ
- `docs/legal/SAAS_MSP_GUIDANCE.md` - MSP and SaaS guidance
- `docs/legal/LICENSE-COMPATIBILITY.md` - License compatibility for dependencies
---
*Document maintained by: Legal + Developer Relations*
*Last review: 2026-01-25*

View File

@@ -6,10 +6,21 @@ authoritative artifacts.
## Canonical documents
### Core License Files (Repository Root)
- Project license (BUSL-1.1 + Additional Use Grant): `LICENSE`
- Community Plugin Grant Addendum: `LICENSE-ADDENDUM-COMMUNITY-PLUGIN-GRANT.md`
- Third-party notices: `NOTICE.md`
### Compliance & Compatibility
- Full dependency inventory: `docs/legal/THIRD-PARTY-DEPENDENCIES.md`
- License compatibility guidance: `docs/legal/LICENSE-COMPATIBILITY.md`
- Additional Use Grant summary and quotas: `docs/legal/LEGAL_FAQ_QUOTA.md`
- Regulator-grade threat and evidence model: `docs/legal/LEGAL_COMPLIANCE.md`
- Cryptography compliance notes: `docs/legal/crypto-compliance-review.md`
### Plugin & Distribution Guidance
- Plugin developer FAQ: `docs/legal/PLUGIN_DEVELOPER_FAQ.md`
- SaaS and MSP licensing guidance: `docs/legal/SAAS_MSP_GUIDANCE.md`
- Enforcement and telemetry policy: `docs/legal/ENFORCEMENT_TELEMETRY_POLICY.md`
- Compliance attestation process: `docs/legal/COMPLIANCE_ATTESTATION_FORM.md`
- Self-attestation form template: `docs/legal/templates/self-attestation-form.md`

View File

@@ -0,0 +1,356 @@
# SaaS and MSP Licensing Guidance
**Document Version:** 1.0.0
**Last Updated:** 2026-01-25
This document provides detailed guidance on Stella Ops licensing for SaaS providers,
Managed Service Providers (MSPs), and hosting scenarios. For the full legal terms,
see `LICENSE-ADDENDUM-COMMUNITY-PLUGIN-GRANT.md`.
---
## Overview
The Stella Ops BUSL-1.1 license with Community Plugin Grant restricts providing Stella
Ops as a commercial hosted service to third parties. This document clarifies what is
and isn't permitted under different hosting scenarios.
**Key Principle:** The restriction targets commercial offerings that compete with
Stella Ops' own hosted services, not legitimate internal use or isolated customer
deployments.
---
## 1. Prohibited: Multi-Tenant SaaS Offerings
The following are **NOT permitted** without a commercial license:
### 1.1 Public SaaS Platform
**Prohibited:** Operating a multi-tenant SaaS platform that provides Stella Ops
functionality to paying customers.
**Example (prohibited):**
```
AcmeScan.io
├── Customer A (paying subscriber)
├── Customer B (paying subscriber)
├── Customer C (paying subscriber)
└── Shared Stella Ops infrastructure
```
**Why prohibited:** This directly competes with Stella Ops' commercial SaaS offering.
### 1.2 White-Label Hosting
**Prohibited:** Rebranding Stella Ops and selling it as your own hosted product.
**Example (prohibited):**
```
"PowerScan Pro" (white-labeled Stella Ops)
├── Sold as monthly subscription
├── Marketed as proprietary technology
└── Runs on shared infrastructure
```
**Why prohibited:** This is commercial redistribution as a competing service.
### 1.3 Embedded SaaS Features
**Prohibited:** Embedding Stella Ops scanning as a feature in your commercial SaaS product.
**Example (prohibited):**
```
AcmeDevPlatform.com (commercial SaaS)
├── Code repository feature
├── CI/CD pipeline feature
├── "Security Scanning" feature <- Powered by embedded Stella Ops
└── Charged as part of subscription
```
**Why prohibited:** Stella Ops functionality is being monetized as part of a third-party
service offering.
---
## 2. Permitted: Internal Use
The following **ARE permitted** under the Community Plugin Grant:
### 2.1 Internal Enterprise Deployment
**Permitted:** Deploying Stella Ops for your organization's internal use.
**Example (permitted):**
```
Acme Corp Internal
├── Development team scans
├── Security team analysis
├── Compliance reporting
└── Accessed only by Acme employees/contractors
```
**Why permitted:** Internal use for the licensee's own business operations.
### 2.2 Internal Platform Team
**Permitted:** A platform/DevOps team providing Stella Ops to internal development teams.
**Example (permitted):**
```
Acme Corp Platform Team
├── Hosts Stella Ops on internal infrastructure
├── Provides scanning service to:
│ ├── Team Alpha (internal)
│ ├── Team Beta (internal)
│ └── Team Gamma (internal)
└── All users are Acme employees
```
**Why permitted:** All users are within the same organization.
### 2.3 Subsidiary/Affiliate Use
**Permitted:** Parent company hosting for subsidiaries under common control.
**Example (permitted):**
```
Acme Holdings
├── Acme Corp (subsidiary) - uses hosted Stella Ops
├── Acme Europe (subsidiary) - uses hosted Stella Ops
└── Acme Asia (subsidiary) - uses hosted Stella Ops
```
**Why permitted:** Affiliates under common control are treated as one organization.
---
## 3. Permitted with Conditions: MSP Single-Tenant Hosting
Managed Service Providers may host Stella Ops for customers under specific conditions.
### 3.1 Single-Tenant Isolated Deployments
**Permitted (with commercial license):** MSP hosting separate Stella Ops instances for
each customer.
**Example (permitted with commercial license):**
```
AcmeMSP Infrastructure
├── Customer A Instance (isolated)
│ ├── Dedicated Stella Ops deployment
│ ├── Customer A data only
│ └── Covered by AcmeMSP commercial license
├── Customer B Instance (isolated)
│ ├── Dedicated Stella Ops deployment
│ ├── Customer B data only
│ └── Covered by AcmeMSP commercial license
└── No shared infrastructure between customers
```
**Requirements:**
- Each instance must be fully isolated
- MSP must have commercial license covering all instances
- Or each customer must have their own commercial license
### 3.2 Customer-Licensed Deployments
**Permitted:** MSP managing infrastructure where customer holds the license.
**Example (permitted):**
```
AcmeMSP (infrastructure only)
├── Customer A Infrastructure
│ ├── Customer A's Stella Ops license
│ ├── MSP manages infrastructure
│ └── Customer controls license compliance
└── Customer B Infrastructure
├── Customer B's Stella Ops license
└── MSP manages infrastructure
```
**Why permitted:** The customer (not MSP) is the licensee; MSP provides only
infrastructure management.
---
## 4. Gray Areas: Guidance for Common Scenarios
### 4.1 Consulting with Temporary Access
**Scenario:** Security consultant deploys Stella Ops at client site for an engagement.
**Analysis:**
- If consultant's license: Consultant needs commercial license for third-party use
- If client's license: Client uses their free tier or commercial license
**Recommendation:** Client should obtain their own license; consultant assists with
deployment.
### 4.2 Training/Demo Environments
**Scenario:** Providing training environments with Stella Ops to external trainees.
**Analysis:**
- Temporary, non-production training: Generally permitted under non-production use
- Ongoing access for trainees: May require commercial license depending on duration
**Recommendation:** Contact legal@stella-ops.org for training program licensing.
### 4.3 Non-Commercial Community Hosting
**Scenario:** Hosting Stella Ops scanning as a free service for community benefit.
The BUSL-1.1 restriction specifically targets "public multi-tenant **paid** hosting."
Non-commercial hosting for community benefit may be eligible for the Community Program.
**Examples of potentially eligible scenarios:**
- Free scanning services for open source projects
- Academic/educational institutions providing free access to students
- Non-profit organizations providing free services to other non-profits
- Community-run instances for local developer communities
**Requirements for Community Program consideration:**
1. Service must be genuinely free (no fees, subscriptions, or required purchases)
2. Service must not be a loss-leader for commercial offerings
3. Service must not compete directly with Licensor's commercial offerings
4. Organization must apply and be approved by Licensor
**Analysis:**
- Non-commercial, community benefit: Contact community@stella-ops.org for evaluation
- If charging any fees: Requires commercial license (not eligible for Community Program)
- If bundled with paid services: Requires commercial license
**Recommendation:** Apply for Community Program at https://stella-ops.org/community
**Important:** Community Program approval is not automatic. Licensor reserves the right
to evaluate each application based on community benefit, competitive impact, and
alignment with program goals.
### 4.4 Reseller/Channel Partner
**Scenario:** Reselling Stella Ops commercial licenses with implementation services.
**Analysis:**
- Reselling licenses: Requires authorized reseller agreement
- Implementation services: Permitted under customer's license
**Recommendation:** Contact sales@stella-ops.org for reseller program details.
---
## 5. Compliance Checklist
### For Internal Deployments
- [ ] All users are employees, contractors, or affiliates of the licensee
- [ ] Deployment is within free tier limits (3 environments, 999 scans/day) OR
commercial license obtained
- [ ] LICENSE and NOTICE files preserved
- [ ] No third-party access to functionality
### For MSP Deployments
- [ ] Each customer instance is fully isolated
- [ ] Either MSP or customer holds valid license for each instance
- [ ] No shared multi-tenant infrastructure
- [ ] Clear documentation of license responsibility
- [ ] Annual compliance attestation completed
### For Any Hosted Scenario
- [ ] Not marketed as competing SaaS product
- [ ] Not white-labeled or rebranded
- [ ] Not embedded in commercial SaaS offering
- [ ] Attribution requirements met
---
## 6. Decision Tree
```
Is Stella Ops functionality being provided to third parties?
├─ NO → Internal use permitted (within free tier or with commercial license)
└─ YES → Is it a commercial offering (paid or part of paid service)?
├─ NO (genuinely free, community benefit)
│ │
│ ├─ Apply for Community Program (community@stella-ops.org)
│ │
│ └─ If approved → Permitted under Community Program terms
│ If not approved → Commercial license required
└─ YES (paid, or free-as-loss-leader for paid services)
└─ Is each customer fully isolated (single-tenant)?
├─ NO → Commercial SaaS license required
│ (contact sales@stella-ops.org)
└─ YES → MSP single-tenant model
├─ MSP holds commercial license covering all instances
│ → Permitted
└─ Each customer holds their own license
→ Permitted (MSP provides infrastructure only)
```
**Key distinction:** The restriction targets "public multi-tenant **paid** hosting."
Non-commercial hosting for genuine community benefit may qualify for the Community Program,
but requires explicit approval from Licensor.
---
## 7. Examples of Compliance Violations
The following are examples of arrangements that would violate the license:
1. **"Vulnerability Scanning as a Service"** - Public signup for scanning services
powered by Stella Ops without commercial license
2. **DevSecOps Platform Bundle** - Including Stella Ops scanning in a paid platform
subscription without commercial license
3. **Shared MSP Instance** - Multiple MSP customers sharing a single Stella Ops
deployment
4. **"Free Tier Arbitrage"** - Running multiple free-tier installations to serve
third-party customers
5. **Competitive Forking** - Forking Stella Ops and offering it as a competing
hosted service
---
## 8. Getting Commercial License
If your use case requires a commercial license:
**Contact:**
- Email: sales@stella-ops.org
- Website: https://stella-ops.org/pricing
**License options include:**
- Per-environment licensing
- Unlimited scan licensing
- MSP/reseller programs
- OEM/embedded licensing
**Volume discounts** available for MSPs and enterprise deployments.
---
## See Also
- `LICENSE-ADDENDUM-COMMUNITY-PLUGIN-GRANT.md` - Full legal terms
- `docs/legal/LEGAL_FAQ_QUOTA.md` - Quota and free tier FAQ
- `docs/legal/PLUGIN_DEVELOPER_FAQ.md` - Plugin developer questions
- `docs/legal/ENFORCEMENT_TELEMETRY_POLICY.md` - Audit and compliance verification
---
*Document maintained by: Legal + Sales Operations*
*Last review: 2026-01-25*

View File

@@ -0,0 +1,188 @@
# Stella Ops Compliance Self-Attestation Form
**Form Version:** 1.0.0
**Attestation Period:** [YEAR]
---
## Instructions
1. Complete all sections marked with `[ ]` or `___`
2. Replace placeholder text `[...]` with your information
3. Have an authorized representative sign
4. Submit to: compliance@stella-ops.org
5. Retain a copy for your records
---
## Section 1: Operator Information
| Field | Value |
|-------|-------|
| **Organization Legal Name** | [Full legal name of organization] |
| **Primary Contact Name** | [Name of compliance contact] |
| **Primary Contact Email** | [Email address] |
| **Primary Contact Phone** | [Phone number - optional] |
| **Mailing Address** | [Business address] |
| **Installation ID** | [From /admin/compliance dashboard, or "Not Available"] |
| **Attestation Date** | [YYYY-MM-DD] |
---
## Section 2: Usage Declaration
### 2.1 Environment Count
Current number of active Environments in this installation:
- [ ] 1 Environment
- [ ] 2 Environments
- [ ] 3 Environments
- [ ] More than 3 Environments
If more than 3 Environments, commercial license reference: _______________
### 2.2 Scan Volume
Peak daily scan volume (new hash scans) in the past 12 months:
- [ ] Under 100 scans/day
- [ ] 100 - 499 scans/day
- [ ] 500 - 999 scans/day
- [ ] Over 999 scans/day
If over 999 scans/day, commercial license reference: _______________
### 2.3 Usage Metrics Source
How were the above metrics determined?
- [ ] Stella Ops admin dashboard
- [ ] API metrics endpoint
- [ ] Log analysis
- [ ] Estimate based on operational knowledge
- [ ] Other: _______________
---
## Section 3: Distribution Declaration
### 3.1 Redistribution Status
- [ ] We do NOT redistribute Stella Ops or Stella Ops Plugins
- [ ] We redistribute Stella Ops (complete Section 3.2)
- [ ] We redistribute Plugins only (complete Section 3.3)
### 3.2 Stella Ops Redistribution (if applicable)
- [ ] LICENSE file included in all distributions
- [ ] NOTICE.md file included in all distributions
- [ ] LICENSE-ADDENDUM-COMMUNITY-PLUGIN-GRANT.md included
- [ ] Modified files marked with change notices
- [ ] Not offered as competing managed service
Distribution channels: _______________
### 3.3 Plugin Redistribution (if applicable)
- [ ] Plugin does not include Stella Ops source code
- [ ] Attribution to Stella Ops included
- [ ] Plugin documentation references Stella Ops licensing
Plugin name(s): _______________
---
## Section 4: SaaS / MSP Declaration
### 4.1 Deployment Model
Select ONE:
- [ ] **Internal Use Only**
- Stella Ops accessed only by our employees, contractors, and affiliates
- No third-party access to Stella Ops functionality
- [ ] **MSP Single-Tenant Hosting**
- We host isolated Stella Ops instances for customers
- Complete Section 4.2
- [ ] **Commercial SaaS License**
- We have a commercial license for SaaS/hosted use
- License reference: _______________
### 4.2 MSP Details (if applicable)
Number of customer instances hosted: _______________
License coverage:
- [ ] Our commercial license covers all customer instances
- [ ] Each customer has their own Stella Ops license
- [ ] Mixed (describe): _______________
Instance isolation:
- [ ] Each customer has dedicated infrastructure (compute, storage)
- [ ] No data sharing between customer instances
- [ ] Customers cannot access each other's data or results
---
## Section 5: Certification
I certify that:
1. [ ] The information in this attestation is accurate and complete to the best of
my knowledge
2. [ ] Our organization's use of Stella Ops complies with the Business Source
License 1.1 and the Community Plugin Grant Addendum
3. [ ] I am authorized to make this attestation on behalf of the organization
named above
4. [ ] I understand that knowingly providing false information may result in
termination of license rights
5. [ ] I will notify stella-ops.org within 30 days of any material changes to
the information provided
---
## Section 6: Signature
| Field | Value |
|-------|-------|
| **Printed Name** | ___________________________ |
| **Title/Role** | ___________________________ |
| **Signature** | ___________________________ |
| **Date** | ___________________________ |
---
## Section 7: Internal Use Only (stella-ops.org)
| Field | Value |
|-------|-------|
| Received Date | |
| Reviewed By | |
| Review Date | |
| Status | [ ] Accepted [ ] Clarification Needed [ ] Referred to Sales |
| Confirmation Sent | |
| Notes | |
---
## Submission
**Email completed form to:** compliance@stella-ops.org
**Subject line:** `Compliance Attestation - [Organization Name] - [Year]`
**Attachments (optional but recommended):**
- Screenshot of /admin/compliance dashboard
- Usage report export (if available)
---
*Form version 1.0.0 | Effective 2026-01-25*
*Questions? Contact legal@stella-ops.org*

View File

@@ -0,0 +1,358 @@
# Trust Architecture Diagrams
> Sprint: SPRINT_20260125_003 - WORKFLOW-008
> Last updated: 2026-01-25
This document provides architectural diagrams for the StellaOps TUF-based trust
distribution system.
---
## 1. Trust Hierarchy
The TUF trust hierarchy showing roles and key relationships.
```mermaid
graph TB
subgraph "TUF Roles & Keys"
ROOT[("Root<br/>(threshold: 3/5)")]
TARGETS[("Targets<br/>(threshold: 1)")]
SNAPSHOT[("Snapshot<br/>(threshold: 1)")]
TIMESTAMP[("Timestamp<br/>(threshold: 1)")]
end
subgraph "Trust Targets"
REKOR_KEY["Rekor Public Key<br/>rekor-key-v1.pub"]
FULCIO_CHAIN["Fulcio Chain<br/>fulcio-chain.pem"]
SERVICE_MAP["Service Map<br/>sigstore-services-v1.json"]
ORG_KEY["Org Signing Key<br/>org-signing-key.pub"]
end
ROOT --> TARGETS
ROOT --> SNAPSHOT
ROOT --> TIMESTAMP
SNAPSHOT --> TARGETS
TIMESTAMP --> SNAPSHOT
TARGETS --> REKOR_KEY
TARGETS --> FULCIO_CHAIN
TARGETS --> SERVICE_MAP
TARGETS --> ORG_KEY
style ROOT fill:#ff6b6b,stroke:#333,stroke-width:2px
style TARGETS fill:#4ecdc4,stroke:#333
style SNAPSHOT fill:#45b7d1,stroke:#333
style TIMESTAMP fill:#96ceb4,stroke:#333
```
### Role Descriptions
| Role | Purpose | Update Frequency |
|------|---------|-----------------|
| Root | Ultimate trust anchor, defines all other roles | Rarely (ceremony) |
| Targets | Lists trusted targets with hashes | When targets change |
| Snapshot | Point-in-time view of all metadata | With targets |
| Timestamp | Freshness guarantee | Every few hours |
---
## 2. Online Verification Flow
Client verification of attestations when network is available.
```mermaid
sequenceDiagram
participant Client as StellaOps Client
participant TUF as TUF Repository
participant Rekor as Rekor Transparency Log
participant Cache as Local Cache
Note over Client: Start verification
Client->>Cache: Check TUF metadata freshness
alt Metadata stale
Client->>TUF: Fetch timestamp.json
TUF-->>Client: timestamp.json
Client->>TUF: Fetch snapshot.json (if needed)
TUF-->>Client: snapshot.json
Client->>TUF: Fetch targets.json (if needed)
TUF-->>Client: targets.json
Client->>Cache: Update cached metadata
end
Client->>Cache: Load Rekor public key
Client->>Cache: Load service map
Note over Client: Resolve Rekor URL from service map
Client->>Rekor: GET /api/v2/log/entries/{uuid}/proof
Rekor-->>Client: Inclusion proof + checkpoint
Note over Client: Verify:
Note over Client: 1. Checkpoint signature (Rekor key)
Note over Client: 2. Merkle inclusion proof
Note over Client: 3. Entry matches attestation
Client-->>Client: Verification Result
```
---
## 3. Offline Verification Flow
Client verification using sealed trust bundle (air-gapped).
```mermaid
sequenceDiagram
participant Client as StellaOps Client
participant Bundle as Trust Bundle
participant Tiles as Cached Tiles
Note over Client: Start offline verification
Client->>Bundle: Load TUF metadata
Bundle-->>Client: root.json, targets.json, etc.
Client->>Bundle: Load Rekor public key
Bundle-->>Client: rekor-key-v1.pub
Client->>Bundle: Load checkpoint
Bundle-->>Client: Signed checkpoint
Note over Client: Verify checkpoint signature
Client->>Tiles: Load Merkle tiles for proof
Tiles-->>Client: tile/data/..., tile/...
Note over Client: Reconstruct inclusion proof
Client->>Client: Verify Merkle path
Note over Client: No network calls required!
Client-->>Client: Verification Result
```
### Trust Bundle Contents
```
trust-bundle.tar.zst/
├── manifest.json # Bundle metadata & checksums
├── tuf/
│ ├── root.json
│ ├── targets.json
│ ├── snapshot.json
│ └── timestamp.json
├── targets/
│ ├── rekor-key-v1.pub
│ ├── sigstore-services-v1.json
│ └── fulcio-chain.pem
└── tiles/ # Pre-fetched Merkle tiles
├── checkpoint
└── tile/
├── 0/...
├── 1/...
└── data/...
```
---
## 4. Key Rotation Flow
Dual-key rotation with grace period.
```mermaid
stateDiagram-v2
[*] --> SingleKey: Initial State
SingleKey --> DualKey: Add new key
DualKey --> DualKey: Grace period<br/>(7-14 days)
DualKey --> SingleKey: Remove old key
SingleKey --> [*]
note right of SingleKey
Only one key trusted
All signatures use this key
end note
note right of DualKey
Both keys trusted
Old attestations verify (old key)
New attestations verify (new key)
Clients sync new key
end note
```
### Detailed Rotation Timeline
```mermaid
gantt
title Key Rotation Timeline
dateFormat YYYY-MM-DD
section TUF Admin
Generate new key :done, gen, 2026-01-01, 1d
Add to TUF repository :done, add, after gen, 1d
Sign & publish metadata :done, pub, after add, 1d
section Grace Period
Dual-key active :active, grace, after pub, 14d
Monitor client sync :monitor, after pub, 14d
section Completion
Remove old key :remove, after grace, 1d
Sign & publish final :final, after remove, 1d
```
---
## 5. Failover Flow
Circuit breaker and mirror failover during primary outage.
```mermaid
stateDiagram-v2
[*] --> Closed: Normal operation
state "Circuit Breaker" as CB {
Closed --> Open: Failures > threshold
Open --> HalfOpen: After timeout
HalfOpen --> Closed: Success
HalfOpen --> Open: Failure
}
state "Request Routing" as Routing {
Primary: Primary Rekor
Mirror: Mirror Rekor
}
Closed --> Primary: Route to primary
Open --> Mirror: Failover to mirror
HalfOpen --> Primary: Probe primary
note right of Open
Primary unavailable
Use mirror if configured
Cache tiles locally
end note
```
### Failover Decision Tree
```mermaid
flowchart TD
START([Request]) --> CB{Circuit<br/>Breaker<br/>State?}
CB -->|Closed| PRIMARY[Try Primary]
CB -->|Open| MIRROR_CHECK{Mirror<br/>Enabled?}
CB -->|HalfOpen| PROBE[Probe Primary]
PRIMARY -->|Success| SUCCESS([Return Result])
PRIMARY -->|Failure| RECORD[Record Failure]
RECORD --> THRESHOLD{Threshold<br/>Exceeded?}
THRESHOLD -->|Yes| OPEN_CB[Open Circuit]
THRESHOLD -->|No| FAIL([Return Error])
OPEN_CB --> MIRROR_CHECK
MIRROR_CHECK -->|Yes| MIRROR[Try Mirror]
MIRROR_CHECK -->|No| CACHE{Cached<br/>Data?}
MIRROR -->|Success| SUCCESS
MIRROR -->|Failure| CACHE
CACHE -->|Yes| CACHED([Return Cached])
CACHE -->|No| FAIL
PROBE -->|Success| CLOSE_CB[Close Circuit]
PROBE -->|Failure| OPEN_CB
CLOSE_CB --> SUCCESS
```
---
## 6. Component Architecture
Full system component view.
```mermaid
graph TB
subgraph "Client Layer"
CLI[stella CLI]
SDK[StellaOps SDK]
end
subgraph "Trust Layer"
TUF_CLIENT[TUF Client]
CACHE[(Local Cache)]
CB[Circuit Breaker]
end
subgraph "Service Layer"
TUF_SERVER[TUF Server]
REKOR_PRIMARY[Rekor Primary]
REKOR_MIRROR[Rekor Mirror / Tile Proxy]
end
subgraph "Storage Layer"
TUF_STORE[(TUF Metadata)]
LOG_STORE[(Transparency Log)]
TILE_STORE[(Tile Storage)]
end
CLI --> TUF_CLIENT
SDK --> TUF_CLIENT
TUF_CLIENT --> CACHE
TUF_CLIENT --> CB
CB --> REKOR_PRIMARY
CB --> REKOR_MIRROR
TUF_CLIENT --> TUF_SERVER
TUF_SERVER --> TUF_STORE
REKOR_PRIMARY --> LOG_STORE
REKOR_MIRROR --> TILE_STORE
style CB fill:#ff9999
style CACHE fill:#99ff99
```
---
## 7. Data Flow Summary
```mermaid
flowchart LR
subgraph "Bootstrap"
A[Initialize TUF] --> B[Fetch Root]
B --> C[Fetch Metadata Chain]
C --> D[Cache Targets]
end
subgraph "Attestation"
E[Create Attestation] --> F[Sign DSSE]
F --> G[Submit to Rekor]
G --> H[Store Proof]
end
subgraph "Verification"
I[Load Attestation] --> J[Check TUF Freshness]
J --> K[Fetch Inclusion Proof]
K --> L[Verify Merkle Path]
L --> M[Check Checkpoint Sig]
M --> N[Return Result]
end
D --> E
H --> I
```
---
## Related Documentation
- [TUF Integration Guide](../tuf-integration.md)
- [Rekor Verification Design](../rekor-verification-design.md)
- [Bootstrap Guide](../../../operations/bootstrap-guide.md)
- [Key Rotation Runbook](../../../operations/key-rotation-runbook.md)
- [Disaster Recovery](../../../operations/disaster-recovery.md)

View File

@@ -0,0 +1,262 @@
# Tile-Proxy Service Design
## Overview
The Tile-Proxy service acts as an intermediary between StellaOps clients and upstream Rekor transparency log APIs. It provides centralized tile caching, request coalescing, and offline support for air-gapped environments.
## Architecture
```
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ CI/CD Agents │────►│ Tile Proxy │────►│ Rekor API │
│ (StellaOps) │ │ (StellaOps) │ │ (Upstream) │
└─────────────────┘ └────────┬────────┘ └─────────────────┘
┌───────────────────────┼───────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Tile Cache │ │ TUF Metadata │ │ Checkpoint │
│ (CAS Store) │ │ (TrustRepo) │ │ Cache │
└─────────────────┘ └─────────────────┘ └─────────────────┘
```
## Core Responsibilities
1. **Tile Proxying**: Forward tile requests to upstream Rekor, caching responses locally
2. **Content-Addressed Storage**: Store tiles by hash for deduplication and immutability
3. **TUF Integration**: Optionally validate metadata using TUF trust anchors
4. **Request Coalescing**: Deduplicate concurrent requests for the same tile
5. **Checkpoint Caching**: Cache and serve recent checkpoints
6. **Offline Mode**: Serve from cache when upstream is unavailable
## API Surface
### Proxy Endpoints (Passthrough)
| Endpoint | Description |
|----------|-------------|
| `GET /tile/{level}/{index}` | Proxy tile request (cache-through) |
| `GET /tile/{level}/{index}.p/{partialWidth}` | Proxy partial tile |
| `GET /checkpoint` | Proxy checkpoint request |
| `GET /api/v1/log/entries/{uuid}` | Proxy entry lookup |
### Admin Endpoints
| Endpoint | Description |
|----------|-------------|
| `GET /_admin/cache/stats` | Cache statistics (hits, misses, size) |
| `POST /_admin/cache/sync` | Trigger manual sync job |
| `DELETE /_admin/cache/prune` | Prune old tiles |
| `GET /_admin/health` | Health check |
| `GET /_admin/ready` | Readiness check |
## Caching Strategy
### Content-Addressed Tile Storage
Tiles are stored using content-addressed paths based on SHA-256 hash:
```
{cache_root}/
├── tiles/
│ ├── {origin_hash}/
│ │ ├── {level}/
│ │ │ ├── {index}.tile
│ │ │ └── {index}.meta.json
│ │ └── checkpoints/
│ │ └── {tree_size}.checkpoint
│ └── ...
└── metadata/
└── cache_stats.json
```
### Tile Metadata
Each tile has associated metadata:
```json
{
"cachedAt": "2026-01-25T10:00:00Z",
"treeSize": 1050000,
"isPartial": false,
"contentHash": "sha256:abc123...",
"upstreamUrl": "https://rekor.sigstore.dev"
}
```
### Eviction Policy
1. **LRU by Access Time**: Least recently accessed tiles evicted first
2. **Max Size Limit**: Configurable maximum cache size
3. **TTL Override**: Force re-fetch after configurable time (for checkpoints)
4. **Immutability Preservation**: Full tiles (width=256) never evicted unless explicitly pruned
## Request Coalescing
Concurrent requests for the same tile are coalesced:
```csharp
// Pseudo-code for request coalescing
var key = $"{origin}/{level}/{index}";
if (_inflightRequests.TryGetValue(key, out var existing))
{
return await existing; // Wait for in-flight request
}
var tcs = new TaskCompletionSource<byte[]>();
_inflightRequests[key] = tcs.Task;
try
{
var tile = await FetchFromUpstream(origin, level, index);
tcs.SetResult(tile);
return tile;
}
finally
{
_inflightRequests.Remove(key);
}
```
## TUF Integration Point
When `TufValidationEnabled` is true:
1. Load service map from TUF to discover Rekor URL
2. Validate Rekor public key from TUF targets
3. Verify checkpoint signatures using TUF-loaded keys
4. Reject tiles if checkpoint signature invalid
## Upstream Failover
Support multiple upstream sources with failover:
```yaml
tile_proxy:
upstreams:
- url: https://rekor.sigstore.dev
priority: 1
timeout: 30s
- url: https://rekor-mirror.internal
priority: 2
timeout: 10s
```
Failover behavior:
1. Try primary upstream first
2. On timeout/error, try next upstream
3. Cache successful source for subsequent requests
4. Reset failover state on explicit refresh
## Deployment Model
### Standalone Service
Run as dedicated service with persistent volume:
```yaml
services:
tile-proxy:
image: stellaops/tile-proxy:latest
ports:
- "8090:8080"
volumes:
- tile-cache:/var/cache/stellaops/tiles
- tuf-cache:/var/cache/stellaops/tuf
environment:
- TILE_PROXY__UPSTREAM_URL=https://rekor.sigstore.dev
- TILE_PROXY__TUF_URL=https://trust.stella-ops.org/tuf/
```
### Sidecar Mode
Run alongside attestor service:
```yaml
services:
attestor:
image: stellaops/attestor:latest
environment:
- ATTESTOR__REKOR_URL=http://localhost:8090 # Use sidecar
tile-proxy:
image: stellaops/tile-proxy:latest
network_mode: "service:attestor"
```
## Metrics
Prometheus metrics exposed at `/_admin/metrics`:
| Metric | Type | Description |
|--------|------|-------------|
| `tile_proxy_cache_hits_total` | Counter | Total cache hits |
| `tile_proxy_cache_misses_total` | Counter | Total cache misses |
| `tile_proxy_cache_size_bytes` | Gauge | Current cache size |
| `tile_proxy_upstream_requests_total` | Counter | Upstream requests by status |
| `tile_proxy_request_duration_seconds` | Histogram | Request latency |
| `tile_proxy_sync_last_success_timestamp` | Gauge | Last successful sync time |
## Configuration
```yaml
tile_proxy:
# Upstream Rekor configuration
upstream_url: https://rekor.sigstore.dev
tile_base_url: https://rekor.sigstore.dev/tile/
# TUF integration (optional)
tuf:
enabled: true
url: https://trust.stella-ops.org/tuf/
validate_checkpoint_signature: true
# Cache configuration
cache:
base_path: /var/cache/stellaops/tiles
max_size_gb: 10
eviction_policy: lru
checkpoint_ttl_minutes: 5
# Sync job configuration
sync:
enabled: true
schedule: "0 */6 * * *"
depth: 10000
# Request handling
coalescing:
enabled: true
max_wait_ms: 5000
# Failover
failover:
enabled: true
retry_count: 2
retry_delay_ms: 1000
```
## Security Considerations
1. **No Authentication by Default**: Designed for internal network use
2. **Optional mTLS**: Can enable client certificate validation
3. **Rate Limiting**: Optional rate limiting per client IP
4. **Audit Logging**: Log all cache operations for compliance
5. **Immutable Tiles**: Full tiles are never modified after caching
## Error Handling
| Scenario | Behavior |
|----------|----------|
| Upstream unavailable | Serve from cache if available; 503 otherwise |
| Invalid tile data | Reject, don't cache, log error |
| Cache full | Evict LRU tiles, continue serving |
| TUF validation fails | Reject request, return 502 |
| Checkpoint stale | Refresh from upstream, warn in logs |
## Future Enhancements
1. **Tile Prefetching**: Prefetch tiles for known verification patterns
2. **Multi-Log Support**: Support multiple transparency logs
3. **Replication**: Sync cache between proxy instances
4. **Compression**: Optional tile compression for storage

View File

@@ -0,0 +1,287 @@
# TUF Integration Guide
This guide explains how StellaOps uses The Update Framework (TUF) for secure trust
distribution and how to configure TUF-based trust management.
## Overview
TUF provides a secure method for distributing and updating trust anchors (public keys,
service endpoints) without requiring client reconfiguration. StellaOps uses TUF to:
- Distribute Rekor public keys for checkpoint verification
- Distribute Fulcio certificate chains for keyless signing
- Provide service endpoint discovery (Rekor, Fulcio URLs)
- Enable secure key rotation with grace periods
- Support offline verification with bundled trust state
## Architecture
```
┌─────────────────────────────────────────────────────────────────┐
│ TUF Trust Hierarchy │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────┐ │
│ │ Root │ ← Offline, rotates rarely (yearly) │
│ │ Key │ │
│ └────┬────┘ │
│ │ │
│ ┌────┴────────────────────────────┐ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Snapshot │ │Timestamp │ │ Targets │ │
│ │ Key │ │ Key │ │ Key │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ snapshot.json timestamp.json targets.json │
│ │ │ │
│ │ ├── rekor-key-v1.pub │
│ │ ├── rekor-key-v2.pub │
│ │ ├── fulcio-chain.pem │
│ │ └── sigstore-services-v1.json │
│ │ │
│ └── Refreshed frequently (daily) │
│ │
└─────────────────────────────────────────────────────────────────┘
```
## TUF Roles
### Root
- Signs the root metadata containing all role keys
- Highest trust level, rotates rarely
- Should be kept offline in secure storage (HSM, air-gapped system)
- Used only for initial setup and key rotation ceremonies
### Timestamp
- Signs timestamp metadata indicating freshness
- Must be refreshed frequently (default: daily)
- Clients reject metadata older than expiration
- Can be automated with short-lived credentials
### Snapshot
- Signs snapshot metadata listing current target versions
- Updated when targets change
- Prevents rollback attacks
### Targets
- Signs metadata for actual target files
- Lists hashes and sizes for verification
- Supports delegations for large repositories
## Configuration
### Attestor Configuration
```yaml
attestor:
trust_repo:
enabled: true
tuf_url: https://trust.yourcompany.com/tuf/
refresh_interval_minutes: 60
freshness_threshold_days: 7
offline_mode: false
local_cache_path: /var/lib/stellaops/tuf-cache
service_map_target: sigstore-services-v1
rekor_key_targets:
- rekor-key-v1
- rekor-key-v2
```
### Configuration Options
| Option | Description | Default |
|--------|-------------|---------|
| `enabled` | Enable TUF-based trust distribution | `false` |
| `tuf_url` | URL to TUF repository root | Required |
| `refresh_interval_minutes` | How often to check for updates | `60` |
| `freshness_threshold_days` | Max age before rejecting metadata | `7` |
| `offline_mode` | Use bundled metadata only | `false` |
| `local_cache_path` | Local metadata cache directory | OS-specific |
| `service_map_target` | TUF target name for service map | `sigstore-services-v1` |
| `rekor_key_targets` | TUF target names for Rekor keys | `["rekor-key-v1"]` |
### Environment Variables
| Variable | Description |
|----------|-------------|
| `STELLA_TUF_ROOT_URL` | Override TUF repository URL |
| `STELLA_SIGSTORE_SERVICE_MAP` | Path to local service map override |
| `STELLA_TUF_OFFLINE_MODE` | Force offline mode (`true`/`false`) |
## CLI Usage
### Initialize Trust
```bash
# Initialize with a TUF repository
stella trust init \
--tuf-url https://trust.yourcompany.com/tuf/ \
--service-map sigstore-services-v1 \
--pin rekor-key-v1 rekor-key-v2
# Initialize in offline mode with bundled metadata
stella trust init \
--tuf-url file:///path/to/bundled-trust/ \
--offline
```
### Sync Metadata
```bash
# Refresh TUF metadata
stella trust sync
# Force refresh even if fresh
stella trust sync --force
```
### Check Status
```bash
# Show current trust state
stella trust status
# Show with key details
stella trust status --show-keys --show-endpoints
```
### Export for Offline Use
```bash
# Export trust state
stella trust export --out ./trust-bundle/
# Create sealed snapshot with tiles
stella trust snapshot export \
--out ./snapshots/2026-01-25.tar.zst \
--depth 10000
```
### Import Offline Bundle
```bash
# Import trust bundle
stella trust import ./snapshots/2026-01-25.tar.zst \
--verify-manifest \
--reject-if-stale 7d
```
## Service Map
The service map (`sigstore-services-v1.json`) contains endpoint URLs for Sigstore
services. This enables endpoint changes without client reconfiguration.
### Schema
```json
{
"version": 1,
"rekor": {
"url": "https://rekor.sigstore.dev",
"log_id": "c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d",
"public_key_target": "rekor-key-v1"
},
"fulcio": {
"url": "https://fulcio.sigstore.dev",
"root_cert_target": "fulcio-chain.pem"
},
"overrides": {
"staging": {
"rekor_url": "https://rekor.sigstage.dev"
}
}
}
```
### Site-Local Overrides
Organizations can define environment-specific overrides:
```yaml
attestor:
trust_repo:
environment: staging # Use staging overrides from service map
```
## Key Rotation
TUF supports secure key rotation with grace periods:
1. **Add new key**: Publish new key while keeping old key active
2. **Grace period**: Clients sync and receive both keys
3. **Verify**: Ensure all clients have new key
4. **Revoke old key**: Remove old key from active set
See [Key Rotation Runbook](../../operations/key-rotation-runbook.md) for detailed procedures.
## Offline Mode
For air-gapped environments, StellaOps can operate with bundled TUF metadata:
1. Export trust state on connected system:
```bash
stella trust snapshot export --out ./bundle.tar.zst
```
2. Transfer bundle to air-gapped system
3. Import on air-gapped system:
```bash
stella trust import ./bundle.tar.zst --offline
```
4. Verify attestations using bundled trust:
```bash
stella attest verify ./attestation.json --offline
```
## Troubleshooting
### "TUF metadata expired"
The timestamp hasn't been refreshed. On the TUF repository:
```bash
./scripts/update-timestamp.sh
```
### "Unknown target"
The requested target doesn't exist in the repository:
```bash
./scripts/add-target.sh /path/to/target target-name
```
### "Signature verification failed"
Keys may have rotated. Force a sync:
```bash
stella trust sync --force
```
### "Service map not found"
Ensure the service map target name matches configuration:
```bash
stella trust status # Check service_map_target value
```
## Security Considerations
1. **Root Key Security**: Keep root key offline. Only use for initial setup and rotations.
2. **Timestamp Automation**: Automate timestamp updates but use short-lived credentials.
3. **Monitoring**: Monitor for failed TUF fetches - may indicate MITM or repository issues.
4. **Rollback Protection**: TUF prevents rollback attacks through version tracking.
5. **Freshness**: Configure appropriate freshness thresholds for your security requirements.
## References
- [TUF Specification](https://theupdateframework.github.io/specification/latest/)
- [Sigstore Trust Root](https://github.com/sigstore/root-signing)
- [StellaOps Trust Repository Template](../../../devops/trust-repo-template/)

View File

@@ -0,0 +1,23 @@
{
"eventId": "d4e5f6a7-89ab-cdef-0123-456789abcdef",
"kind": "attestor.logged",
"version": "1",
"tenant": "tenant-01",
"ts": "2025-12-24T13:00:00+00:00",
"actor": "attestor-service",
"payload": {
"attestationId": "attest-001-20251224",
"imageDigest": "sha256:abc123def456789012345678901234567890123456789012345678901234abcd",
"imageName": "registry.example.com/app:v1.0.0",
"predicateType": "https://slsa.dev/provenance/v1",
"logIndex": 12345,
"links": {
"attestation": "https://stellaops.example.com/attestations/attest-001-20251224",
"rekor": "https://rekor.sigstore.dev/api/v1/log/entries?logIndex=12345"
}
},
"attributes": {
"category": "attestor",
"logProvider": "rekor"
}
}

View File

@@ -0,0 +1,24 @@
{
"eventId": "b2c3d4e5-6789-abcd-ef01-23456789abcd",
"kind": "scanner.report.ready",
"version": "1",
"tenant": "tenant-01",
"ts": "2025-12-24T11:00:00+00:00",
"actor": "scanner-worker",
"payload": {
"reportId": "report-001-20251224",
"scanId": "scan-001-20251224",
"imageDigest": "sha256:abc123def456789012345678901234567890123456789012345678901234abcd",
"imageName": "registry.example.com/app:v1.0.0",
"format": "cyclonedx",
"size": 524288,
"links": {
"report": "https://stellaops.example.com/reports/report-001-20251224",
"download": "https://stellaops.example.com/reports/report-001-20251224/download"
}
},
"attributes": {
"category": "scanner",
"reportFormat": "cyclonedx-1.5"
}
}

View File

@@ -0,0 +1,30 @@
{
"eventId": "a1b2c3d4-5678-9abc-def0-123456789abc",
"kind": "scanner.scan.completed",
"version": "1",
"tenant": "tenant-01",
"ts": "2025-12-24T10:30:00+00:00",
"actor": "scanner-worker",
"payload": {
"scanId": "scan-001-20251224",
"imageDigest": "sha256:abc123def456789012345678901234567890123456789012345678901234abcd",
"imageName": "registry.example.com/app:v1.0.0",
"verdict": "pass",
"findingsCount": 7,
"vulnerabilities": {
"critical": 0,
"high": 0,
"medium": 2,
"low": 5
},
"scanDurationMs": 15230,
"links": {
"findings": "https://stellaops.example.com/scans/scan-001-20251224/findings",
"sbom": "https://stellaops.example.com/scans/scan-001-20251224/sbom"
}
},
"attributes": {
"category": "scanner",
"environment": "production"
}
}

View File

@@ -0,0 +1,23 @@
{
"eventId": "c3d4e5f6-789a-bcde-f012-3456789abcde",
"kind": "scheduler.rescan.delta",
"version": "1",
"tenant": "tenant-01",
"ts": "2025-12-24T12:00:00+00:00",
"actor": "scheduler-service",
"payload": {
"scheduleId": "schedule-daily-rescan",
"deltaId": "delta-20251224-1200",
"imagesAffected": 15,
"newVulnerabilities": 3,
"resolvedVulnerabilities": 2,
"links": {
"schedule": "https://stellaops.example.com/schedules/schedule-daily-rescan",
"delta": "https://stellaops.example.com/deltas/delta-20251224-1200"
}
},
"attributes": {
"category": "scheduler",
"scheduleType": "daily"
}
}

View File

@@ -0,0 +1,42 @@
# Notify SLO Alerts
# Prometheus alerting rules for the notification service
groups:
- name: notify-slo
rules:
- alert: NotifyDeliverySuccessSLO
expr: |
(
sum(rate(notify_delivery_success_total[5m])) /
sum(rate(notify_delivery_total[5m]))
) < 0.99
for: 5m
labels:
severity: critical
service: notify
annotations:
summary: "Notification delivery success rate below SLO"
description: "Current success rate: {{ $value | humanizePercentage }}"
- alert: NotifyBacklogDepth
expr: notify_backlog_depth > 10000
for: 10m
labels:
severity: warning
service: notify
annotations:
summary: "Notification backlog depth high"
description: "Current backlog: {{ $value }} notifications"
- alert: NotifyLatencyP99
expr: |
histogram_quantile(0.99,
sum(rate(notify_delivery_duration_seconds_bucket[5m])) by (le)
) > 5
for: 5m
labels:
severity: warning
service: notify
annotations:
summary: "Notification delivery P99 latency high"
description: "P99 latency: {{ $value | humanizeDuration }}"

View File

@@ -0,0 +1,32 @@
# Notification Quotas
This document describes the quota system for notification delivery.
## Overview
Quotas ensure fair usage of the notification system across tenants.
## Quota Types
### Daily Limits
- Maximum notifications per day per tenant
- Maximum notifications per channel per day
### Rate Limits
- Maximum notifications per minute
- Maximum notifications per second per channel
### Size Limits
- Maximum payload size
- Maximum attachment count
## Quota Enforcement
Quota violations result in:
1. Notification is queued for later delivery
2. Tenant is notified of quota exceeded
3. Admin alert is triggered if threshold is reached
## Configuration
Quotas are configured per tenant and can be overridden by administrators.

View File

@@ -0,0 +1,38 @@
# Notification Retries
This document describes the retry mechanism for failed notification deliveries.
## Overview
The retry system ensures reliable notification delivery even when temporary failures occur.
## Retry Strategy
### Exponential Backoff
- Initial delay: 5 seconds
- Maximum delay: 1 hour
- Backoff multiplier: 2x
### Retry Limits
- Maximum attempts: 10
- Maximum retry duration: 24 hours
### Retry Conditions
- Network errors: Always retry
- HTTP 5xx errors: Always retry
- HTTP 429 (rate limit): Retry with Retry-After header
- HTTP 4xx errors: Do not retry (permanent failure)
## Dead Letter Queue
Notifications that exceed retry limits are moved to the dead letter queue for:
- Manual inspection
- Automatic alerting
- Scheduled reprocessing
## Monitoring
Retry metrics are exposed for:
- Retry count per notification
- Success rate after retries
- Average retry duration

View File

@@ -0,0 +1,27 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://docs.stella-ops.org/notifications/schemas/notify-schemas-catalog.json",
"title": "Notify Schemas Catalog",
"description": "Catalog of all notification schemas",
"type": "object",
"properties": {
"version": {
"type": "string",
"const": "1.0.0"
},
"schemas": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"version": { "type": "string" },
"description": { "type": "string" },
"path": { "type": "string" }
},
"required": ["name", "version", "path"]
}
}
},
"required": ["version", "schemas"]
}

View File

@@ -0,0 +1,28 @@
# Redaction Catalog
This document catalogs the redaction rules applied to notification payloads.
## Overview
The redaction catalog ensures that sensitive information is not exposed in notifications.
## Redaction Rules
### Personal Identifiable Information (PII)
- Email addresses are partially redacted
- IP addresses are anonymized
- User names are replaced with user IDs
### Credentials
- API keys are fully redacted
- Passwords are never included
- Tokens are truncated to first/last 4 characters
### Internal Data
- Internal URLs are replaced with public equivalents
- Database IDs are not exposed
- Stack traces are summarized
## Configuration
Redaction rules can be customized per tenant and notification channel.

View File

@@ -0,0 +1,19 @@
# Tenant Approvals
This document describes the tenant approval process for notification delivery.
## Overview
Tenant approvals ensure that notifications are only sent to approved tenants with proper configuration.
## Approval Process
1. Tenant submits a request for notification access
2. Admin reviews the request and approves/denies
3. Approved tenants can configure notification channels
## Security Considerations
- All approval decisions are logged for audit purposes
- Approvals can be revoked at any time
- Cross-tenant notifications are blocked by default

View File

@@ -0,0 +1,22 @@
# Webhook Acknowledgment Hardening
This document describes the security measures for webhook acknowledgment validation.
## Overview
Webhook acknowledgment hardening ensures that webhook deliveries are properly verified and acknowledged.
## Security Measures
- HMAC signature verification for all webhook payloads
- Timeout handling for slow webhook endpoints
- Retry logic with exponential backoff
- Dead letter queue for failed deliveries
## Configuration
Webhook endpoints must be configured with:
- Secret key for HMAC signing
- Signature header name
- Timeout duration
- Maximum retry attempts

View File

@@ -0,0 +1,4 @@
{"simulation_id": "sim-001", "name": "High Volume Burst", "description": "Simulates a burst of 10000 notifications in 1 minute", "tenant": "test-tenant", "status": "ready"}
{"simulation_id": "sim-002", "name": "Rate Limit Test", "description": "Simulates hitting rate limits across all channels", "tenant": "test-tenant", "status": "ready"}
{"simulation_id": "sim-003", "name": "Retry Storm", "description": "Simulates webhook endpoints returning 500 errors causing retries", "tenant": "test-tenant", "status": "ready"}
{"simulation_id": "sim-004", "name": "Multi-Tenant Isolation", "description": "Validates tenant isolation with concurrent notifications", "tenant": "test-tenant", "status": "ready"}

View File

@@ -0,0 +1,248 @@
# StellaOps Trust Bootstrap Guide
> Sprint: SPRINT_20260125_003 - WORKFLOW-001
> Last updated: 2026-01-25
## Overview
This guide covers the initial trust setup for a new StellaOps deployment. Trust
bootstrap establishes the cryptographic foundations for secure attestation and
verification.
## Prerequisites
- StellaOps CLI installed (`stella` command available)
- Network access to TUF repository (or offline trust bundle)
- Sufficient permissions to create keys in `/etc/stellaops/keys/`
- For keyless mode: OIDC identity provider configured
## Quick Start
### Online Bootstrap
```bash
# Initialize trust from organization's TUF repository
./devops/scripts/bootstrap-trust.sh \
--tuf-url https://trust.example.com/tuf/ \
--pin rekor-key-v1
```
### Offline Bootstrap (Air-Gapped)
```bash
# Import pre-packaged trust bundle
./devops/scripts/bootstrap-trust-offline.sh \
/media/usb/trust-bundle-2026-01-25.tar.zst
```
## Detailed Steps
### Step 1: Generate Signing Keys (Optional)
If using local signing keys (not keyless/OIDC):
```bash
# Create key directory
mkdir -p /etc/stellaops/keys
chmod 700 /etc/stellaops/keys
# Generate ECDSA P-256 signing key
stella keys generate \
--type ecdsa-p256 \
--out /etc/stellaops/keys/signing-key.pem
# Or use OpenSSL
openssl ecparam -name prime256v1 -genkey -noout \
-out /etc/stellaops/keys/signing-key.pem
chmod 600 /etc/stellaops/keys/signing-key.pem
```
### Step 2: Initialize TUF Client
```bash
# Initialize with your organization's TUF repository
stella trust init \
--tuf-url https://trust.example.com/tuf/ \
--service-map sigstore-services-v1 \
--pin rekor-key-v1 rekor-key-v2
# Verify initialization
stella trust status
```
The `--pin` option specifies which Rekor keys to trust. Pin multiple keys during
rotation periods.
### Step 3: Verify TUF Metadata
```bash
# Check trust status
stella trust status --show-keys --show-endpoints
# Expected output:
# TUF Repository: https://trust.example.com/tuf/
# Service Map: sigstore-services-v1
# Trusted Keys:
# - rekor-key-v1 (expires: 2027-01-01)
# - rekor-key-v2 (expires: 2028-01-01)
# Endpoints:
# - Rekor: https://rekor.sigstore.dev
# - Fulcio: https://fulcio.sigstore.dev
```
### Step 4: Test Sign/Verify Cycle
```bash
# Create a test payload
echo "StellaOps bootstrap test" > /tmp/test-payload.txt
# Sign with your key
stella sign /tmp/test-payload.txt \
--key /etc/stellaops/keys/signing-key.pem \
--out /tmp/test.sig
# Verify signature
stella verify /tmp/test-payload.txt \
--sig /tmp/test.sig
# Clean up
rm /tmp/test-payload.txt /tmp/test.sig
```
### Step 5: Test Rekor Submission (Online Only)
```bash
# Create and submit an attestation
stella attest create /tmp/test-payload.txt \
--type stellaops.io/predicates/test@v1 \
--rekor-submit
# Verify inclusion in transparency log
stella attest verify /tmp/test-payload.txt \
--check-inclusion
```
## Offline Bootstrap
For air-gapped deployments without network access:
### Create Trust Bundle (Connected System)
On a system with network access, create a trust bundle:
```bash
stella trust snapshot export \
--include-tiles \
--out trust-bundle-$(date +%Y-%m-%d).tar.zst
```
### Transfer and Import (Air-Gapped System)
```bash
# Transfer bundle via USB, DVD, or approved data diode
# Then import:
./devops/scripts/bootstrap-trust-offline.sh \
/media/usb/trust-bundle-2026-01-25.tar.zst
# Optional: Reject stale bundles
./devops/scripts/bootstrap-trust-offline.sh \
/media/usb/trust-bundle-2026-01-25.tar.zst \
--reject-if-stale 7d
```
## Configuration Options
### TUF Client Configuration
After bootstrap, TUF client configuration is stored in:
`~/.local/share/StellaOps/TufCache/`
Key files:
- `root.json` - Root of trust (only updated via ceremony)
- `targets.json` - List of trusted targets
- `snapshot.json` - Point-in-time snapshot of targets
- `timestamp.json` - Freshness guarantee (regularly updated)
### Environment Variables
```bash
# Override cache directory
export STELLAOPS_TUF_CACHE=/custom/path
# Enable debug logging
export STELLAOPS_LOG_LEVEL=debug
# Offline mode (no network calls)
export STELLAOPS_OFFLINE=true
```
## Troubleshooting
### Error: "TUF metadata verification failed"
The TUF root key may have been rotated. Obtain the new root.json from your
security team and re-bootstrap:
```bash
stella trust init \
--tuf-url https://trust.example.com/tuf/ \
--root-json /path/to/new/root.json \
--force
```
### Error: "Rekor connectivity check failed"
1. Verify network access to Rekor endpoint
2. Check firewall rules for HTTPS (port 443)
3. Verify the Rekor URL in service map is correct
4. Try forcing a sync: `stella trust sync --force`
### Error: "Key not found in trust store"
The pinned key may not exist in the TUF repository. Check available keys:
```bash
stella trust status --show-keys
```
### Offline: "Bundle is stale"
The trust bundle exceeds the staleness threshold. Obtain a fresh bundle from a
connected system:
```bash
# On connected system
stella trust snapshot export --out fresh-bundle.tar.zst
# Transfer and import
./devops/scripts/bootstrap-trust-offline.sh fresh-bundle.tar.zst
```
## Maintenance
### Periodic Sync
Set up a cron job to keep TUF metadata fresh:
```bash
# Every 6 hours
0 */6 * * * /usr/local/bin/stella trust sync --quiet
```
### Updating Air-Gap Bundles
For air-gapped systems, schedule regular bundle updates based on your
organization's freshness requirements (typically 7-30 days).
## Next Steps
- Configure CI/CD to use the signing key
- Set up key rotation procedures (see `key-rotation-runbook.md`)
- Configure monitoring for trust state freshness
- For air-gap: Establish bundle transfer schedule
## Related Documentation
- [TUF Integration Guide](../modules/attestor/tuf-integration.md)
- [Key Rotation Runbook](key-rotation-runbook.md)
- [Disaster Recovery](disaster-recovery.md)

View File

@@ -0,0 +1,328 @@
# StellaOps Disaster Recovery Guide
> Sprint: SPRINT_20260125_003 - WORKFLOW-003
> Last updated: 2026-01-25
## Overview
This guide covers disaster recovery procedures for StellaOps trust
infrastructure, including Rekor outages, key compromise, and TUF repository
failures.
## Scenario 1: Rekor Service Outage
### Symptoms
- Attestation submissions failing
- Verification requests timing out
- Circuit breaker reporting OPEN state
### Immediate Actions
1. **Verify the outage**
```bash
# Check Rekor health
curl -sf https://rekor.sigstore.dev/api/v1/log | jq .
# Check circuit breaker state
stella trust status --show-circuit-breaker
```
2. **Check if mirror is active**
```bash
# If mirror failover is enabled, verify it's working
stella trust status --show-backends
```
3. **If mirror is not available, swap endpoints via TUF**
```bash
# On TUF repository admin system
./devops/scripts/disaster-swap-endpoint.sh \
--repo /path/to/tuf \
--new-rekor-url https://rekor-mirror.internal:8080 \
--note "Emergency: Production Rekor outage $(date -u)"
```
4. **Publish the update**
```bash
cd /path/to/tuf
./scripts/sign-metadata.sh # Sign updated metadata
./scripts/publish.sh # Deploy to TUF server
```
5. **Force client sync (optional, for immediate effect)**
```bash
stella trust sync --force
```
### Key Principle
**No client reconfiguration required.** Endpoint changes flow through TUF.
Clients discover new endpoints within their configured refresh interval.
### Recovery
Once the primary Rekor is restored:
1. **Swap back to primary**
```bash
./devops/scripts/disaster-swap-endpoint.sh \
--repo /path/to/tuf \
--new-rekor-url https://rekor.sigstore.dev \
--note "Recovery: Primary Rekor restored"
```
2. **Verify service map published**
```bash
stella trust sync --force
stella trust status --show-endpoints
```
3. **Reset circuit breakers**
```bash
stella trust reset-circuits
```
## Scenario 2: Rekor Key Compromise
### Symptoms
- Security team reports potential key exposure
- Unusual entries in transparency log
- Third-party security advisory
### Immediate Actions
1. **Assess the compromise scope**
- When was the key potentially exposed?
- What entries may be affected?
- Are there signed entries from the compromised period?
2. **Emergency key rotation**
```bash
# Phase 1: Add new key immediately (no grace period)
./devops/scripts/rotate-rekor-key.sh add-key \
--repo /path/to/tuf \
--new-key /secure/new-rekor-key-v2.pub
# Sign and publish immediately
cd /path/to/tuf
./scripts/sign-metadata.sh
./scripts/publish.sh
```
3. **Force all clients to sync**
- Announce emergency update to all teams
- Clients should run: `stella trust sync --force`
4. **Revoke compromised key immediately**
```bash
# Phase 2: Remove old key (skip grace period due to compromise)
./devops/scripts/rotate-rekor-key.sh remove-old \
--repo /path/to/tuf \
--old-key-name rekor-key-v1
# Sign and publish
cd /path/to/tuf
./scripts/sign-metadata.sh
./scripts/publish.sh
```
5. **Document the incident**
- Log rotation time
- Affected key ID and fingerprint
- List of potentially affected entries
- Remediation steps taken
### Forensics
Identify entries signed during the compromise window:
```bash
# Query entries by time range
stella rekor query \
--after "2026-01-20T00:00:00Z" \
--before "2026-01-25T00:00:00Z" \
--key-id compromised-key-id
```
## Scenario 3: TUF Repository Unavailable
### Symptoms
- Clients cannot sync trust metadata
- `stella trust sync` failing with network errors
- TUF timestamp verification failing
### Immediate Actions
1. **Diagnose the issue**
```bash
# Check TUF repository health
curl -sf https://trust.example.com/tuf/timestamp.json | jq .
# Check DNS resolution
nslookup trust.example.com
# Check TLS certificate
openssl s_client -connect trust.example.com:443 -servername trust.example.com
```
2. **For clients - extend offline tolerance**
```bash
# Temporarily allow stale metadata (use with caution)
stella trust sync --allow-stale --max-age 7d
```
3. **Restore TUF server**
- Check hosting infrastructure
- Restore from backup if needed
- Verify metadata integrity
4. **Deploy mirror (if available)**
```bash
# Update DNS or load balancer to point to mirror
# Or update clients directly (less preferred)
stella trust init \
--tuf-url https://trust-mirror.example.com/tuf/ \
--force
```
## Scenario 4: Signing Key Compromise
### Symptoms
- Security team reports key exposure
- Unauthorized attestations appearing
### Immediate Actions
1. **Revoke the compromised key**
```bash
./devops/scripts/rotate-signing-key.sh retire \
--old-key compromised-key-name
```
2. **Generate new signing key**
```bash
./devops/scripts/rotate-signing-key.sh generate \
--key-type ecdsa-p256
```
3. **Update CI/CD immediately**
- Remove compromised key from all pipelines
- Add new key
- Trigger rebuild of recent releases
4. **Notify downstream consumers**
- Announce key rotation
- Provide new public key
- Advise re-verification of recent attestations
## Scenario 5: Root Key Ceremony Required
### When Required
- Scheduled root key rotation (typically annual)
- Root key compromise (emergency)
- Threshold change for root signatures
### Procedure
1. **Schedule ceremony**
- Require M-of-N key holders present
- Air-gapped ceremony machine
- Hardware security modules
2. **Generate new root**
```bash
# On air-gapped ceremony machine
tuf-ceremony init \
--threshold 3 \
--keys 5 \
--algorithm ed25519
```
3. **Sign new root with old keys**
- Requires old threshold of signatures
- Ensures continuous trust chain
4. **Distribute new root**
- Publish to TUF repository
- Update bootstrap documentation
- Notify all operators
### Air-Gap Considerations
For air-gapped deployments after root rotation:
```bash
# Export new trust bundle with updated root
stella trust snapshot export \
--include-root \
--out post-rotation-bundle.tar.zst
# Transfer and import on air-gapped systems
./devops/scripts/bootstrap-trust-offline.sh \
post-rotation-bundle.tar.zst \
--force # Required due to root change
```
## Communication Templates
### Outage Notification
```
Subject: [StellaOps] Rekor Service Disruption - Failover Active
Status: Service Degradation
Impact: Attestation submissions may be delayed
Mitigation: Automatic failover to mirror active
Action Required: None - clients will auto-discover new endpoint
Updates: Monitor status at https://status.example.com
```
### Key Rotation Notice
```
Subject: [StellaOps] Emergency Key Rotation - Action Required
Reason: Security precaution / Scheduled rotation
Affected Key: rekor-key-v1 (fingerprint: abc123...)
New Key: rekor-key-v2 (fingerprint: def456...)
Action Required:
1. Run: stella trust sync --force
2. Verify: stella trust status --show-keys
Timeline: Old key will be revoked at [DATE/TIME UTC]
```
## Monitoring and Alerting
### Key Metrics
- Circuit breaker state changes
- TUF metadata freshness
- Rekor submission latency
- Verification success rate
### Alert Thresholds
| Metric | Warning | Critical |
|--------|---------|----------|
| TUF metadata age | > 12h | > 24h |
| Circuit breaker opens | > 2/hour | > 5/hour |
| Submission failures | > 5% | > 20% |
| Verification failures | > 1% | > 5% |
## Contacts
| Role | Contact | Escalation |
|------|---------|------------|
| TUF Admin | tuf-admin@example.com | On-call |
| Security Team | security@example.com | Immediate |
| Platform Team | platform@example.com | Business hours |
## Related Documentation
- [Bootstrap Guide](bootstrap-guide.md)
- [Key Rotation Runbook](key-rotation-runbook.md)
- [TUF Integration Guide](../modules/attestor/tuf-integration.md)

View File

@@ -421,9 +421,111 @@ groups:
---
## TUF-Based Key Rotation
> Sprint: SPRINT_20260125_003 - WORKFLOW-007
For organizations using TUF-based trust distribution, additional key rotation
procedures apply to Rekor public keys and TUF metadata signing keys.
### Rekor Public Key Rotation
Rekor public keys verify transparency log signatures. Rotation uses a dual-key
grace period to ensure all clients sync the new key before removing the old one.
**Recommended rotation interval:** Annually
**Grace period:** 7-14 days
#### Phase 1: Add New Key
```bash
# Add new Rekor key to TUF repository
./devops/scripts/rotate-rekor-key.sh add-key \
--repo /path/to/tuf \
--new-key rekor-key-v2.pub
# Sign and publish TUF metadata
cd /path/to/tuf
./scripts/sign-metadata.sh
./scripts/publish.sh
```
#### Phase 2: Grace Period
During the grace period (7-14 days):
- Monitor client sync logs
- Verify both keys work for verification
- Confirm all clients have updated
```bash
# Check client trust status
stella trust status --show-keys
# Should show both rekor-key-v1 and rekor-key-v2
```
#### Phase 3: Remove Old Key
```bash
# Remove old key after grace period
./devops/scripts/rotate-rekor-key.sh remove-old \
--repo /path/to/tuf \
--old-key-name rekor-key-v1
# Sign and publish
cd /path/to/tuf
./scripts/sign-metadata.sh
./scripts/publish.sh
```
### TUF Root Key Rotation
TUF root keys are the ultimate trust anchor. Rotation is a high-ceremony
operation requiring M-of-N key holders.
**Recommended rotation interval:** 2-3 years
**Requires:** Key ceremony with multiple signers
See [Disaster Recovery](disaster-recovery.md#scenario-5-root-key-ceremony-required)
for full root key ceremony procedures.
### TUF Metadata Signing Key Rotation
For targets, snapshot, and timestamp keys:
```bash
# Generate new metadata signing key
openssl ecparam -name prime256v1 -genkey -noout \
-out /secure/targets-key-v2.pem
# Update root.json to include new key
tuf update-root --add-targets-key /secure/targets-key-v2.pem
# Sign with both old and new keys during transition
tuf sign targets --key /secure/targets-key-v1.pem
tuf sign targets --key /secure/targets-key-v2.pem
# After grace period, remove old key from root.json
tuf update-root --remove-targets-key /secure/targets-key-v1.pem
```
### Automated Scripts
Use the provided automation scripts:
| Script | Purpose |
|--------|---------|
| `devops/scripts/rotate-rekor-key.sh` | Rekor public key rotation |
| `devops/scripts/rotate-signing-key.sh` | Organization signing key rotation |
| `devops/trust-repo-template/scripts/revoke-target.sh` | Remove target from TUF |
---
## Related Documentation
- [Proof Chain API](../api/proofs.md)
- [Attestor Architecture](../modules/attestor/architecture.md)
- [Signer Architecture](../modules/signer/architecture.md)
- [TUF Integration Guide](../modules/attestor/tuf-integration.md)
- [Bootstrap Guide](bootstrap-guide.md)
- [Disaster Recovery](disaster-recovery.md)
- [NIST SP 800-57](https://csrc.nist.gov/publications/detail/sp/800-57-part-1/rev-5/final) - Key Management Guidelines

View File

@@ -12,8 +12,11 @@ Guidance on DSSE/TUF roots, rotation, and signed time tokens.
- Verification in sealed mode uses bundled roots; no online Rekor needed.
- Rotate signing keys with overlapping validity; publish new root in next bundle.
## TUF (optional)
- If using TUF metadata, ship `root.json`, `snapshot.json`, `timestamp.json` with bundles.
## TUF (planned enhancement)
- **Current**: TUF metadata can be shipped with bundles (`root.json`, `snapshot.json`, `timestamp.json`).
- **Planned**: Full TUF client integration for dynamic trust metadata distribution.
- See: `SPRINT_20260125_001_Attestor_tuf_trust_foundation.md`
- See: `SPRINT_20260125_002_Attestor_trust_automation.md`
- In sealed mode, trust only bundled metadata; no remote refresh.
## Signed time tokens