Formance uses a policy-based access control system. Policies are named groups of scopes; you assign one policy to a user at the organisation level, and optionally a different one for each stack. The user's effective permissions are the union of the scopes attached to those policies.
Concepts#
Scopes#
Scopes are permission labels in <resource>:<Action> form (e.g. organization:ReadStack, stack:Write). Each scope corresponds to a single API operation or a single class of operations at the data plane. Scopes are static — they're defined in the Membership service itself, not created at runtime.
Two scopes are federated to the data plane (gateway → ledger, payments, etc.):
stack:Read— read-only access to every stack service.stack:Write— write access to every stack service.
A user holding stack:Write on a given stack can call any write endpoint on the modules running in that stack. Finer-grained per-service scoping is not currently exposed at the policy level.
Policies#
A policy is a named collection of scopes stored in Membership. Policies have an integer ID, a name, and a protected flag. Protected policies are seeded by the Membership service and cannot be deleted or modified.
Assignment#
Each user is bound to:
- one policy at the organisation level — controls what they can do across the whole org (manage users, regions, stack inventory, etc.);
- optionally, one policy per stack — controls what they can do on that specific stack and the data-plane services running in it.
If no stack-level policy is set, the org-level policy's scopes apply.
Built-in policies#
The Membership service ships with eight protected policies that cover the common shapes. You can reference these by ID when assigning users.
| ID | Name | Intent |
|---|---|---|
| 1 | StackGuest | Read a single stack and its modules; stack:Read on data plane. |
| 2 | StackAdmin | Full control of a single stack — CRUD, enable/disable/upgrade, user access, modules; stack:Read + stack:Write on data plane. |
| 4 | OrganizationGuest | Read everything at the organisation level (orgs, users, policies, regions, stacks); stack:Read on data plane. |
| 5 | OrganizationGuestStackGuest | Combined: read at the org level plus read on every stack in the org. |
| 6 | OrganizationGuestStackAdmin | Read at the org level plus full admin on every stack in the org. |
| 8 | OrganizationAdmin | Full control at the organisation level — orgs, users, invitations, policies, regions, stacks, clients, auth providers; stack:Read + stack:Write on data plane. |
| 9 | OrganizationAdminStackGuest | Combined: full org admin plus read on every stack. |
| 10 | OrganizationAdminStackAdmin | Combined: full org admin plus full admin on every stack. Closest to the legacy 'ADMIN/ADMIN' grant. |
You can also create custom policies if these don't fit — see "Manage policies" below.
Scope reference#
Every scope available in Membership:
| Scope | Category | Description |
|---|---|---|
| stack:Read | Stack (federated) | Read-only access to stack services (ledger, payments, etc.) |
| stack:Write | Stack (federated) | Write access to stack services |
| organization:Read | Organisation | Read organisation details |
| organization:Create | Organisation | Create organisation |
| organization:Update | Organisation | Update organisation details |
| organization:Delete | Organisation | Delete organisation |
| organization:ListUsers | Users | List organisation users |
| organization:ReadUser | Users | Read user details |
| organization:CreateUser | Users | Create or invite users to organisation |
| organization:UpdateUser | Users | Update user details |
| organization:DeleteUser | Users | Remove users from organisation |
| organization:ListPolicies | Policies | List organisation policies |
| organization:ReadPolicy | Policies | Read policy details |
| organization:CreatePolicy | Policies | Create policies |
| organization:UpdatePolicy | Policies | Update policies and manage their scopes |
| organization:DeletePolicy | Policies | Delete policies |
| organization:ListInvitations | Invitations | List organisation invitations |
| organization:ReadInvitation | Invitations | Read invitation details |
| organization:CreateInvitation | Invitations | Create invitations |
| organization:UpdateInvitation | Invitations | Update invitations |
| organization:AcceptInvitation | Invitations | Accept invitations |
| organization:RejectInvitation | Invitations | Reject invitations |
| organization:DeleteInvitation | Invitations | Delete invitations |
| organization:ListRegions | Regions | List organisation regions |
| organization:ReadRegion | Regions | Read region details |
| organization:CreateRegion | Regions | Create regions |
| organization:UpdateRegion | Regions | Update regions |
| organization:DeleteRegion | Regions | Delete regions |
| organization:ListStacks | Stacks (control) | List organisation stacks |
| organization:ReadStack | Stacks (control) | Read stack details |
| organization:CreateStack | Stacks (control) | Create stacks |
| organization:UpdateStack | Stacks (control) | Update stacks |
| organization:DeleteStack | Stacks (control) | Delete stacks |
| organization:EnableStack | Stacks (control) | Enable stacks |
| organization:DisableStack | Stacks (control) | Disable stacks |
| organization:RestoreStack | Stacks (control) | Restore stacks |
| organization:UpgradeStack | Stacks (control) | Upgrade stacks |
| organization:ListStackUsers | Stack users | List stack users |
| organization:ReadStackUser | Stack users | Read stack user details |
| organization:CreateStackUser | Stack users | Add users to stack |
| organization:UpdateStackUser | Stack users | Update stack user access |
| organization:DeleteStackUser | Stack users | Remove users from stack |
| organization:ListStackModules | Stack modules | List stack modules |
| organization:EnableStackModule | Stack modules | Enable stack modules |
| organization:DisableStackModule | Stack modules | Disable stack modules |
| organization:ListClients | OAuth clients | List organisation clients |
| organization:ReadClient | OAuth clients | Read client details |
| organization:CreateClient | OAuth clients | Create clients |
| organization:UpdateClient | OAuth clients | Update clients |
| organization:DeleteClient | OAuth clients | Delete clients |
| organization:ReadAuthProvider | Auth provider | Read authentication provider configuration |
| organization:UpdateAuthProvider | Auth provider | Update authentication provider configuration |
| organization:DeleteAuthProvider | Auth provider | Delete authentication provider configuration |
| organization:ReadLogs | Logs | Read organisation logs |
| organization:ListFeatures | Features | List organisation features |
| organization:ReadFeature | Features | Read feature details |
Inspect with fctl#
Once you've logged in with fctl cloud login, you can list and inspect policies from the command line:
# List policies in your organisation
fctl cloud organizations policies list
# Show a specific policy's scopes
fctl cloud organizations policies show <policy-id>
# Create a custom policy
fctl cloud organizations policies create "<name>"
# Add or remove scopes
fctl cloud organizations policies add-scope <policy-id> <scope-id>
fctl cloud organizations policies remove-scope <policy-id> <scope-id>
# Update / delete (protected policies cannot be deleted)
fctl cloud organizations policies update <policy-id>
fctl cloud organizations policies delete <policy-id>Manage policies via the API#
List policies#
curl -X GET $FORMANCE_API_URL/api/membership/organizations/<ORG_ID>/policiesCreate a policy#
curl -X POST $FORMANCE_API_URL/api/membership/organizations/<ORG_ID>/policies \
-H "Content-Type: application/json" \
-d '{
"name": "Developer",
"description": "Read-only access to ledger and payments"
}'Add scopes to a policy#
curl -X PUT $FORMANCE_API_URL/api/membership/organizations/<ORG_ID>/policies/<POLICY_ID>/scopes/<SCOPE_ID>Remove a scope from a policy#
curl -X DELETE $FORMANCE_API_URL/api/membership/organizations/<ORG_ID>/policies/<POLICY_ID>/scopes/<SCOPE_ID>Delete a policy#
curl -X DELETE $FORMANCE_API_URL/api/membership/organizations/<ORG_ID>/policies/<POLICY_ID>The eight built-in policies are protected and cannot be deleted. The API returns a 400 if you try.
Manage user access#
Organisation level#
Assign a policy to a user at the organisation level:
curl -X PUT $FORMANCE_API_URL/api/membership/organizations/<ORG_ID>/users/<USER_ID>List users in an organisation:
curl -X GET $FORMANCE_API_URL/api/membership/organizations/<ORG_ID>/usersRemove a user from an organisation:
curl -X DELETE $FORMANCE_API_URL/api/membership/organizations/<ORG_ID>/users/<USER_ID>Stack level#
Grant a user access to a specific stack with a per-stack policy:
curl -X PUT $FORMANCE_API_URL/api/membership/organizations/<ORG_ID>/stacks/<STACK_ID>/users/<USER_ID>View a user's stack access:
curl -X GET $FORMANCE_API_URL/api/membership/organizations/<ORG_ID>/stacks/<STACK_ID>/users/<USER_ID>Revoke stack access:
curl -X DELETE $FORMANCE_API_URL/api/membership/organizations/<ORG_ID>/stacks/<STACK_ID>/users/<USER_ID>