Security

Security, described honestly.

Your clients trust you with their data, and you would be handing it to us. Everything below is a mechanism in the codebase, not an aspiration — and the last section is the list of things we are not claiming.

Access control

Who can see what, decided per workspace.

Permissions are granular rather than a three-tier dropdown. Corker ships 98 individual permissions across seventeen areas of the product, and a workspace composes its own roles out of them.

  • 98 named permissions covering invoices, quotes, projects, issues, epics, tickets, leads, contacts, organisations, products, time, planning, billing, taxonomies, service settings, workspace settings and role management.
  • Roles are rows inside a workspace, not global objects. Every workspace starts with a privileged Team Leader role and a Member role with an explicit allowlist, and you can add your own.
  • There is no global administrator account and no back door: permission checks resolve against the roles you hold in the workspace you are currently in, and nothing overrides them.
  • Every authorisation check re-verifies that you are still a member of the workspace before it looks at your permissions, so removing someone takes effect on their next request rather than when their session expires.
  • Project work adds participants and observers on top, so notifications reach the people actually on a project.

Accounts and sign-in

Getting into an account is the hard part on purpose.

Authentication is built on Laravel Fortify with the throttling and confirmation steps written into the application rather than left at their defaults.

  • Two-factor authentication by authenticator app, with single-use recovery codes. Turning it on requires re-entering your password, and it is not active until you have proved the code works.
  • Two-factor secrets and recovery codes are encrypted before they are stored, never written in plain text, and recovery codes are compared in constant time.
  • Passwords are stored as bcrypt hashes at cost 12 and rehashed automatically when that cost changes. Changing a password requires the current one and sends you an email either way.
  • Failed sign-ins are throttled twice over: five attempts per email address and IP, and twenty per IP across all addresses, to blunt password spraying. Two-factor codes, registrations, password confirmations and verification resends are each rate-limited too.
  • Email addresses must be verified before the application opens, through a signed, throttled, single-use link.
  • Session identifiers are regenerated on sign-in and again after a two-factor challenge, so a session captured beforehand is worthless.

Visibility and control

You can see what your account is doing.

Security you cannot inspect is a claim rather than a control. The security section of your profile shows the state of your account and lets you act on it.

  • A list of your active sessions with the IP address, browser and last-active time of each, current session first.
  • A record of the devices you have signed in from. Only a one-way hash of the device token is stored, and records expire a year after last use.
  • An email whenever a new device signs in to your account.
  • One click to sign every other session out, which also rotates your "remember me" token. It requires your password.
  • Deleting your account irreversibly overwrites your name, email, avatar, password and two-factor credentials rather than leaving them in the database.

Workspace isolation

One tenant cannot reach another, and a test proves it.

Corker is multi-tenant: workspaces share a database and every tenant-owned row carries its workspace. Three independent layers keep them apart, and a test in the build proves it rather than assuming it.

  • A query scope on every workspace-owned record type constrains each query to the current workspace before it reaches the database.
  • Middleware re-checks on every single request that you are still a member of the workspace you have selected, and clears the selection if you are not.
  • Authorisation policies re-derive the owning workspace themselves rather than trusting the query scope, so a cross-tenant request is refused rather than quietly returning nothing.
  • An automated test enumerates every authenticated route that takes a record in its URL and asserts each one answers another workspace's record with a 403 or a 404. Adding a route without covering it fails the build.

Files

Attachments are not public URLs.

Files attached to tickets, quotes, invoices and documents are stored on a private disk that has no public address at all.

  • Every download runs an authorisation check and then re-checks that the file actually belongs to the record you asked for, which closes the "swap the id in the URL" hole.
  • Uploads are capped at 10 MB and validated twice: on the file extension and on the content type as the server itself detects it, so renaming a file does not get it through.
  • SVG, HTML and XML uploads are rejected outright, because all three can carry executable content.
  • Downloads are served with a no-sniff header, and only a short allowlist of raster image formats is ever displayed inline. Everything else downloads.
  • The one exception, stated plainly: images pasted into a rich-text editor inside the application are stored at an unguessable but publicly readable address. Use a file attachment for anything confidential.

Application hardening

The boring defences, actually applied.

Most breaches are not exotic. These are the ordinary ones, and each is a mechanism in the codebase rather than an intention.

  • Cross-site request forgery protection on every form, with a single narrow exception for incoming webhooks, which are signature-verified instead.
  • Incoming webhooks verify a cryptographic signature with a five-minute timestamp window against replay, and refuse everything if no signing secret is configured.
  • User-written content is rendered with raw HTML escaped rather than passed through, and links using javascript:, vbscript:, file: and similar schemes are neutralised.
  • Search terms are escaped before they reach a LIKE query, so wildcards in user input cannot widen a search or be used to hang the database.
  • URL segments that address a record by number are constrained to digits before they reach the database.
  • Cookies are encrypted and HTTP-only, with SameSite set to Lax.

Change history

Who changed what, and when.

Corker records a per-field change history rather than a comprehensive audit log, and it is worth being precise about the difference.

  • Issues, epics, projects and leads record one entry per changed field, with the previous value, the new value and the user who made the change.
  • Tickets keep their own typed timeline: status changes, assignment, priority, linked issues, contacts added or removed, and every reply.
  • Invoices carry a timeline of their own lifecycle events.
  • What is not covered, and we would rather say so: sign-ins, role and permission changes, membership changes, settings changes and file downloads are not written to that history today.

How it is built

Every change runs the same gauntlet.

Security properties survive refactors only if something checks them automatically. Corker's pipeline is the same on every commit.

  • Static analysis at PHPStan's strictest level, across the application code and the Blade templates, with unmatched suppressions reported as errors.
  • 100% type coverage, enforced as a build failure rather than tracked as a metric.
  • More than 600 test files, run against PostgreSQL and SQLite and again in a real browser, on every change.
  • Code style and automated refactoring both run in check mode in CI, so drift fails the build.

What we are not claiming

The section most security pages leave out.

Corker is a pre-launch product built by one person. Plenty of the badges you are used to seeing on a page like this would be false, so they are not here.

  • No SOC 2, ISO 27001 or any other compliance certification. None has been attempted.
  • No third-party penetration test has been carried out, and there is no bug bounty programme.
  • No uptime service level agreement. Corker has SLA features for your tickets; that is a different thing, and we are not going to let the two blur together.
  • No claim of encryption at rest beyond specific fields. Passwords are hashed, two-factor credentials and cookies are encrypted, and whole-database encryption is a property of the hosting platform rather than something Corker implements.
  • No published backup and disaster-recovery policy yet.
  • No automated dependency vulnerability scanning in the build yet.
  • The client-facing support portal, including its expiring signed links, is built but is not switched on in production. When it goes live it will be described here as live, and not before.

Reporting a vulnerability.

If you find a security problem in Corker, email [security contact email address] with enough detail to reproduce it. There is no bug bounty, but you will get a reply from the person who can fix it, and credit if you want it. Please give us a reasonable window before publishing.

For what happens to your data rather than how it is guarded, read the privacy policy — it is written from the same code this page is.

Request early access

Related: Privacy policy, Terms of service, Pricing at launch.