Data isolation
WorkThroughLine is multi-tenant: several organizations share one instance but never see each other’s data. Isolation is held in two layers that do not depend on one another:
- Application layer: every query is scoped to the organization from the session, and every inbound identifier (foreign key) is checked to belong to that organization before anything is written.
- Database layer: PostgreSQL Row-Level Security (RLS). The application connects to the database as an account without superuser rights, so RLS is genuinely enforced - each request runs inside a transaction that sets the active organization, and the database itself rejects rows outside it.
Migrations and database maintenance run through a separate privileged account that is never used for application traffic. Even if the application layer failed, RLS remains as the second barrier.
Access and authentication
- Passwords are never stored in readable form - only as a bcrypt hash. Sign-in takes constant time so it cannot reveal whether an account exists.
- Sessions: a short-lived JWT access token plus a rotating refresh token. If an already-used (rotated) token is presented again, we treat that as possible theft and invalidate that user’s entire token family.
- Two-factor sign-in (2FA): optional TOTP (any authenticator app, per RFC 6238), with single-use recovery codes in case the phone is lost. Recovery codes are stored hashed.
- Role-based access control inside the organization determines who sees and changes what.
Encryption
- In transit: TLS on every public connection (Caddy with Let’s Encrypt certificates).
- At rest: secrets the system must read back - TOTP 2FA secrets and webhook signing secrets - are encrypted with AES-256-GCM (authenticated encryption with a separate nonce and integrity tag per record). Values we never need to decrypt (passwords, API keys) are stored hashed only.
Change record (audit log)
Every data change automatically writes an audit-log entry, across all modules (strategy, discovery, delivery, documentation).
- Administrators get an org-wide view in settings: who changed what and when, with per-field differences for create, update and delete.
- The view filters by user, action type, entity and date, and can be exported.
- At the level of a single item, the change history is visible directly on the work item.
Backups, recovery and portability
- Off-site backup: a daily encrypted database snapshot (with runtime configuration) is sent to an encrypted restic repository off the server. Everything is encrypted before it leaves, so the destination never sees plaintext.
- Verification and proof: a weekly repository integrity check and a monthly automated restore drill that genuinely restores the latest archive into an isolated, throwaway database and verifies it (SHA-256 manifest plus row and migration counts). We do not consider a backup valid until the restore is proven.
- Retention: 14 daily, 8 weekly and 12 monthly snapshots; the target RPO is 24 hours. An automatic alert fires if a backup, check or drill runs late.
- Self-service organization export and restore: an administrator can export the whole organization as a versioned, restorable JSON bundle (without passwords, 2FA secrets, tokens or webhook secrets), including every attachment and its SHA-256 hash. Restoring into an empty tenant re-exports and compares the result to prove the copy is faithful. Work items can additionally be exported as CSV. This exists for portability and as proof that you can take a pilot back out intact.
Safe Jira migration
The Jira Migration Assistant is built for a controlled, one-time cutover without changing the source Jira. An administrator first runs preflight and mapping, neither of which writes data. Import only starts after explicit confirmation.
- No deletion: import never deletes data, in Jira or in WorkThroughLine.
- No duplicates: stable Jira identities make repeating an import safe.
- Manual changes protected: the default mode skips previously imported items that were manually changed afterwards.
- Isolation: mappings, import history and the Jira connection belong to one organization and are protected by PostgreSQL RLS policies.
- Temporary file: the CSV for the background job is stored encrypted, has an expiry, and is deleted on successful completion.
- OAuth: Jira Cloud access and refresh tokens are stored encrypted and removed when the connection is severed. The direct connection will not be advertised as active before production verification.
A detailed description of supported data and limitations is on the Migrate from Jira page.
API, MCP and Git webhooks
- Access to the API and hosted MCP goes through a personal API key that is stored hashed. Codex, Claude Code and other MCP clients inherit the key owner’s role, maker rules and RLS tenant isolation. Only ADMIN, PM and DEV can create one key each; stakeholder and guest accounts cannot.
- GitHub and GitLab: an inbound GitHub webhook passes HMAC signature verification, and GitLab a secret-token check, before any tenant processing. We do not store a provider access token; the connected repository, branches, commits and pull or merge requests belong to exactly one organization.
- Signed webhooks: every outbound delivery carries an HMAC-SHA256 signature of the message body (the
X-WTL-Signatureheader) so the receiver can verify authenticity; the comparison is constant-time. - SSRF protection: because the user supplies the webhook URL, we prevent the server from reaching a private network. The URL is validated and the destination address is checked at connect time - loopback, private (RFC1918), link-local and cloud-metadata ranges are blocked, which also closes DNS rebinding.
The signature-verification recipe and the API reference are on the Developers page.
Incident reporting and availability
- Availability of the API, the public web and sign-in is checked automatically; a failed deploy is rolled back to the previous version automatically.
- We have a written incident procedure with severity levels. Report a security or operational incident to [email protected] (time, URL and the
requestIdif you can see it; no passwords or sensitive content). - We notify administrators of a personal-data breach without undue delay, and within 72 hours at the latest from becoming aware of it.
Availability and reporting details are on the Status and incidents page.
Jurisdiction, EU hosting and GDPR
- Data is processed primarily on servers in the EU (Amsterdam, Netherlands).
- We comply with the Serbian Personal Data Protection Act (ZZPL) and the EU General Data Protection Regulation (GDPR). We give at least 15 days’ notice before changing or adding a sub-processor.
- The details, the roles and the full sub-processor list are in the Data Processing Addendum (DPA) and the Personal Data Processing Policy. Both are published in Serbian.
What we do not claim (yet)
WorkThroughLine is currently in free beta, and we talk about security honestly:
- We do not (yet) hold ISO 27001 or SOC 2 certification - we do not present one and will not claim it until we have it.
- We do not promise a specific RTO (recovery time) until we have measured it on a full-size restore drill; the RPO is based on daily snapshots (no point-in-time recovery for now).
- Full contractual processor details and binding retention/deletion periods will be defined before the first paid contract.
If your pilot needs something you do not see here, ask - we will tell you what exists, what is planned and what we do not do.
Have a security question before a pilot, or need this page as a PDF for an internal review? Save it from your browser (Print → Save as PDF) or write to [email protected].