Skip to main content

Threat model

GuildGate is designed for controlled writes from an authenticated Discord dashboard user to a resource they are authorized to manage. The browser, client-side JavaScript, and every incoming request field are treated as untrusted.

Addressed threats​

ThreatControl
Forged origin or CSRFExact-origin allowlist and session-bound CSRF verification
Stolen or stale sessionHashed opaque token, idle/absolute expiry, rotation, revocation, and cookie clearing
OAuth state replayAtomic single-use consume()
Credential disclosureApplication key-ring encryption and audit redaction
Writes after permission lossAuthorization repeated at action time
Repeated requestIdempotency reservation, request hash, and replay
Concurrent updateOptimistic revision, lease, and fencing token
Old worker corrupting a new resultReservation-owner compare-and-set
Rate-limit raceAtomic store operation; advisory locks in PostgreSQL
False rollback after commitCommit finality and a separate afterCommit failure path
Realtime channel disclosureSession/channel authorization, periodic revalidation, and revocation
Slow client or unbounded queuePayload, queue, buffered-byte, subscription, and connection-lifetime limits
Duplicate outbox deliveryAt-least-once contract and consumer deduplication by event ID
Local address in productionHTTPS requirement and loopback/unspecified address rejection

Trust boundaries​

GuildGate assumes these components are configured correctly:

  • TLS termination and proxy-header policy
  • secret management and key rotation
  • PostgreSQL and Redis access control
  • Discord OAuth application settings
  • correct route-to-action mapping
  • fencing and unique constraints for domain writes
  • logs, traces, and error monitoring

Deliberately out of scope​

The package does not automatically solve:

  • XSS in the dashboard HTML or React application
  • operating-system protection for the Discord bot token
  • database backup and disaster recovery
  • third-party API availability
  • application-specific role hierarchy and business rules
  • malicious dependencies or compromised CI accounts

Fail-open and fail-closed choices​

Not every dependency uses the same failure policy. Examples:

  • A write is denied when authorization cannot be resolved.
  • For an action in the fail-closed audit list, the transaction cannot commit if audit persistence fails.
  • If cache or realtime publishing fails after commit, the domain write remains successful; the issue goes to retry handling and telemetry.
  • Retry, timeout, and circuit-breaker bounds for Discord reads are selected per action.

Review checklist​

When adding an action, answer these questions:

  1. How is the resource identity parsed from untrusted input?
  2. When and with which Discord data is authorization checked?
  3. Can a repeated request safely return the same result?
  4. Which worker wins when two workers write the same resource?
  5. How is a failed post-commit side effect retried?
  6. Does the audit event contain secrets or unnecessary personal data?
  7. Does a realtime subscription close after permission loss?

Keep those answers visible in the action definition, store contract, and tests.