DocsReference
Security model
How Gatehouse protects tokens, credentials, the audit log and the console, and what it assumes.
This page describes how Gatehouse protects itself and your systems. For a shorter summary, see Security.
Identity and tokens
- Agents sign in with OAuth 2.1 and PKCE. Access tokens last one hour. Refresh tokens rotate on every use.
- Replaying an authorization code revokes every token it issued.
- Only hashes of tokens are stored. A database copy doesn't contain usable tokens.
- MCP sessions are bound to the person who opened them. Another person's token can't use them.
- Disabling a person revokes all their tokens immediately.
- Reusing a refresh token that was already rotated revokes every token that agent has, because it means someone has a copy.
- The admin API only accepts personal tokens. Tokens agents get through MCP sign-in work on
/mcpalone. - Passwords are hashed with scrypt at OWASP's recommended cost (N=2^17). Older hashes are upgraded at the next sign-in.
- Two-step codes work once, and 10 wrong codes lock the account, however many times the password is re-entered.
- A locked account gets the same answer as a wrong password, with the same timing, so sign-in doesn't reveal who has an account.
- Changing a password signs out your other devices. A reset signs out everywhere and revokes agent sign-ins.
Credentials
- Server credentials, SSO client secrets and the audit stream secret are encrypted with AES-256-GCM using the master key.
- Agents never see credentials. Gatehouse adds them only on its own call to the MCP server.
- Local (stdio) servers get only
PATH,HOMEand their own secret variables, not Gatehouse's environment. - Variables that change how programs run (
NODE_OPTIONS,LD_PRELOAD,PYTHONPATH,PATHand similar) can't be set as credentials, by admins or by people saving their own. - Only owners can add a local (stdio) server or change what it runs, because it runs a program on the Gatehouse host. Limit the programs with
GATEHOUSE_STDIO_COMMANDS, or turn local servers off withGATEHOUSE_DISABLE_STDIO=true. - Gatehouse never connects to cloud metadata or link-local addresses (
169.254.0.0/16,fe80::/10,metadata.google.internal), for MCP servers, SSO issuers or audit streaming. - The master key can come from your KMS or vault and never be written to disk. See Self-hosting.
Tool calls
- Default deny. New tools are off, and calls no policy allows are refused.
- Definition pinning. Gatehouse hashes each tool's name, description and schema when it's enabled. Any change pauses the tool until reviewed.
- Poisoning scan. Descriptions are checked for text that tries to instruct the model.
- Secret scanning. Arguments that contain credentials are refused. Credentials in results are redacted before the model sees them.
- Separation of duties. Nobody can approve their own call.
- Conditions fail closed. If an argument has an unexpected type (a list where a word was expected, say), deny and approval rules still apply.
- Safe patterns. Regex conditions that could run for exponential time, like
(a+)+, are refused when saved, and long inputs aren't matched. - Owner protection. Admins can't reset, disable, sign out or unlock owners. Only owners can.
Audit log
- Append-only, enforced by database triggers that reject updates and deletes.
- Hash-chained with an HMAC keyed by the master key, so someone with raw database access but without the key can't edit an entry and recompute the chain. Run
npm run cli -- verify-auditor see Settings → General. - Exportable as CSV (cells that would run as spreadsheet formulas are neutralized) and streamable to your SIEM with signed requests.
Console and web
- Cookies are
HttpOnlyandSameSite=Lax, andSecureover https. - Every form post is checked for the same origin.
- A strict Content Security Policy allows only Gatehouse's own scripts and styles. Pages can't be framed. HSTS is sent over https, plus
Permissions-Policy,Cross-Origin-Opener-Policyandnosniff. - Only the configured
GATEHOUSE_BASE_URLcounts as the same origin. The client'sHostheader is never trusted. - Messages shown from a link (
?err=,?ok=) appear only when Gatehouse signed them, so a crafted link can't show a fake message. - Sign-in is rate limited per IP, and accounts lock after repeated failures.
Single sign-on
- OIDC ID tokens are verified against the provider's keys, issuer, audience, expiry and nonce.
- SAML assertions must be signed by the configured certificate.
- Sign-in state is single-use, expires after 10 minutes and is bound to the browser that started it, which stops login CSRF.
- Every SAML response must answer a request Gatehouse sent, and each request is accepted once (no assertion replay).
- An email must be verified by the provider (
email_verified). For Microsoft Entra ID, which doesn't send that claim, an owner turns on Trust emails for that provider. - The first sign-in links the SSO account (provider and subject) to the Gatehouse account. After that, a different SSO account with the same email is refused.
- Owner accounts are only linked by a provider limited to your company's email domains.
Directories and SCIM
- LDAP connections must use LDAPS or StartTLS (
GATEHOUSE_ALLOW_PLAIN_LDAP=trueis for labs). Values in filters are escaped, and empty passwords are refused. - SCIM can't change owners, or people who sign in with a Gatehouse password, so a leaked SCIM token can't redirect their email. A PUT without
activekeeps the current state. An email change signs the person out and revokes their agent tokens.
What Gatehouse assumes
- You run it behind TLS and keep the host patched.
- You protect the master key and the database volume.
- MCP servers you add can still do whatever their credentials allow. Gatehouse decides whether a call happens, so give each server the narrowest credential that works.
- A person who is allowed to call a tool can misuse it. Approvals and the audit log help you catch and review that.