This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
# Gitea webhook threat model
|
||||
|
||||
Status: design gate only. Incoming webhooks are disabled and no webhook is
|
||||
registered by DevRunbook. Periodic PostgreSQL-backed refresh remains the sole
|
||||
automatic freshness mechanism for this release.
|
||||
|
||||
## Trust boundary
|
||||
|
||||
A webhook body, headers, event name, repository identity and delivery ID are
|
||||
untrusted network input. They may request only the same bounded, read-only
|
||||
snapshot job that an authorized refresh already creates. They must never carry
|
||||
forge credentials, select a workspace directly, execute content or mutate a
|
||||
repository.
|
||||
|
||||
## Mandatory controls before enabling an endpoint
|
||||
|
||||
- Authenticate the exact raw body with HMAC-SHA-256 and a per-integration
|
||||
secret; compare the digest in constant time before parsing JSON.
|
||||
- Require a signed timestamp within five minutes and a cryptographically
|
||||
random delivery ID. Persist `(integration_id, delivery_id)` with a TTL and
|
||||
atomically reject replays before enqueueing work.
|
||||
- Resolve workspace and repository exclusively from the authenticated
|
||||
integration and allowlisted remote identity. Never trust workspace IDs or
|
||||
callback URLs supplied by the body.
|
||||
- Limit the raw body before buffering, allowlist push/default-branch and
|
||||
repository-change events, validate content type and reject unknown fields.
|
||||
- Apply independent per-source-IP, per-integration and per-workspace token
|
||||
buckets before database work. Return `429` with bounded jitter and never
|
||||
bypass the normal queue's deduplication or retry limits.
|
||||
- Use the existing snapshot preflight and idempotency contract. A delivery may
|
||||
enqueue work but cannot force full analysis or create a profile revision.
|
||||
- Log only a hashed delivery ID, integration ID, event class and safe outcome.
|
||||
Never log the signature, raw body, token or repository content.
|
||||
- Respond with generic errors so signature, tenant and repository existence
|
||||
cannot be enumerated. Keep last-known-good snapshots on every failure.
|
||||
|
||||
## Required verification gate
|
||||
|
||||
The feature stays disabled until integration tests prove valid/invalid
|
||||
signatures, raw-byte verification, expired/future timestamps, replay races,
|
||||
body limits, event allowlisting, flood limits, queue deduplication and strict
|
||||
cross-workspace isolation. Deployment documentation must also cover secret
|
||||
rotation with an explicitly bounded overlap window and immediate revocation.
|
||||
|
||||
This keeps the Gitea integration read-only: webhook registration itself is an
|
||||
operator action outside DevRunbook, and the callback can only schedule reads.
|
||||
Reference in New Issue
Block a user