Case study 062022
Authorization & SSO Platform
One permissions service and enterprise SSO for a SaaS product whose access rules lived in 14 codebases.
- Role
- Tech lead
- Team
- 4 engineers
- Timeline
- 7 months
- Focus
- Backend, Platform
14
services on one permission model
5 ms
p99 permission check
0
access-control exceptions in SOC 2
The problem
Permission checks were copied across 14 services and quietly disagreed, which had already caused one data-exposure incident. Enterprise deals required SAML single sign-on, SCIM provisioning and custom roles, and a SOC 2 audit was six months away.
What I owned
- The permissions model: roles, teams and resource sharing stored as relationships.
- The Go authorization service and its client libraries for TypeScript and Ruby.
- SAML and OIDC single sign-on, and SCIM provisioning for Okta and Entra ID.
- The service-by-service migration, with old and new checks compared in production before each switch.
Key decisions
- 1
Relationships, not role flags
Access is modelled as relationships between users, teams and resources, in the style of Google's Zanzibar. Custom roles and sharing became data instead of code.
- 2
Compare before you enforce
Each service ran old and new checks side by side and logged every disagreement. A service switched over only after a full week with none.
- 3
Fast enough to call everywhere
A revision-aware cache keeps checks at 5 ms p99, so teams had no reason to cache permissions themselves and drift apart again.
Outcome
Permissions are defined once and audited in one place. SSO and SCIM became standard on the enterprise plan, and the SOC 2 Type II report had no access-control exceptions.
- Go
- PostgreSQL
- Redis
- TypeScript
- SAML / OIDC
- SCIM