> Source: https://www.gitdash.info/docs/security · GitDash v4.7.1

# Security model

Your token never reaches the browser

The GitHub token (PAT or OAuth) lives in an encrypted, HTTP-only session cookie that only the server can read. Pages call GitDash's own API; the server calls GitHub.

## Request flow

```text
Browser ── /api/... ──► proxy.ts
                          │  decrypts the session cookie
                          │  no session        → /login or /setup (pages), 401 (API)
                          │  organization mode → identity + groups, then the route's grant
                          ▼
                     API route ── token from the session ──► GitHub REST API
                          │
                          ▼
                     JSON response (never contains the token)
```

## Protection layers

| Layer | Mechanism |
| --- | --- |
| Session | iron-session (AES-256-GCM); cookie is `HttpOnly`, `SameSite=Lax`, `Secure` in production, 7-day lifetime. `SESSION_SECRET` must be at least 32 characters. |
| Sign-in | The session is replaced on every sign-in, so an old session cannot carry over to a new account. |
| Cross-site requests | State-changing API requests from another origin are rejected; token sign-in only accepts JSON from GitDash's own pages. |
| Rate limits | `/api/auth/setup` 5 per minute per IP · `/api/auth/login` 10 per minute · issue creation 5 per hour |
| Input validation | Owner, repo and org parameters are validated before any GitHub call (`src/lib/validation.ts`). |
| Authorization | Organization mode checks the route's grant on the server for every request (see Access control). |
| Secrets in responses | Alert destinations (webhooks, email) and AI/email settings are visible to admins only in organization mode. |
| HTTP headers | Content-Security-Policy, HSTS, X-Frame-Options: DENY, X-Content-Type-Options: nosniff, Referrer-Policy, Permissions-Policy. |
| Container | Runs as the non-root `nextjs` user on `node:20-alpine`. |
