A security tool has to be worth trusting.
What protects the platform, what leaves your network, and the weaknesses we know about. All three, on one page.
The second factor is checked after the password, never instead of it
- Two factors
- TOTP and WebAuthn passkeys. A successful password on an enrolled account returns a short-lived pre-auth token and no session cookie: the session only opens once the second factor is verified.
REQUIRE_2FAforces enrolment across a whole workspace. - Recovery codes
- Offered only alongside a real factor, never on their own. An account can never end up protected by codes alone.
- Removing a factor
- Always re-asks for the password. A stolen session must not be enough to strip protection and then sign in as the user. The administrative reset refuses to cross an organisation boundary.
- Sessions
- Server-side, seven days, three concurrent per user. Revoking one takes effect immediately rather than waiting for a token to expire.
- Rate limiting
- On everything that verifies a code or reaches a third party. A TOTP is six digits, so an unthrottled endpoint is not a second factor.
A key that can ingest an alert should not be able to delete a case
| Kind | Prefix | Belongs to | Can do |
|---|---|---|---|
| Account key | mlab_acc_ | A person | Exactly what its owner can do in a browser, judged by the same permission checks. Revoked when the account is. |
| App token | mlab_app_ | The organisation | Create alerts, and nothing else. Enforced at the router on an exact path allowlist rather than trusted to sixty-seven handlers. |
Identifiable when leaked
The prefix names the kind, so a key pasted into a log or a repository is recognisable by a person reading it and by a secret scanner.
Private by default
The settings page shows you your own account keys and the workspace's app tokens. Administrators see everything. Members no longer see each other's.
Write-only secrets
Provider keys and webhook URLs are stored once and never sent back to a browser, only replaced. A read-only viewer cannot exfiltrate them from the settings page.
Everything that leaves your network
Nothing on this list is telemetry, and nothing on it carries a case, an alert or a piece of evidence to us.
- License validation
- Once per hour, a signed HMAC challenge to
mlab.sh/api/v1/ir/license/validate. It carries the tier, a timestamp and a nonce. The result is cached locally with a 48-hour grace window. Always on. - Enrichment lookups
- Only to the sources you enable, only for the observable types you route to them, and only the observable value. Off until you configure a source.
- Outbound webhooks
- Only to the destinations you create, carrying the event you subscribed to. Off until you create a subscription.
- Playbook HTTP nodes
- Only to the URLs your own playbooks contain. Private and internal destinations are refused, including through a redirect.
- Never
- No usage analytics, no error reporting to a SaaS, no alert, case, observable or evidence content. Outbound requests never follow redirects, so a credential cannot be replayed to a host nobody chose.
Stated, rather than left to be discovered
Provider keys are not encrypted at rest
The column is binary, which is not encryption. A database backup contains them. The same is true of API keys, stored in the clear so the settings page can show a preview. Protect your backups accordingly.
No enterprise single sign-on
No OIDC and no SAML in this build. Access is password plus a second factor, with server-side sessions.
Domain scans do not survive a restart
The result is persisted once it arrives, but a scan in flight dies with the process and leaves no trace.
Provider fixtures are synthetic
The 27 recorded provider responses were written from vendor documentation. A green test suite means the parsing is self-consistent, not that the vendor's API still looks like that.
What the test suite actually proves
432 unit and integration tests
Run on every build, alongside a job that hands all 419 SQL statements in the codebase to MySQL to parse. A query that does not prepare is caught before release, not by a customer.
Webhook delivery on a real socket
The suite stands up a listener and checks what arrives on the wire, including that the HMAC signature covers the exact bytes sent.
Provider schemas
Every JSON path a provider module reads is extracted from the source and checked against a recorded response. A mapping that reads nothing fails the build.
Template structure
Page templates are checked for balanced tags, links that resolve, ids that exist and no inline colour, so a theme or contrast fix cannot be silently escaped.