Reporting
Security vulnerabilities: email[email protected]. Do not file a public issue. Acknowledgment arrives within 48 hours. Target remediation is 7 days for high severity and 30 days for medium severity.
Operational incidents (in your own deploy): follow your internal runbook. This page describes the general steps that apply to any incident.
First five minutes
- Contain. If you do not know how far the issue has spread, flip the relevant feature flag or route to maintenance mode. A 503 error is safer than a breach.
-
Preserve. Snapshot the database before any destructive recovery:
-
Gather evidence. Pull logs, metrics, and the recent audit trail:
- Declare. Open an incident channel. One person owns coordination and one person drives fixes. Everyone else only observes.
Common incidents
Admin token leaked
Follow Admin token rotation → emergency path. Revoke every session, rotate the token, and audit the window of exposure. If you stored OAuth credentials as admin-level environment variables, rotate those too.Policy bypass / data exposure
- Reproduce with a throwaway session token against staging.
- Check
audit_logfor rows accessed during the window. In the EU, this triggers the GDPR notification requirement. - Patch the issue and ship the fix. Verify that the regression test in
crates/policy/src/lib.rs::testscovers it. - If user data was exposed, start the breach notification workflow.
Runaway write loop
Signal: the write rate exceeds the 70k/sec ceiling, the WAL grows without bound, and disk space fills.- Identify the source. Check recent deploys and
audit_logfor the offendinguser_idor IP. - Rate-limit or block at the proxy. Do not try to fix this inside the server while it is under load.
- Once the system is stable, investigate the trigger. A common cause is a client stuck in an exponential-backoff retry loop with no jitter.
WAL file growth past disk budget
SQLite in WAL mode delays checkpoints. If a checkpoint is not completing, run:sqlite3 … ".pragma stats" and kill the client holding the lock.
WS fanout storm
Signal: ws-broadcast-N threads at 100% CPU, clients reporting missed events, queue-full warnings in the log.- Check the client count. The per-IP cap is 64. If one IP reaches 64 connections, a client is stuck in a loop.
- Check the broadcast rate. The event might come from a retry loop creating 1000 inserts/sec.
- Restart the WS server (
kill -HUP <pid>) only as a last resort. Every client must reconnect.
Cloudflare Workers billing spike
Signal: Cloudflare emails you that you have used 80% of your monthly budget in a week. See Workers costs for patterns.Magic-link emails not arriving
- Check the spam folder.
- Verify the email provider environment variables (
PYLON_EMAIL_*). - Check the provider’s dashboard. Your account may be paused for a high bounce rate.
- Check
journalctl -u pylon | grep emailfor delivery errors. - For domain authentication, verify SPF, DKIM, and DMARC records with
mxtoolbox.com.
Sudden surge of 401 / 403 errors
- Check whether a deploy went out recently. A regression in policy expressions can lock everyone out.
- Check the session database integrity. If
sessions.dbis corrupted, every authenticated request fails. - If needed, restore the previous session database from backup. Sessions are recoverable; users only need to sign in again.
Post-mortem template
- Summary: one paragraph covering what happened, how long it lasted, and how far it reached.
- Timeline: UTC timestamps from the first signal to the all-clear.
- Root cause: what went wrong, not who caused it.
- What worked: detection, containment, and communication.
- What did not work: slow alerts, unclear runbooks, and missing graphs.
- Action items: owners and target dates. Track them in the sprint.
On Pylon Cloud
For Cloud workspaces, Pylon’s on-call team is paged on infrastructure-level incidents (DB outage, region-wide failure, control-plane bugs). For app-level incidents (your code, your data), Cloud’s dashboard surfaces logs and request traces but you own the response. Status: status.pylonsync.com shows region health and incident history.Contacts
- Security:
[email protected] - Public issues / feature requests: github.com/pylonsync/pylon/issues
- Cloud support: dashboard → Help → Contact
- Your internal oncall: (fill in your rotation)