Skip to content

How Sail is protected

  • Your identity provider only. People sign in through your provider over OpenID Connect, using the authorization code flow with PKCE. Sail never sees or stores a password.
  • MFA and password rules stay in your provider, where you already enforce them.
  • Identity by issuer and subject, never by email. Changing someone’s email doesn’t hand their account to someone else.
  • You decide who gets in, by email domain, provider group, or both. With neither set, only owners can sign in.
  • Leavers lose access within the hour. Sail re-checks every person with your provider each hour. Removed or disabled people are signed out, and the audit log records it.
  • Locked out? sail admin recover on the server gives a one-time owner link, valid for an hour, and the audit log records it.
  • Sessions live on the server and can be ended at any time.
  • The browser holds only a random session cookie: __Host- prefixed, Secure, HttpOnly and SameSite=Lax. Sail stores just a hash of it, so a leaked database contains no working sessions.
  • Your provider’s tokens never reach the browser.
  • Every request that changes data needs a separate anti-forgery header.
  • Idle timeout (12 hours by default) and longest session (7 days by default) are policies you set.
  • People can Sign out everywhere. Admins can end anyone’s sessions.
  • Four roles: owner, admin, auditor and member, plus team managers. See People and teams.
  • No role, including owner, can read other people’s chats or memories.
  • Every policy is enforced on the server. The interface only hides what’s not allowed.
  • Every policy and role change is recorded in the audit log, with values before and after.
How
In transitHTTPS. Sail requires an https:// address, and sends HSTS. The bundled Caddy gets certificates on its own, or uses yours.
Stored secretsEncrypted by Sail with XChaCha20-Poly1305, using a key only your server holds. This covers the identity provider’s client secret, the Nexus credential, and people’s refresh tokens.
Sessions and share linksStored only as hashes
Chats, memories and filesNot encrypted by Sail. Protect them with encrypted disks and encrypted backups.

The secret key is never included in backups, so a stolen backup can’t be used to read the secrets in it.

  • Outside text is data, not instructions. Assistants are told that web pages, files and tool results are data to use, never instructions to follow. This reduces prompt injection. No AI system can rule it out completely.
  • No code runs. Sail never runs code a model writes. There’s no Python sandbox. Word, Excel, PowerPoint and PDF files are created and read by Sail itself.
  • Files are checked. Uploads and generated files are refused if they contain macros, ActiveX or embedded objects, external links, data connections, or formulas that reach outside the workbook. PDFs with scripts, launch actions or embedded files are refused too. Archive and XML limits stop zip bombs.
  • Pages are fenced off. Interactive pages run on a separate domain, in a sandbox with no network access, no forms and no access to Sail’s cookies or data. Admins can turn scripts off entirely.
  • No silent requests. Images from outside websites don’t load in answers until the person clicks. Links in answers, pages and PDFs ask before opening.
  • Tools can ask first. Tools set to “ask” in Nexus pause the reply until the person allows it.
  • Uploaded files never run. Files are always downloaded, never opened as web pages on Sail’s address.
  • Records sign-ins, people losing access, role and team changes, policy and settings changes, assistant publishing and sharing, chat and file sharing, exports, Nexus connection changes, erasures and owner recovery.
  • Each entry has who, what, when, the target, the IP address and a request ID.
  • Never records message content or secrets.
  • Owners, admins and auditors can read it, and export it as CSV or JSON.
  • Kept for 365 days by default, at least 30.

Sign-ins Sail turns away, such as someone outside your allowed domains, aren’t in Sail’s audit log yet. Your identity provider records every sign-in attempt.

  • Small attack surface. One Rust binary, on a minimal “distroless” image with no shell and no package manager, running as a non-root user. Only the data volume is writable.
  • Memory-safe code. The server is written in Rust, with unsafe code forbidden across the project.
  • Locked-down outbound calls. Sail calls only your identity provider and Nexus. It refuses private addresses unless you allow them, and never follows redirects, so a bad URL can’t be used to reach into your network.
  • Strict browser headers: a Content Security Policy with no inline scripts, X-Frame-Options: DENY, nosniff, a same-origin referrer policy, and a permissions policy that blocks the camera, microphone and location.
  • Quiet logs. Logs carry request IDs and error codes, never message content, secrets or query strings.
  • Errors without internals. People see a clear message and a request ID, never a stack trace.
  • Every change runs automated tests, including against real Postgres, plus an upgrade-and-rollback test.
  • Rust dependencies are checked against the RustSec advisory database and an allowed-license list in every build.
  • Dependency updates are proposed weekly and must pass the same tests.
  • Sail’s images are signed with Sigstore cosign and include a software bill of materials (SPDX), at /usr/share/doc/msty-sail/sbom/ in the image.

So you can plan around it:

  • No SOC 2, ISO 27001 or other certification is claimed yet.
  • Sail doesn’t encrypt chats and files itself, and doesn’t support customer-held keys.
  • Rotating the secret key isn’t supported yet.
  • Streaming the audit log to a SIEM isn’t supported yet. Export it instead.
  • Provisioning people with SCIM isn’t supported yet. People are created at first sign-in, and teams can sync from provider groups.