Enterprise Access
The challenge
Enterprise authorization is fragmented by design — every team, every acquisition, and every partner adds another layer of complexity:
- Post-M&A identity chaos — acquired companies bring their own IdPs, their own role definitions, and their own authorization logic. Unifying access takes months or years.
- Every application is an island — each application manages its own permissions. Changing a policy means code changes across multiple teams and release cycles.
- Partners need controlled access — external contractors, vendors, and partner organizations need specific resource access without getting full internal accounts or VPN connectivity.
- The CISO can't answer "who has access to what?" — there is no single view of authorization across the organization. Audit is a spreadsheet exercise that nobody trusts.
- AI agents and automation need access — RPA bots and AI agents access internal systems with service accounts that have no standardized, auditable authorization model.
How PBAC handles it
Multi-IdP federation under one policy plane
Connect every identity provider — the parent company's Azure AD, the acquired company's Okta instance, the partner's OIDC provider — under one authorization layer. No user migration. No IdP consolidation. One set of policies governs access regardless of where the user authenticates.
Centralized policy, decentralized control
Business units define their own authorization rules through policy data. Engineering controls access to the Project API. HR controls access to HR records. PBAC enforces all of it consistently, with one audit trail.
Partner access via dynamic client registration
External partners register their applications via software statements with constrained entitlements. A third-party Project Sync tool gets project.read — not email, not HR records, not calendar. Onboarding a new partner is a registration, not a custom integration.
Unified audit trail
Every access decision across every application — internal and external — is logged with full context. When the auditor asks "who had access to the HR system last quarter," it is a single query.
Architecture
Resource types and scopes
| Resource | Type URI | Scopes |
|---|---|---|
| Calendar | urn:enterprise:calendar | read, write, share, delete |
| urn:enterprise:email | read, write, share, archive | |
| Document | urn:enterprise:document | read, write, share, print |
| Slide | urn:enterprise:slide | read, write, share, print |
| Project | urn:enterprise:project | read, write, manage, archive |
| HRRecord | urn:enterprise:hr-record | read, audit |
Scope-resource binding: Scopes are grouped under resource types in granted_resources. read and write for Calendar are in the grant for urn:enterprise:calendar. read and write for Document are in the grant for urn:enterprise:document. Calendar write does not imply Document write.
Resource servers
| RS | Resource Indicator | Types Served |
|---|---|---|
| Calendar API | https://api.corp.example.com/calendar/* | Calendar |
| Email API | https://api.corp.example.com/email/* | |
| Docs API | https://api.corp.example.com/docs/* | Document, Slide |
| Project API | https://api.corp.example.com/projects/* | Project |
| HR API | https://api.corp.example.com/hr/* | HRRecord |
Trust issuers
- https://trust.corp.example.com — Internal app registry
- https://federation.corp.example.com — Third-party integrations
Client apps and entitlements
| App | Type | granted_resources |
|---|---|---|
| Workspace | confidential_app | urn:as:userinfo (openid); calendar, document, slide, project with scopes per type; resource_indicators for calendar/, docs/, projects/* |
| HR Portal | confidential_app | urn:as:userinfo (openid); hr-record, document with scopes; resource_indicators for docs/, hr/ |
| Project Sync | confidential_app | urn:as:userinfo (openid); project: read; resource_indicator for projects/* |
Key flows:
- Eng user via Workspace: calendar.read, calendar.write, document.read, document.write, project.read
- HR user via HR Portal: hr-record.read, document.read (for policies)
- Third-party Project Sync: project.read only — no HR, no email, no document write
Example token requests
Workspace app — read calendar:
scope=openid read
resource=https://api.corp.example.com/calendar/events
resource_types=urn:enterprise:calendar
Workspace app — write document (not calendar):
scope=openid write
resource=https://api.corp.example.com/docs/files
resource_types=urn:enterprise:document
HR Portal — read HR record:
scope=openid read
resource=https://api.corp.example.com/hr/records
resource_types=urn:enterprise:hr-record
Policy implementation note
The token policy uses the unified model: granted_resources (array of { type, scopes, resource_indicator? }). Resource-scoped scopes require resource_types in the request. Policy evaluates via oauth.entitlements.client_is_allowed.
Try it
See this model in action with the Quickstart — from credentials to a policy decision in 5 minutes.
Want to discuss how PBAC fits your environment? Talk to us →
Next steps
- Quickstart — From credentials to a policy decision in 5 minutes
- Registering Software — How partners self-register via DCR with software statements
- Policy Data — Configure entitlements, denylists, and IdP selection rules