| policy_version | 1.0 | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| contact_channel | [email protected] | ||||||||||||
| preferred_channel | github_private_vulnerability_reporting | ||||||||||||
| disclosure_policy_url | https://github.com/shelf-project/shelf/blob/main/SECURITY.md | ||||||||||||
| response_sla |
|
||||||||||||
| embargo_default_days | 90 | ||||||||||||
| rota |
|
Shelf is a read-through cache sitting directly on the path between
Trino workers and S3. A defect in shelfd, the Trino plugin, or the
trainer could:
- leak rows across tenants (confidentiality)
- serve stale or tampered bytes (integrity)
- take Trino down by way of fail-closed instead of fail-open (availability)
Because the blast radius is large, we commit to the disclosure and response process documented here.
Do not open a public GitHub issue. Do not discuss in Discord or Slack. Use one of the channels below.
Open a private vulnerability report on GitHub. This is the canonical channel for sensitive findings: it gives us a private fork to coordinate fixes, automatic CVE reservation, and a clean disclosure path that Security Advisories handles end-to-end.
If GitHub PVR is not available to you, send to
[email protected]. The mailbox is monitored by the
year-1 BDFL and routed to the same triage queue as PVR reports. We
acknowledge within 48 hours.
PGP encryption is not required at v1.0; if you need it for sensitive disclosures, request a key over email and we will publish it before the next exchange.
Include, to the extent you can:
- Shelf version / commit hash / chart version
- Affected component (
shelfd,clients/trino, trainer, snapshot-watcher, Helm chart, CI) - Reproduction steps, proof of concept, or a minimal patch
- Impact estimate (tenant isolation, RCE, DoS, info leak, etc.)
- Whether the issue is already public anywhere (pre-prints, forks, CVE drafts)
- Do not run automated scanners against
shelfdinstances you do not own. We assume any traffic hitting our production clusters is production traffic and will page on-call. - Do not exfiltrate data beyond the minimum required to demonstrate impact. One record is plenty.
- Do not contact customers or external maintainers on our behalf.
report → acknowledge → triage → fix → disclose
| Step | Owner | SLA (from receipt) | Artefact |
|---|---|---|---|
| Acknowledge | Security rota | ≤ 48 h | Reply mail (no technical content, just "we have it") |
| Triage | Security rota | ≤ 5 business days | Severity assignment (§3), CVE reservation, private advisory opened on GitHub |
| Fix | Code owner + rota | per severity (§3) | Patch on a private branch, regression test, advisory draft |
| Validate | Reporter + rota | ≤ 14 days after patch | Reporter confirms fix; we run full CI + chaos drill (SECURITY/CHECKLIST.md) |
| Disclose | Rota + scribe | per embargo (§4) | Published advisory + patched release + credit line |
| Severity | Examples | Fix SLA |
|---|---|---|
| P0 / Critical | RCE on shelfd; cross-tenant S3 read; auth bypass on Pin / Evict RPC |
7 calendar days |
| P1 / High | Cache poisoning; plugin fails closed instead of open; trainer writes outside config bucket | 30 calendar days |
| P2 / Moderate | Information leak in logs; DoS requiring authenticated attacker; TLS downgrade | 90 calendar days |
| P3 / Low | Dependency advisory with no reachable code path; documentation error | Next minor release |
Severity is ours to assign, but we record the reporter's view. If we downgrade, we say why.
- Social engineering of maintainers or the company that employs them
- DoS that requires unrealistic resource ratios (e.g. 1 TB/s of S3
traffic to knock over
shelfd) - Bugs in dependencies already fixed upstream — we will cut a release bumping the pin, but we credit the upstream reporter, not you
- Attacks requiring physical access to NVMe
- Clickjacking on the docs site
- Default embargo: 90 days from report receipt, or date of fix, whichever is later.
- Negotiable. If a fix is shipped faster and the reporter agrees, we disclose earlier. If the issue is in an upstream dependency with a longer embargo, we honour theirs.
- Hard stop. If the issue is being actively exploited in the wild, embargo drops to whatever minimum is needed to ship a fix. We tell the reporter before going public.
- Credit. Reporter chooses: full name, handle, or anonymous. We do not credit without permission.
Some defects will be in code we depend on:
| Upstream | Channel |
|---|---|
| Trino (the engine + plugin SPI) | Trino security — we file, we do not republish before they do |
| Foyer cache | foyer-rs/foyer#security |
| tokio / hyper / axum / tonic | Rustsec + maintainer channel per crate |
| Arrow / Parquet (Java + Rust) | apache.org/security |
| AWS SDK (Rust) | [email protected] |
We will never publish a Shelf advisory that discloses an upstream unfixed issue.
| Role | Initial owner | Backup |
|---|---|---|
| Primary triage | @aamir306 |
(unfilled — BDFL absorbs) |
| Disclosure comms | @aamir306 |
(unfilled — BDFL absorbs) |
The rota is single-owner at v1.0 because Shelf is in Year-1 BDFL governance. It expands as additional maintainers are added; this file changes in the same PR as any rota change.
None. This file is maintained as advisories are published.
The canonical list lives at:
SECURITY/THREAT_MODEL.md— STRIDE per componentSECURITY/IAM.md— IRSA, STS chaining, mTLS, RBACSECURITY/SUPPLY_CHAIN.md— SBOM, signing, scannersSECURITY/CHECKLIST.md— pre-release gate.github/PULL_REQUEST_TEMPLATE.md— per-PR security checklistCODEOWNERS— security-sensitive routing.github/workflows/security.yml— CI enforcement
Runbooks for incident handling on the operational side live in
runbooks/ (owned by agent 8 — do not duplicate here).