Shared SaaS mode
Genosyn can serve many customer companies from one deployment. Shared SaaS mode turns the production boundaries into startup requirements, so an unsafe configuration fails before the server accepts traffic.
Required production baseline
Set the following values in App/config.ts. Use independently generated secrets; do not copy the examples into production.
security: {
multiTenant: true,
encryptionSecret: "<independent 32+ character random secret>",
previousEncryptionSecrets: [],
secureCookies: "auto",
sessionMaxAgeDays: 7,
trustedProxyHops: 1,
outboundPrivateHostAllowlist: [],
outboundRequestTimeoutMs: 15_000,
outboundMaxResponseBytes: 25 * 1024 * 1024,
authRateLimit: { windowMinutes: 15, maxAttempts: 10, blockMinutes: 15 },
bootstrapMasterAdminEmail: "operator@example.com",
},
agent: {
codingTools: {
enabled: true,
executionMode: "bubblewrap",
bubblewrapPath: "/usr/bin/bwrap",
allowNetwork: false,
allowUnsafeHostExecution: false,
},
browserEnabledInMultiTenant: false,
},
db: {
driver: "postgres",
sqlitePath: "",
postgresUrl: "postgresql://…",
},
sessionSecret: "<different 32+ character random secret>",Those are the boot settings — the whole of config.ts that matters here. Operational settings are not in the file at all; they live in the database and are edited at Admin → Runtime without a restart. Shared SaaS still forces the isolation boundaries regardless of what is saved there: member browsers are refused in multi-tenant mode even when the setting is on.
A working global SMTP transport is effectively mandatory because new Members must verify their email and account recovery must reach a mailbox. It is not a boot requirement — a fresh install has no database row and no operator yet, so boot warns loudly and writes system mail to the server log rather than refusing to start. That is how the bootstrap operator claims the first account. Configure Admin → Email transport immediately afterwards, before inviting anyone else; Admin → Instance Health keeps flagging the transport until you do.
On the first operator sign-in, Genosyn detects the same-origin browser URL. Review and save the canonical HTTPS origin at Admin → General before configuring SSO, WebAuthn, or OAuth integrations. It is stored in Postgres and propagated across replicas.
What startup checks
- Postgres is selected and has a connection URL.
- Session cookies are Secure.
- The session-signing and encryption secrets are strong and different.
- The Bubblewrap binary exists, shell networking is off, and the shared browser is off.
- No private outbound hostname exception is configured.
- A bootstrap operator email is configured.
If any check fails, Genosyn exits with the exact unsafe setting instead of silently starting in a partial posture. The system SMTP transport is the one exception: it is checked at boot but only warned about, because the dashboard that configures it has to be reachable first.
Tenant and identity boundaries
- Company scope
- Every customer resource is selected through a verified Membership and company id. API keys are bound to one company.
- Roles
- Members can collaborate; owner/admin roles control sensitive configuration. Owners promote, demote, and remove Members in Settings. Removal revokes company API keys and clears private Channel and Project membership.
- Email ownership
- Hosted Members verify a single-use, hashed email token before creating a company or accepting an invitation. The signed-in email must match the invitation.
- Two factor
- A company owner or admin can require 2FA for every Member. Master admins must always enroll and complete a second factor to use the hosted operator control plane, and must sign in again after 15 minutes before another operator action.
- Sessions
- Password changes and resets increment a server-side session version, invalidating every older signed cookie across replicas.
AI execution isolation
Each AI employee's shell runs inside Bubblewrap user, mount, PID, IPC, UTS, and network namespaces, plus a cgroup namespace where the kernel supports it. Only that employee's workspace is writable; the API process environment is not inherited. File tools resolve real paths and reject symlink escapes. Top-level AI work, including Routine runs and chat, can overlap without an application-level per-company cap. One AI Employee replies to each of their chat threads in parallel; only two replies in the same thread are serialized.
- Company secrets are not injected into hosted coding shells.
- Arbitrary stdio MCP servers are not started in shared SaaS mode.
- The app-owned browser is unavailable until it moves to a separately isolated browser worker. See Browser for self-hosted mode.
Outbound network policy
URL ingestion, Pipeline HTTP nodes, AI Model endpoints, MCP endpoints, and configurable Connection hosts reject loopback, private, link-local, carrier-grade NAT, documentation, multicast, and reserved addresses. Every redirect is rechecked, responses are bounded, and DNS is checked again at socket connection time to stop rebinding attacks. Keep a cloud egress firewall that blocks metadata and private ranges as defense in depth.
Raw-TCP Postgres and MySQL Connections and arbitrary Repository remotes are disabled in shared SaaS mode until they can run in a dedicated egress worker. Fixed-host GitHub checkouts remain available through a granted GitHub Connection.
Running more than one replica
Postgres stores OAuth/OIDC/WebSocket handshake state, scheduler leases, same-AI-Employee chat-reply leases, and short-lived realtime fan-out records. Recurring work elects one replica, pending mail handovers are claimed atomically, Telegram listeners fail over, and Postgres LISTEN/NOTIFY carries authorized WebSocket events between replicas.
- Mount the same
dataDiron every replica with ReadWriteMany storage. Uploaded files and employee working trees still live there. - Use one migration job or allow the first replica to apply migrations before rollout.
- Forward WebSocket upgrades and preserve the original HTTPS origin at the ingress.
- Use a managed Postgres backup and back up the shared data volume separately. Genosyn's built-in SQLite archive and restore surface is disabled in shared SaaS mode.
Launch checklist
- Start with an empty Postgres database and let the Postgres migration stream apply.
- Configure HTTPS, trusted proxy hops, strong secrets, and the bootstrap email.
- Run the container with Bubblewrap/user namespaces available and shell network disabled.
- Create the operator account using the exact bootstrap email, then verify it. With no transport configured yet, that verification link is written to the server log — copy it from there. The account is not a master admin and cannot reach operator APIs before the verification succeeds; verification revokes the pre-verification session, so sign in again.
- Configure the system SMTP transport at Admin → Email transport and send the test message, before inviting anyone else. Until this passes, no other Member can verify an address or recover a password.
- Enroll an authenticator, passkey, or security key, then sign in again with that factor to unlock the operator control plane.
- Test signup, verification, password reset, invitation matching, role denial, and 2FA.
- Test two concurrent companies and at least two replicas against shared storage.
- Keep database, volume, ingress, SMTP, and model-provider monitoring outside the app.