The flat model couldn't represent an organisation or scale to thousands of users. The nested hierarchy mirrors the org chart and lets a role set once at a parent cascade to every team beneath it.
Cycloid's permission model used a flat team structure with manually assigned roles. The EU contract — thousands of users — broke it on two fronts.
Manual setup and maintenance at that scale was operationally unworkable, and the flat structure simply couldn't represent the organisational hierarchy the EU needed to maintain access control.
I ran competitor analysis to understand existing patterns. GitLab and GitHub were the primary references — both with well-documented group/subgroup inheritance — alongside a direct competitor. The research validated a nested team hierarchy with role-based inherited permissions as the right direction.
DevOps Admin
Sets up and configures Cycloid; full access; owns the permission model itself.
Developer
Occasional user; mostly consumes pipelines set up by DevOps and checks notifications.
Manager / Admin
Needs summary and reporting information; doesn't touch the technical setup.
With no defined limit from the Product Owner, I made reasonable assumptions to keep moving — and flagged them explicitly.
how deep before a tree is unusable?
does origin (direct vs. inherited) live on this tab, or on Ownership?
reuse Surface 01's team/count data, or rebuild it here?
Sketched as three linked boxes rather than one screen at a time — checking the same team names and counts held together across teams, profile and project before any of it got real pixels. The open questions above became the assumptions flagged below.
~15–20 members per team, up to 4 levels deep.
Permissions apply at project level — unblocking user-facing design from complex entity logic.
A collapsible tree; each node counts members across itself and all child teams.
Which teams a user belongs to, which permissions they hold and where they originate (inherited vs. direct), and their projects.
Which teams are assigned to a project, and the membership of those teams.
Same model, reused
The project's Teams tab pulls the same team and membership data as the org-level tree and the user profile — one model surfaced three ways, not three separate builds.
The three surfaces resolved cleanly and held together as one connected model — the tree, the profile and the project view all reflecting the same team data. Entity-level permissions — how components and environments behave under the model — hit ambiguity at the product-definition level along the way, and the design surfaced that complexity early rather than absorbing it silently.
The designs weren't ultimately shipped. That doesn't change what the process demonstrated: a complex enterprise problem scoped into deliverable surfaces, with assumptions flagged rather than guessed at.
demonstrates
Autonomous decision-making under ambiguity, with assumptions flagged to stakeholders.
Scoping a complex enterprise problem into deliverable surfaces.
Systems thinking across connected views — teams, users, projects.
Pragmatic unblocking without waiting for perfect information.