Documentation
Security & OAuth.
What TaskBridge is allowed to do, how that authority is stored, and how it is protected. Exact scopes, exact routes, exact lifetimes.
On this page
Sign-in & sessions Tenancy OAuth connections Token storage Logging & redaction Transport & deployment Reporting a concernSign-in & sessions
- Sign-in is passwordless: a magic link is emailed to you. Each link works once and expires in 15 minutes; at most 3 links per hour are issued per address.
- Sign-in is restricted to an explicit invite allowlist of email addresses. Addresses not on the list cannot start a session.
- Sessions last up to 30 days and are carried in an
HTTP-only cookie (
SameSite=Lax,Securein production). Session tokens are not readable by page scripts. - Every mutating API request additionally requires a
CSRF token in the
x-csrf-tokenheader. The cookie alone can not authorize a change.
Tenancy
Every tenant-owned row in the database carries its owner. API handlers derive the acting user from the authenticated session — never from client input — for every read and every write. Bridges, connections, task links, webhook cursors, and activity are all scoped this way.
OAuth connections
You authorize each provider directly on that provider’s own consent screen. TaskBridge never sees or stores provider passwords.
| Provider | Scope | Used for |
|---|---|---|
| Linear | read,write (acting as you) |
Reading issues assigned to you; moving issues between the workflow states you configured; registering the per-connection webhook. Never editing, renaming, or deleting issues. |
| Todoist | data:read_write |
Creating, updating, completing, and reopening mirror tasks in your chosen project. Personal planning fields are never read for decisions and never written. |
The flow
- Each OAuth flow uses a single-use state bound to your signed-in session, valid for 10 minutes. Forged or replayed callbacks are rejected.
- Callbacks land on
/oauth/callback/linearand/oauth/callback/todoist, derived from the application’s configured public base URL — never hardcoded. - The authorization code is exchanged server-side. Neither the code nor the resulting access token is logged or returned to the browser.
- The beta permits one connection per provider per account, enforced by both a database constraint and service-layer checks.
Token storage
- Provider access tokens are stored only as
AES-256-GCM ciphertext, behind an explicit
encryption boundary in the code (
TokenCipher). The 32-byte key lives in server configuration, not in the database. - Disconnecting a provider deletes the ciphertext immediately. Reconnecting requires a fresh OAuth grant.
- Production refuses to start without real encryption, mail, and provider configuration — there is no “insecure fallback” mode.
Logging & redaction
- Authorization headers, webhook signatures, configured sensitive values, and connector error bodies are excluded or redacted from errors and structured logs.
- Configuration errors name variable names only — never values.
- Webhook payloads are verified against the exact raw body before anything is persisted; unverifiable deliveries are rejected.
Transport & deployment
- The public application is served over HTTPS behind a reverse proxy. Neither the application port nor PostgreSQL is exposed directly on a public interface; both bind to loopback on the host.
- Webhook verification (HMAC signatures, replay windows, payload limits) is described in Webhooks & reconciliation.
Reporting a concern
TaskBridge is an invite-only beta run by a single operator. If you believe you have found a security issue, contact the operator through the channel your invitation came from — see Support. Please include enough detail to reproduce, and allow reasonable time to remediate before sharing publicly.