Skip to main content
An organization is the top-level resource owner in abadge. Every profile, item, agent, permission, and audit entry is scoped to an organization. A personal workspace is just an organization with one member.

Schema

A personal account is a normal single-member org flagged via metadata. It is capped at a single profile (profiles.create rejects a second profile with PROFILE_LIMIT_EXCEEDED; the cap is an ≤ 1 existence check). Team orgs are uncapped. Creating any org auto-seeds one default server_managed profile (name and externalId both "default") in the same transaction, so a fresh org is immediately usable. A personal account is not in custody mode — its owner can reveal their own item values (items.ownerReveal for server-managed, in-browser decrypt for ZK); team orgs stay in custody mode and the dashboard never reveals plaintext there.

Membership

Users join organizations through the member table. Roles are:
Member emails are visible to owner and admin roles only. member-role callers see null for email — including their own row. Users should read their own email from their session.

Invitations

Invitations are one-time tokens (abi_...) shown once and stored as SHA-256 hashes. They expire after 7 days. The flow:
1

Admin creates invite

organizations.members.invite returns a token. The frontend builds the URL: {APP_URL}/invite/accept?token={token}.
2

Recipient looks up the invite

organizations.members.getInviteInfo reveals the org name, role, and expiry. Authentication is required to prevent enumeration.
3

Recipient accepts

organizations.members.acceptInvite adds them to the organization with the invite’s role. The token is consumed atomically.

Cascades

Deleting an organization cascades to its agents, permissions, profiles, and items. The audit log retains entries (no FK constraints). Removing a member cascades agent revocation for agents owned by that member.

In the dashboard

Switch the active organization using the org switcher in the dashboard header. Operations on profiles, items, agents, and permissions act on the active organization. In the CLI, set the active organization with:
The apiUrl and activeOrgId are persisted in ~/.abadge/config.json.