User Journey: Know what I may do
Table of Contents
This page documents a user journey: A member sees the roles they hold and the permissions those roles carry.
A user journey describes what one person is trying to do, before anything is built. It is a design document that outlives any sprint, so it names the screens, the entity fields each screen shows, and the operations and messages each step needs.
1. Goal
"I want to see what I am allowed to do, and where it comes from." The member reads the roles on their account and the permissions those roles carry. The journey is done when the member can name every role they hold, and answer "may I do this?" for any action the system offers.
2. Actor and trigger
The member: an account of type user, signed in, reading their own record. The
trigger is a refusal — a screen answers "permission denied" — or curiosity from
the account menu. It starts when the member opens My access, and ends when
they close it. Nothing is written, so the journey keeps no server-side state.
This is the read half of the access topic. An administrator changes the same records for somebody else — see Change someone's access.
3. Steps
- Open my access. The member chooses My access. The system reads the roles assigned to the caller's account and lists them with their descriptions.
- Read the roles. Each row shows the role name and what the role is for. The member's identity in the header comes from the session established at sign-in, not from a second read.
- Read the permissions. The system reads the effective permissions of the
account and lists the codes. Each code follows
component::resource:action, so the member reads the component and the action from the code alone. - Follow a permission back. The member picks a permission and asks which role grants it. The system reads the permissions of the held roles and answers.
- Leave. The member closes the screen. No change has been made.
4. Screens and wireframes
One screen, read-only. Three panels: the caller's identity, the roles they hold, and the permissions those roles carry. The member thinks of the three as one answer to one question, so they are panels of one screen rather than separate screens.
Figure 1: My access: who I am, the roles I hold, and the permissions they carry.
5. Entities composed
| Entity | What it contributes | Model |
|---|---|---|
account |
The signed-in identity in the header: username and full name | ores.iam.account |
role |
The roles the account holds: name and description | ores.iam.role |
permission |
The atomic codes the roles bundle: code and description | ores.iam.permission |
account_role |
The junction row that links the account to each role | no entity model — junction table |
role_permission |
The junction row that links each role to its permissions | no entity model — junction table |
The two junctions have no entity model of their own: they are many-to-many
links, and the joined shape is a query result rather than an entity. There is
also no module entity and no module table. The component segment of the code —
iam in iam::accounts:read — is what plays the part a module would play.
No credential field appears on this screen. password_hash, password_salt,
service_password_hash, totp_secret and cleartext passwords stay on the
server, and no read in this journey returns them.
6. Operations and messages
| Step | Operation | Subject | Status |
|---|---|---|---|
| Open my access | Read the roles I hold, with the permissions each grants and its assignment record | iam.v1.ops.get_my_roles |
exists |
| Follow a permission back | Read the permissions one role bundles | iam.v1.ops.get_role_permissions |
exists |
| Another account's access, which this journey does not ask for | Read the same shape for an account the caller names | iam.v1.ops.get_account_roles |
exists |
The reads are defined in
ores.iam.authorization_messages, and
Authorised reads states the rule
they follow. iam.v1.ops.get_my_roles takes no account id, so it cannot name anybody
else: the account is the authenticated caller's, and the read needs no
permission beyond a session. The privileged read still takes an id and now
requires iam::roles:read before it looks the account up.
7. What is missing
The screen runs in ores.web as My access: the roles held with who gave
each one and why, a Can I…? search that names the role behind a yes, and
the permissions by area. A role that grants everything says so instead of
listing every code (Implement the access journeys in ores.web).
Nothing. All three gaps this journey recorded have closed, and the build that closed them is recorded on Implement the access journeys in ores.web.
iam.v1.ops.get_my_roles answers one composed shape: each role the caller holds, the
permission codes that role grants, and the account_role junction's own record
of who granted it, when and why. So the three gaps close together rather than in
turn. The read attributes a permission to the role it arrives through, which the
flat list could not; it carries the assignment tail, which no subject returned;
and it is scoped to the caller by construction rather than by a comparison that
has to be right.
A refusal is worth stating separately, because it is what the composed read
needed before it could be honest. iam.v1.ops.get_role_permissions-by-account
answered a flat list and nothing else, so an empty list meant both "you may
read nothing" and "this account holds nothing". The read that replaced it
carries a result, and a caller who may not have what it asked for is told
denied with the permission that was required. An account that holds no roles
answers ok with no rows, which is a different answer.
8. Related journeys
- Shape the role catalogue — see the permissions a role you hold actually bundles
- Change someone's access — the administrator's side of the same question, where roles are granted and revoked
- Choose where I work — permissions are exercised in a party, and the session picks one
- Ask for more access — when the roles I hold are not enough, and somebody else has to answer
9. Related knowledge
- Identity and Access Management
- Role-Based Access Control
- Accounts and Roles — the user guide chapter
- How do I add a PlantUML diagram?
- Access journeys — the group hub