The security model
The short version: nothing is trusted by default, tenant isolation is enforced in the database rather than only in application code, and every credential is encrypted before it touches storage.
Authentication
Section titled “Authentication”Local accounts use Argon2id password hashing. Not SHA-256, not bcrypt with a low cost factor.
Sessions are stateless JWTs with refresh tokens. Access tokens are short-lived; refresh tokens are revocable and are revoked in the same transaction when an account is deactivated, whether by hand or through SCIM.
Two-factor authentication is TOTP, set up by each user under their account. Disabling it requires a current code, so somebody at an unlocked machine cannot simply turn it off.
Single sign-on is generic OIDC or SAML 2.0. The OIDC flow uses PKCE and a nonce, and fixes the audience at the start of the flow so it cannot be changed on the way back. See SSO.
Authorisation
Section titled “Authorisation”Role-based, with fine-grained permissions. A role
holding * is a superuser within its tenant, and there is no permission anywhere
that crosses a tenant boundary.
The same checks run on every surface: the web console, the REST API, the MCP server and the assistant. There is no ambient administrator and no back door for an integration.
Two of the splits are on purpose:
ticket.internalseparates the desk’s own notes from working the queue, so a casual can be given the queue without being given the notes.charge.raiseandcharge.approveseparate proposing a charge from making it real, and waiving sits with approval rather than raising.
Tenant isolation
Section titled “Tenant isolation”Three layers, and a query missing tenant context fails rather than returning everything. See tenant isolation.
Secrets
Section titled “Secrets”Connector credentials are protected with envelope encryption. They are encrypted before they reach the database and decrypted in memory only for the duration of a call.
A connector handler never receives database access. It returns data and the platform decides what to persist. See secrets and keys.
The outbound fetch guard
Section titled “The outbound fetch guard”Plugboard accepts URLs from tenants: service monitor targets, webhook endpoints, connector base URLs. Any of those could be pointed at an internal host or a cloud metadata service.
So outbound requests to private, loopback and link-local addresses are blocked by default.
A self-hosted install that legitimately monitors LAN addresses opts out:
ALLOW_PRIVATE_EGRESS=1Leave it off for anything multi-tenant. A managed deployment uses a connector agent instead, which reaches internal systems without Plugboard ever making a request to a private address.
Transport
Section titled “Transport”TLS 1.2 is the floor. HSTS is sent. HTTP redirects to HTTPS. A strict content security policy is applied.
The API sets trust proxy, so a reverse proxy’s X-Forwarded-Proto and
X-Forwarded-For are honoured. See HTTPS and
certificates.
Rate limiting
Section titled “Rate limiting”Applied to authentication endpoints and to the public API per key.
Append-only, covering every action that changes state or grants access. Entries cannot be edited or deleted through the application by anybody, including administrators. See the audit log.
Vendor access to a managed deployment appears in your own audit log, attributed to the engineer, and can be disabled outright.
Supply chain
Section titled “Supply chain”Every release image is signed with cosign, keyless, so there is no signing key to leak. Each carries an SPDX SBOM attestation. Images are scanned, and a critical finding fails the build.
Portable bundles are covered by a checksum published beside each one, and the automatic updater refuses an archive that does not match, because it runs unattended with privileges and “probably the right file” is not good enough.
Verification instructions are in updating.
What is your responsibility
Section titled “What is your responsibility”SECRETS_MASTER_KEY, kept somewhere other than the server.
The certificate, and its renewal.
Who holds which role. The product enforces permissions; it cannot tell you
that four people should not have device.manage.
Deciding when to update. Nothing updates itself except the on-premises bundle, which you can turn off.
Restoring a backup once, to confirm your regime works.
Reporting a vulnerability
Section titled “Reporting a vulnerability”See the project’s SECURITY.md for the disclosure process and the supply-chain
guarantees.