Access management
Access management answers one question: who gets into a project. What they may then change once inside is a separate decision, made by namespace permissions .
Keeping the two apart is deliberate. Admission is an account concern — orgs, invitations, tokens. Mutation is a data concern — which namespaces a principal may write to. A project ADMIN is not automatically allowed to overwrite your production features.
Guest, project, org
Run FeatureQL from a notebook with no access token and you are a guest: queries compile and execute, but nothing persists and no persisted feature is readable.
To persist features you need a project. Features belong to exactly one project and never cross into another. To work with other people, put that project in an org and invite them.
The pieces
- A user gets a personal org automatically on signup, named after their user id.
- An org holds many projects and many members, each
OWNERorADMIN. - A project belongs to exactly one org and has its own members:
OWNER,ADMIN,READ_WRITE, orREAD_ONLY. - A user can hold roles in several orgs and several projects at once.
- An org always keeps at least one
OWNER. So does a project.
Personal orgs are single-player
A personal org is your permanent workspace: it cannot be deleted, and it cannot be shared. No extra members, no invitations, no shared projects. The moment you need a second person, create a regular org — the full permission model only applies there.
Project references
A project is identified by org_name/project_name, and that pair is unique. In a personal org the reference is user_id/project_name.
Project names are unique per org, not globally: acme/data and corp/data can both exist.
Roles admit, they don't grant writes
Roles control admission and the administrative APIs — creating projects, inviting people, reading audit logs. They do not hand out mutation rights on features. Once a principal is in the project, namespace policy independently decides WRITE_FEATURE, DELETE_FEATURE, and delegated MANAGE_PERMISSIONS.
Org roles
OWNER— create and delete projects, manage every org member, transfer ownership, delete the org.ADMIN— create projects, invite users to the org, manage project access.
Project roles
OWNER— every project operation: manage all members, transfer ownership, move the project to another org, delete it.ADMIN— invite and manageREAD_WRITE/READ_ONLYmembers, and repair namespace policy.READ_WRITEandREAD_ONLY— membership tiers. Reads are unrestricted inside the project; anything that mutates a feature comes from namespace policy, not from the role name.
OWNER and ADMIN may administer namespace policy project-wide, but they receive no implicit WRITE_FEATURE or DELETE_FEATURE. If they need it, they grant it to themselves explicitly — which leaves a trace.
| Org action | OWNER | ADMIN | Non-member |
|---|---|---|---|
| Create projects | ✅ | ✅ | ❌ |
| Invite users to org | ✅ | ✅ | ❌ |
| Modify any member's role | ✅ | ❌ | ❌ |
| List org members | ✅ | ✅ | ❌ |
| Delete org | ✅ | ❌ | ❌ |
| Cancel own invitations | ✅ | ✅ | ❌ |
| Cancel any invitation | ✅ | ❌ | ❌ |
| View audit logs | ✅ | ✅ | ❌ |
| Project action | OWNER | ADMIN | READ_WRITE | READ_ONLY |
|---|---|---|---|---|
| Read features | ✅ | ✅ | ✅ | ✅ |
| Write or delete features | Namespace policy | Namespace policy | Namespace policy | Namespace policy |
| Administer namespace policy | ✅ | ✅ | Delegated policy only | Delegated policy only |
| Invite users | ✅ | READ_WRITE / READ_ONLY only | ❌ | ❌ |
| Modify OWNER / ADMIN roles | ✅ | ❌ | ❌ | ❌ |
| Modify READ_WRITE / READ_ONLY roles | ✅ | ✅ | ❌ | ❌ |
| List project members | ✅ | ✅ | ❌ | ❌ |
| Transfer project | ✅ | ❌ | ❌ | ❌ |
| Delete project | ✅ | ❌ | ❌ | ❌ |
| View audit logs | ✅ | ✅ | ❌ | ❌ |
When several OWNERs exist, any of them can change or remove the others. The only guardrail is that the last one cannot be removed.
Two tokens, two jobs
| Token | Where it comes from | What it is for |
|---|---|---|
| Identity token | Console login | Managing orgs, projects, invitations, and roles |
| Project access token | generate_access_token(identity_token, project_reference) | Running FeatureQL against one project |
Both are JWTs, and only the user id inside them is used for access control. They expire one week after issue. client.invalidate_token() kills them sooner by recording an invalidation timestamp — everything older than it dies immediately, while tokens minted afterwards stay valid, so you can rotate without locking yourself out.
Service accounts are API-only identities scoped to one project, with longer-lived (28-day) tokens. They live in the Python guide .
Getting started
Sign in at console.featuremesh.com with GitHub, Google, or email. Your personal org appears automatically, and from there you can create projects and manage people in the UI.
If you would rather do all of it from a notebook, everything in the console is also available through AccessClient:
from featuremesh import AccessClient
client = AccessClient(identity_token="your_identity_token")
client.create_project(project_name="my_project") Next
- Managing access from Python — the full
AccessClientwalkthrough: orgs, invitations, roles, transfers, service accounts, audit logs - Namespace permissions — who may write or delete features once they are in
- Feature lifecycle — how much a feature can be trusted