AboutColophon
  • About
  • Colophon
Say Hi
Get in touchsabrinasettle.for.more@gmail.com

Sabrina Settle — 2026

Loading...

Designing KeelHub's First Access Control System for 400 Users

Summary

KeelHub was KeelWorks' internal platform for managing employees and volunteers across 15 projects. It had two roles at signup: basic user and admin. Users chose their own. Anyone could select admin and walk into a directory containing home addresses, visa status, country of birth, and personal contact information for every person in the system. I caught it, escalated it, and led the design of the org's first RBAC system from zero.

  • Open security vulnerability closed: self-selected admin access to sensitive employee data removed before the product reached a single real user
  • First documented access control system: replacing fragmented spreadsheets and manual HR coordination with a designed, stakeholder-approved architecture
  • Named-role architecture: supporting multiple simultaneous roles per user, granular permission toggles, and role assignment at the point of invitation

Problems

The original login flow gave users direct control over their own access level with no enforcement, no identity check, and no backend validation. Below that, the underlying model was too simple to represent the actual org.

  • 01

    The original system put two roles in front of users at signup and asked them to pick one. There was no invite gate. No identity check. No backend enforcement. A volunteer could select admin, complete signup, and access private records for every employee and volunteer in the organization. Home addresses, visa status, country of birth, personal contact details — all of it, immediately available.

  • 02

    This wasn't a known risk that had been deprioritized. The product was moving fast and access control hadn't been thought through yet.

  • 03

    Beyond the signup flaw, the underlying model was too blunt for an org of this complexity. A two-tier system can't represent a program manager who also does data analysis, or a volunteer with narrowly scoped responsibilities, or a foundation director who needs visibility without editing authority. Everyone got forced into a category that didn't quite fit. As KeelHub scaled, that mismatch would compound.

Access changes were also handled manually. Permission requests went through HR via email. There was no audit trail, no single source of truth, and no way to see who had access to what without asking someone directly.

Discovery & Approach

I started by working on the login flow. Once I understood what self-selected roles actually meant in terms of data exposure, I flagged it. The flag didn't move on its own. The product manager had 300 pages of documentation and revisiting the access model meant revisiting those docs. I brought it to an all-hands meeting and walked through the vulnerability directly. Showing the path was more effective than describing it. RBAC went on the roadmap.

When the project started, my early framing of the system used a tiered model: Level 1, Level 2, Level 3, each adding permissions incrementally. That framing stuck. It made it into the product documentation and the first round of designs, where numbered level badges appeared in the UI. The problem was that tiers can't model real jobs. Assigning someone Level 3 to cover both their product and data responsibilities means over-provisioning everyone else at that level. Assigning Level 1 means blocking them from things they genuinely need. The model looked clean and it was wrong. I pushed for named roles with granular, toggleable permissions grouped by entity. The argument was simple: RBAC is complex by nature. Building a simplified version first doesn't reduce that complexity, it defers it. When you need to fix it later, you're touching permissions, roles, user assignments, and engineering logic all at once. Better to build it correctly once.

Solution

The core decision was to replace access levels with named roles that could be composed of specific permissions, and to allow users to hold more than one role simultaneously.

The admin view is a table of all users, paginated for scale, filterable by status, access level, and role. Each row shows invitation status, job title, assigned access role, and a 1+ badge where multiple roles apply. That badge makes cross-functional assignments visible at a glance without requiring the admin to open each profile.

Clicking into a user opens a profile with two views. Admins and HR see the full record, including sensitive fields. Everyone else sees a limited view. The original vulnerability was anyone seeing everything. The fix was a structural separation built into the profile itself.

The permissions page for each role uses toggles grouped by entity: Users and Access. The HR role has Invite New Users, Edit Users, Approve Onboarding, Assign to Projects, and Deactivate Users turned on. Create Role, Edit Roles, and Delete Role are off. An HR admin can manage people. They cannot restructure the permission system itself. The UI makes that distinction legible without instruction.

The invite flow assigns both a job title and an access role at the point of invitation, before the account exists. This removes the gap where access might be incorrectly set or forgotten during onboarding.

Impacts

  • Open Security Vulnerability Closed

    Before this work, any user could sign up, select admin, and access employee home addresses, visa status, country of birth, and personal contact information. The path existed and had no gate. The RBAC system replaced self-selected roles with admin-assigned access, removed sensitive fields from non-privileged profile views, and introduced a permission structure that controlled what each role could see and do — before a single real user touched the product.

  • First Documented Access Control System

    KeelHub had no formal access control before this project. Permissions lived across spreadsheets managed by HR. Access changes went through email. There was no audit trail and no single source of truth. This project produced the org's first designed, documented, and stakeholder-approved system for managing access across 400 employees and volunteers and 15 projects. It reached C-suite sign-off from the CEO, CTO, and COO, and 60% engineering implementation before the org was shut down due to funding changes.

  • Named-Role Architecture

    The tiered model would have forced every user into a numbered level regardless of their actual responsibilities. The named-role system supports multiple simultaneous roles per user, granular permission toggles grouped by entity, and role assignments at the point of invitation. The old design showed Level 1, Level 2, Level 3 with colored number badges. The new design shows HR, Product Manager, Admin, with a 1+ indicator for users holding more than one role. The UI changed because the underlying model changed.

  • Design Benchmark

    KeelHub became the most fully designed product at KeelWorks. When the org began building a company-wide design system, other teams referenced this product as the standard. That wasn't directed. It happened because the work was complete and the system thinking was visible.

Reflections

  1. 01

    I introduced RBAC to the team too casually. I used the tiered model as a simplification to explain the concept early, and that framing calcified into product documentation before I understood its limits. On a small team without other systems thinkers, early explanations carry more weight than they feel like they do in the moment. I'd treat the first framing of a complex system as a consequential design decision, not just directional shorthand.

  2. 02

    I would have pushed for this work earlier in the roadmap. I flagged the login vulnerability and got it fixed, but the broader access model wasn't questioned until I led the effort to do so. Framing the two-tier system as design debt from the start, not just a security risk, might have opened that conversation sooner and with more shared context.