95 lines
7.9 KiB
Markdown
95 lines
7.9 KiB
Markdown
# Security Policy
|
||
|
||
This is the public security index for the repository. It points to the canonical sub-documents under [`docs/security/`](docs/security/) and to the public reporting channel (`.well-known/security.txt`). Anyone reporting a vulnerability, evaluating a procurement question, or planning a penetration test should start here.
|
||
|
||
## Quick links
|
||
|
||
| Topic | Where to look |
|
||
| --- | --- |
|
||
| Report a vulnerability | [`docs/security/vulnerability-disclosure.md`](docs/security/vulnerability-disclosure.md), `mailto:security@<your-domain>` (PGP in [`/.well-known/pgp-key.txt`](apps/web/public/.well-known/pgp-key.txt)) |
|
||
| Public researcher-facing policy | [`apps/web/public/.well-known/security.txt`](apps/web/public/.well-known/security.txt) (RFC 9116) |
|
||
| Threat model (STRIDE per component) | [`docs/security/threat-model.md`](docs/security/threat-model.md) |
|
||
| Pen-test scope and engagement guidelines | [`docs/security/pen-test-scope.md`](docs/security/pen-test-scope.md) |
|
||
| Incident-response runbook (P0–P3, GDPR 72h) | [`docs/security/incident-response.md`](docs/security/incident-response.md) |
|
||
| Bug-bounty foundation (planned) | [`docs/security/bug-bounty.md`](docs/security/bug-bounty.md) |
|
||
| SBOM workflow and distribution | [`docs/security/sbom.md`](docs/security/sbom.md) |
|
||
| Security-header + CORS contract | [`docs/security/runbook.md`](docs/security/runbook.md) |
|
||
| Tenant-isolation inventory | [`docs/security/tenant-isolation-report.md`](docs/security/tenant-isolation-report.md) |
|
||
| Route-access inventory | [`docs/security/route-access-inventory.md`](docs/security/route-access-inventory.md) |
|
||
| CSRF inventory | [`docs/security/csrf-inventory.md`](docs/security/csrf-inventory.md) |
|
||
| Audit-event hash chain (forensics) | tracked under [`docs/improvement-plan/10-compliance-polish/compliance-audit-export.md`](docs/improvement-plan/10-compliance-polish/compliance-audit-export.md) |
|
||
|
||
For an internal security overview see [`docs/security.md`](docs/security.md).
|
||
|
||
## Reporting a vulnerability
|
||
|
||
The full reporting policy, response SLA and safe-harbor commitment is in [`docs/security/vulnerability-disclosure.md`](docs/security/vulnerability-disclosure.md). In short:
|
||
|
||
- Email `security@<your-domain>` (PGP key in [`/.well-known/pgp-key.txt`](apps/web/public/.well-known/pgp-key.txt))
|
||
- We acknowledge within **48 hours** (business days)
|
||
- Triage within **5 business days**
|
||
- Fix windows by severity: **P0** 7 days, **P1** 30 days, **P2** 60 days, **P3** 90 days
|
||
- Researchers acting in good faith are granted safe harbor — see the disclosure policy
|
||
|
||
**Do not** open a public issue, post on social media, or contact customer support for a security issue.
|
||
|
||
## Supported scope
|
||
|
||
Reports are in scope when they affect the repository-maintained web runtime, API runtime, worker runtime, or documentation contracts:
|
||
|
||
- Web responses, redirects, static assets, and browser security headers.
|
||
- API routes, authentication boundaries, request-id behavior, CORS decisions, OpenAPI exposure, and error responses.
|
||
- Worker queue behavior, job diagnostics, dependency readiness, and secret-backed provider integration boundaries.
|
||
- Realtime collaboration (Hocuspocus), form-widget embed surface, public lead-capture endpoint.
|
||
- Security documentation, runbooks, configuration examples, and verification scripts that could leak sensitive material or describe unsafe handling.
|
||
|
||
Out-of-scope activity includes testing against live third-party systems, provider consoles, customer environments, tenant-specific domains, social engineering, denial-of-service attempts, physical attacks, and any action that requires accessing data you are not authorised to view. The authoritative scope list is [`docs/security/pen-test-scope.md`](docs/security/pen-test-scope.md) §2 and §3.
|
||
|
||
## What a useful report looks like
|
||
|
||
A useful report includes:
|
||
|
||
1. The affected surface, such as web, API, worker, documentation, or configuration.
|
||
2. The relevant generic route class, endpoint shape, job category, or documentation page.
|
||
3. The observed impact and the expected safe behavior.
|
||
4. Reproduction steps that use local fixtures, synthetic values, or generic origin labels only.
|
||
5. Safe evidence (see below), including request IDs or job IDs when available.
|
||
|
||
Maintainers acknowledge receipt through the same private channel, triage severity based on exploitability and data-exposure risk, preserve safe evidence only, and coordinate a remediation timeline before public disclosure. If a report is not reproducible from the provided safe evidence, maintainers may request additional redacted steps rather than raw sensitive material.
|
||
|
||
## Safe evidence
|
||
|
||
Safe evidence may include the minimum facts needed to reproduce or correlate the issue:
|
||
|
||
- Header names, expected policy values, response status, stable error code, and generic route class.
|
||
- HTTP method, normalised path shape, `x-request-id`, and generic origin labels.
|
||
- Worker enablement state, queue name, job ID, retry count, job status, dependency category, and redacted diagnostic code.
|
||
- Environment variable key names, configuration parse status, provider category, and non-sensitive readiness state.
|
||
- Screenshots or logs only after removing customer data, tenant identifiers, credentials, provider payloads, full URLs tied to live providers, and secret-shaped values.
|
||
|
||
Use synthetic values for examples and prefer local verification output over production evidence. Keep evidence narrow enough that it can be copied into a ticket without additional redaction.
|
||
|
||
## Do not include
|
||
|
||
Do not include or request any of the following in a vulnerability report, ticket, pull request, chat, screenshot, log excerpt, or documentation example:
|
||
|
||
- Raw secrets, tokens, passwords, cookies, API keys, registry credentials, webhook signing secrets, authorisation headers, or reversible hashes of those values.
|
||
- Database connection strings, Redis URLs, deployment webhook URLs, provider dashboard URLs, UUID-like deploy endpoints, or full environment dumps.
|
||
- Customer data, customer email addresses, tenant identifiers, tenant hostnames, customer-specific domains, provider payloads, message bodies, or raw request bodies.
|
||
- Secret-shaped sample values, live provider URLs, screenshots containing personal data, or stack traces that expose credentials.
|
||
- Instructions that weaken the documented security headers, CORS boundaries, authentication checks, request-id correlation, or redaction rules in the linked runbooks.
|
||
|
||
If sensitive material is accidentally disclosed, stop sharing it, remove it from shared systems where possible, rotate the affected credential when applicable, and continue the report with redacted facts only.
|
||
|
||
## Triage expectations
|
||
|
||
Maintainers compare reports against the repository security overview and the [threat model](docs/security/threat-model.md) before changing implementation behavior. A valid fix preserves existing cache behavior, redirects, request IDs, CORS allow and deny decisions, worker diagnostics, and redaction boundaries unless the vulnerability is specifically in one of those contracts.
|
||
|
||
When a report escalates into an active incident, the [incident-response runbook](docs/security/incident-response.md) drives the response: severity classification (P0–P3), six-phase workflow, GDPR Article 33 72-hour notification, GDPR Article 34 data-subject notification, communication templates and post-incident review template.
|
||
|
||
Repository verification and incident notes stay focused on non-E2E checks unless a human explicitly approves a live browser, provider, Docker, registry, or deployment run in the current session. Public disclosure waits until the issue is remediated or a coordinated maintainer decision is recorded, and the final public summary avoids sensitive details that could identify customers, tenants, providers, or credentials.
|
||
|
||
## Versioning of this policy
|
||
|
||
This policy is versioned with the repository. Material updates are announced via the operator's public security page. The authoritative version is the file `SECURITY.md` at the tip of the `main` branch.
|