Skip to main content
Version: 2026.8.1

Accounts and access

Who can get into the instance, and what they can do once in, is controlled at three levels: whether someone can make an account at all, what role their account holds inside a workspace, and what a token or agent acting on their behalf is allowed to touch.

Getting an account​

  • Signup is a single setting, PUBLIC_SIGNUP_ENABLED, closed by default in a production build. That's the safe default for anything reachable beyond your own hands: nobody makes an account unless you let them.
  • Invites are the intended flow after first setup, not open signup. As the operator you mint a sign-up invite from the admin console. The person follows the link and registers into the workspace you pointed them at.
  • To open the door wide (a household instance where signup being on is harmless), set PUBLIC_SIGNUP_ENABLED=true and bring the stack up.

Roles inside a workspace​

Every membership in a workspace carries a role, from most to least authority: owner, admin, editor, member, guest.

  • Owners and admins run the workspace.
  • Editors work in it.
  • Members and guests start with almost nothing and see only what you grant.
  • Permissions are individual capabilities below those broad roles (adjust stock, create a part, run a specific action). You grant them to a person one at a time, or bundle them into a custom role you define and assign.
  • The operator tier sits above every workspace: the person hosting the instance, named by email in SUPERADMIN_EMAILS, who gets the cross-workspace admin console. That's a separate layer from the per-workspace roles, described in Self-hosting.
  • Hidden and refused from one source. What someone lacks the capability for is both hidden in the interface and refused by the server, and the two decisions come from the same source, so the UI never shows something the server would block. The full treatment is in People and permissions.

Sessions​

  • Lifetime: logging in creates a signed session that lasts SESSION_TTL_DAYS, 30 days by default and configurable in .env.
  • Sign everyone out at once: sessions are signed with JWT_SECRET. Rotate that secret and every session is invalidated, which is the blunt way to sign everyone out if you suspect a token leaked.
  • Sign one person out: individual sessions can be revoked without touching the secret.

API tokens for scripts and agents​

People log in. Scripts and agents use API tokens.

  • Minted from your account settings, tied to your user, and shown once at creation (only a hash is stored, so it can't be recovered later, only replaced).
  • Expiry and revocation: tokens can carry an expiry, and you can revoke one at any time.

Two properties matter for keeping a token narrow:

  • Scopes are deny-by-default. A token minted with a scope can reach only the endpoints that scope allows, and nothing else, even though it carries your identity. A token scoped to one job (say, feeding an edge bridge, or driving your open browser tab) cannot read workspace data or mint more tokens. A token minted with no scope is unrestricted, so scope the ones you hand to automation.
  • Driving is its own grant. The token scope that lets an assistant operate your open Cobblr tab (drive:control) navigates the interface and reads or writes no data on its own. It is also gated by a per-workspace toggle that is off by default. Connecting an assistant this way is covered in Connecting Claude.

A forgotten password​

Forgot password? on the login page sends a reset link to the account's email.

  • The link lives for an hour, and only the newest one issued still works.
  • Using it signs the account out everywhere else, since a reset is exactly the moment a stolen session must die.
  • The form's answer is the same whether or not the address is registered, so it cannot be used to fish for accounts.
  • That flow needs the instance to be able to send email. With no email delivery configured, the reset silently goes nowhere. That is deliberate, because the alternative is showing the reset link to whoever asked for it.

On a no-email box, recovery is the operator's job:

  1. In the admin console, reset the user's password. Cobblr mints a memorable temporary password and shows it once.
  2. Hand it to the person however you already talk to them: out loud, on paper, in chat. Nothing depends on email.
  3. They log in with it and Cobblr refuses to go anywhere until they have chosen a new password of their own. The console shows "reset pending" against the account until they have.

The same mint-a-temp-password flow is also how an operator creates an account by hand while signup is closed.

Recovering access​

Because you own the box, being locked out is always fixable with an .env edit and a restart.

  • Signup closed and no account at all: set PUBLIC_SIGNUP_ENABLED=true, run docker compose up -d, register, then close it again.
  • An account but no admin console: add that account's email to SUPERADMIN_EMAILS and bring the stack up. The operator check reads the list live, so the existing account is granted the tier retroactively.

The step-by-step version is in Operating.