Security
For administrators, and for whoever has to answer a security questionnaire about this desk.
The isolation model
Everything belongs to a brand, and staff belong to brands and departments. That boundary is enforced in the policies every request passes through, not in the screens, so a page that forgets to filter still cannot show what it should not.
Concretely:
- An agent cannot reach a brand or department they are not in, by any route: list, search, direct link, API, AI answer, rule, or a link from something they can see.
- A members-only project is invisible to everyone not named on it, not listed, not fetchable, not searchable, and never named by a relation from an issue they can see.
- A report is visible to whoever can see the project its type points at. A security report whose work was planned into an open project does not become visible because of that.
- Canned responses, knowledge, tags, rules, drafts, console answers and projects never cross a brand.
- A ticket can only be linked to an issue in its own brand.
Identity
Client records link on proof of control, never on an email address matching. Proof is: the platform vouching for a signed-in browser session, a token from an email only that mailbox received, or a ticket’s own reply token. A message whose sender merely looks like a client is filed as a guest sender.
This is the single most important design decision in the desk, and it is why a forged From: header
achieves nothing.
Staff sign-in
Email and password, with two-factor (authenticator app plus recovery codes) and passkeys. The desk policy can require two-factor for administrators or for everyone. Trusted devices expire. Changing a password signs every session out everywhere.
Administrators can work as another staff member; the history and the audit log record who really acted, and impersonation cannot touch sign-in security.
Tokens and keys
| Scope | |
|---|---|
| Integration keys | One brand, the client-facing routes only |
| Automation keys | One project, an allow-list of issue routes, the permissions ticked, running as their maker |
| Chat sessions | One browser, one brand; cleared on sign-out so a retained copy stops working |
| Report links | One report, expiring |
| Rating links | Single use, expiring with the rating window |
| Calendar feeds | Read-only, revocable, token stored hashed |
Expiring tokens are pruned nightly. Secrets, mailbox passwords, platform keys and repository private keys are all encrypted at rest, and the repository private key appears in no API response at all.
Uploads
See Files and attachments. In short: an allow-list per brand and per group decides what is
accepted, a content check refuses a program wearing another extension, files live outside the web root,
and everything is served as a download with nosniff.
Untrusted text and the AI
Anything the desk did not write, a client’s message, a crawled page, a commit subject, an issue title from a stranger’s report, is fenced before it reaches a model, under a random tag generated for that one request, with marker-shaped text inside it rewritten, and the system prompt says nothing inside a fence is an instruction.
So a crawled documentation page cannot tell the assistant to do something, and neither can a commit message or a ticket.
The public surface
These are reachable without signing in, and each is deliberately narrow:
- The chat widget API, brand key plus an allowed origin, rate limited per address.
- The site snippet: announcements and status for allowed origins.
- The status feed: read-only, and closable per brand.
- The report form: with human verification where the brand has it configured, address confirmation before anything reaches a project, and per-address limits.
- Guest ticket links: a token per ticket.
- Signed platform lookups: timestamp, one-time nonce, HMAC; a replayed request is refused.
- Repository pings: the same signature; every failure answers the same 404.
What is audited
Sign-ins and failures with the method, sign-outs, two-factor and passkey changes, impersonation, password changes, token creation and revocation, credential reveals, conversation exports, rule changes, project and membership changes, publishing to a reporter, announcements, incidents, chat blocks, quarantine actions, and every automation key made, changed or revoked.
The log is append-only. Nobody can delete an entry, including an administrator.
Your side
The desk cannot do these for you:
- Keep the server patched, and keep PHP and the database current.
- TLS everywhere, with a real certificate.
- SPF, DKIM and DMARC on every brand’s sending domain.
- Back up off the box, and test a restore, see Backups.
- Require two-factor for administrators. It is one setting.
- Review staff access when people change roles, and deactivate rather than delete when they leave.
- Keep
.envat mode 600, and treat the application log as sensitive.
Reporting a vulnerability in the desk itself
If you find one, report it privately to whoever supplied your install. If you run the public report intake, point your own security type at a members-only project so a report about you does not arrive somewhere everybody can read it.