How permissions work
What this screen is for
This page is not a screen — it is the model behind the four People & Access tabs. Read it once and the rest of Settings stops being surprising.
Fenwave uses role-based access control. Access travels along one chain, and every tab in People & Access is one link in it:
permission → policy → role → user
Before you start
Nothing to configure. To apply the model you need the permissions listed on People & Access.
Opening it
There is nothing to open. The concepts here appear in Policies, Roles, Users and Access Explorer.
The interface
The four links in the chain
| Link | What it is | Where you manage it |
|---|---|---|
| Permission | One atomic action, e.g. platform-settings.user.create |
Not managed directly — selected inside a policy |
| Policy | A set of permissions, optionally scoped to clusters and environments | Policies |
| Role | A set of policies. Admin, Developer, DevOps ship by default |
Roles |
| User | Holds one or more roles | Users |
You never grant a permission to a person. If someone needs access, the question is always which role, and then which policy in it.
Permission naming
<plugin>.<resource>.<action> — for example platform-settings.cluster.validate.
Actions are usually read, create, update, delete, plus verbs specific to
the resource: validate on credentials, export and import on configuration,
assign-group on users, assign-owner and manage-components on projects,
view-details on groups and projects.
Copy permission strings exactly. Access Explorer matches them literally.
Permission types and profiles
Permissions carry a type:
- default — available to both profiles.
- devops — usable only by a DevOps profile.
Every user has a profile, Dev or DevOps, set explicitly on their record.
It is not derived from the permissions they hold. The profile does two things:
- It filters roles. A Dev-profile user cannot be given a role marked DevOps; the role is shown as “requires DevOps profile”.
- It selects the licence seat pool. Dev and DevOps seats are counted separately, and a user with no profile set counts as dev.
Scoping
Scoping lives on the policy statement, nowhere else. A statement can restrict its permissions to:
- Clusters — chosen as resources.
- Environments —
dev,staging,production, as a condition; one or several.
A statement with neither applies everywhere. This is the single most common misconfiguration in Fenwave, and it is silent: a too-broad policy looks identical to a correct one in the list.
Environment-scoped permission names
env-by-branch.* permissions come in two shapes, and the backend expands
between them. A flat name such as env-by-branch.devops-config.read is checked
as env-by-branch.dev.devops-config.read, then staging, then production, then
the flat name itself. Holding any one environment variant satisfies a
flat-named route for that environment.
env-by-branch.platform-service.* is deliberately env-agnostic and never
expanded.
Walkthroughs
Work out why someone cannot do something
- Open Access Explorer.
- Look up the user and the exact permission string.
- Read the result along the chain:
- Denied, and no role grants it → assign a role that carries a policy with it.
- Allowed here but failing in the product → check scoping: the policy may not cover that cluster or environment.
- Allowed and they still cannot see the menu → session cache; reload.
Grant access without over-granting
- Start from the narrowest policy that does the job.
- Scope the statement to the specific clusters and environments.
- Attach it to a role dedicated to that job.
- Verify in Access Explorer before telling the user it is done.
Scenario
“Marc can deploy to production and nobody knows why.”
Marc is a developer who should only reach dev.
- Access Explorer for
marcand the production deployment permission → allowed. So it is granted, not a bug. - Look at Marc’s roles. He holds
Backend DeveloperandOn-Call. - Open the policies under each.
Backend Developeris correctly scoped to dev.On-Callhas a statement with no environment condition. - That unscoped statement is the cause. Permissions are additive — the union of every role is what applies, so a correctly scoped role cannot take away what another role grants.
- Fix the
On-Callpolicy by adding the production environment condition and the cluster resource, rather than removing Marc from the role. - Re-check in Access Explorer.
The lesson generalises: when access is too broad, audit every role the user holds. Narrowing the one you expected to be responsible achieves nothing on its own.
When it doesn’t work
| Symptom | Cause | How to check | Fix |
|---|---|---|---|
| Permission granted, user sees no change | Permission results are cached per session | — | Ask them to reload |
| Access is broader than the role suggests | Another role grants the same permission | Access Explorer, then audit every role | Scope or remove the offending policy |
| Role cannot be assigned to a user | The role is DevOps and the user’s profile is Dev | The dialog labels it “requires DevOps profile” | Change the profile, or use a Dev-compatible role |
| Licence seat count looks wrong | Users with an unset profile count as dev | The active-user report in General | Set an explicit profile on every user |
| A cluster or environment cannot be scoped | It is not registered | Infrastructure | Register it first |
admin role behaves unlike other roles |
It bypasses policies entirely — full access, including resources added later | The notice in the role editor | Use a scoped role instead |
Next
- Policies — where scoping is applied
- Access Explorer — the tool that answers “why not?”