Brod

Security model

Brod security architecture

Brod runs apps that people in your organisation, or their agents, wrote. It decides who may open each app, signs people in once for all of them, and keeps one app's data apart from another's. This page explains how, and is plain about the limits.

This is a summary for people choosing where to run AI-built internal apps. The full model, written for engineers, is docs/security.md in the open-source repository, and the code is there to check it against.

Access is decided before the app runs

Every request to an app goes through Brod's gateway first. The gateway works out who the visitor is, checks the app's access mode and grants, and only then forwards the request. An app with a bug in its own permission logic, or no permission logic at all, is still behind that check.

A browser request passes Brod's gateway, which checks sign-in and access, before reaching the app's code, which reads its own database, files and secrets. Browser Brod gatewaywho is this? may they open it? App codeown database, files, secrets Refused requests never reach the app and are logged.

Each app has one of six access modes:

ModeWho can open the app
privateThe app's owner and workspace admins. The default for a new app.
peopleOnly the people, groups and email domains granted a role in the app.
workspaceEveryone in the workspace (guests only if granted).
passwordAnyone with the address and the app's password, without an account.
signed_inAnyone signed in to Brod, in any workspace. On brod.sh, that means anyone with a brod.sh account.
publicAnyone, without signing in.

Safe defaults

  • Private by default. A new app opens only for its owner and workspace admins.
  • People confirm widening access. When an agent asks to share an app more widely, invite someone, or delete an app, Brod returns a confirmation link and nothing changes until a person opens it and confirms. Narrowing access applies at once.
  • Staging first. An update to a live app goes to the app's staging address unless the deploy says otherwise, and becomes live when someone publishes it.
  • One place to remove someone. Removing a person from the workspace ends their access to every app on their next request.
  • Everything is recorded. Deploys, access changes and refused requests are in each app's activity log.

Sign-in and identity

People sign in once per workspace, with an emailed link or Google. Apps never see a password and never handle the sign-in flow. When a signed-in person opens an app, the app gets its own session for its own host, so one app cannot read another's session.

The gateway removes any identity headers a visitor sends and adds its own, signed by Brod, before forwarding the request. App code reads the visitor's email, name, role and groups from /_brod/me in the browser, or from those headers on the server, and can trust them.

On HTTPS, every Brod cookie is __Host--prefixed, Secure, HttpOnly and SameSite=Lax.

Secrets and stored credentials

WhatHow it is kept
App secrets (API keys and the like)AES-256-GCM under a key derived with HKDF and bound to the app. Write-only through the API: an agent can set a secret, but never read one back.
Agent tokens, OAuth tokens, sessions, sign-in linksOnly a SHA-256 hash of a 24-byte random value is stored.
App passwordsArgon2id with a per-password salt.

Because the app reads secrets as env.NAME at runtime, the key does not need to be in the code the agent writes, in the repository, or in the browser.

Isolation between apps

  • Separate hosts

    Apps are served from *.brod.sh app hosts, a different domain from the platform's own pages, so an app cannot read the platform's cookies.

  • Separate data

    Each app with server code has its own SQLite database, key-value store and file storage. An app has no way to address another app's data.

  • Separate isolates

    Server code runs in workerd, each app in its own V8 isolate.

  • Declared outbound hosts

    Apps list the outside hosts their server code calls in brod.json. The operator can log or refuse calls to anything else.

  • Upload checks

    Bundles are checked for size, file count and path traversal, and files are served with a type from their extension and X-Content-Type-Options: nosniff.

  • Rate limits

    Sign-in links, deploys, API and MCP calls and app passwords are rate limited per person, address or app.

What an agent can and cannot do

An agent with a Brod token can

  • Deploy new apps and new versions, to staging by default
  • Read an app's files, status and logs
  • Set and remove secrets (not read them)
  • Publish staging, roll back, narrow access, pause an app

Waits for a person

  • Opening an app to more people
  • Inviting someone to the workspace
  • Deleting an app

Tokens are made by a person on the workspace's connections page, can be given an expiry, and can be revoked at any time. Agents can also connect with OAuth 2.1, where the person picks the workspace in the browser.

What Brod does not protect against

Brod assumes the people who deploy apps are trusted members of the team. It is not a sandbox for hostile code. Specifically:

  • Hostile server code. Isolates separate memory, not CPU. A busy loop in one app can slow other apps on the same server until Brod's watchdog stops it.
  • Apps attacking each other's users. All apps share the brod.sh site for browser purposes, so SameSite=Lax does not stop a page in one app posting a form to another. Apps that change data on POST should check the Origin header.
  • Framing. App pages carry no frame-ancestors policy by default. Apps that need clickjacking protection should send their own.
  • Staging data. An app's staging version uses the same database, files and secrets as the live version. Changes you test on staging are real.
  • Bugs in the app. Brod controls who reaches the app. What a person allowed in can do inside it, such as which records they can edit, is the app's own logic, using the role Brod gives it.

Brod does not yet offer company sign-in (SAML or OIDC), SCIM, or blocking paths by role. Those are on the roadmap, not in the product.

Open source and reporting

Brod is open source under AGPL-3.0, so the gateway, runtime and storage code can be read and audited. Vulnerabilities can be reported privately through GitHub as described in SECURITY.md.

Questions

Can an AI agent make an app public without anyone noticing?

No. Widening an app's access returns a confirmation link, and nothing changes until a person opens it and confirms. The change is recorded in the app's log.

Can an agent read the secrets it stored?

No. Secrets are write-only through the API and MCP tools. Only the app's server code can read them, as environment values.

Does Brod support SSO with Okta or Azure AD?

Not yet. People sign in with an emailed link or Google. Company sign-in with SAML or OIDC is on the roadmap.

Is my app's data shared with other customers' apps?

No. Each app has its own database and file storage, and its server code runs in its own isolate. Apps cannot address each other's data.

Your AI already built the app. Put it in your team's hands.