PBAC Onboarding Guide¶
This document explains how access control works in practical terms. It covers how requests are evaluated, how company and project permissions work together, how visibility and quotas are enforced, and how policy changes are tracked.
How a Request Flows Through the System¶
When a user makes an API call, here is what happens:
Responsibility Model¶
- Gateway → Enforces decisions
- PolicyVault → Makes decisions
- Services → Execute business logic only
Services must not independently decide authorization.
3. The Access Hierarchy¶
Everything in the system follows a strict structure.
Tenant¶
Derived from the Keycloak realm. Provides complete isolation between customers.
Company¶
Represents an organization. Governs users, projects, and company-level quotas.
Project¶
A workspace inside a company (or personal). Contains resources and members.
Resource¶
Files, folders, templates --- any object requiring access control.
Every access decision walks down this hierarchy.
4. Company-Level Access¶
Company scope answers:
"Are you allowed to operate inside this organization?"
Available Scopes¶
- Owner
- Admin
- Editor
- Viewer
- Member
What Company Scope Controls¶
- Managing company users
- Managing company projects
- Managing company quotas
- Organization-level settings
If the user is not a company member, access is denied immediately.
5. Project-Level Access¶
Project role answers:
"What are you allowed to do inside this workspace?"
Available Roles¶
- Owner
- Admin
- Contributor
- Viewer
- Custom
What Project Role Controls¶
- Viewing project resources
- Creating or editing resources
- Managing project users
- Managing project quotas
- Sharing resources
For company projects, access requires both company and project approval:
For personal projects, only the project check applies.
6. Resource Visibility and Sharing¶
Passing project access does not guarantee visibility of all resources.
Resources can be shared in two ways:
- Anyone → visible to all project members
- Personal → visible only to specific users + project owner
Visibility Evaluation¶
Folder Inheritance¶
If a folder is shared, all child resources inherit its visibility.
Important principle:
- Roles grant ability
- Sharing grants visibility
Both must pass.
7. Quota Enforcement¶
Authorization includes usage limits.
Supported Quota Types¶
- Compute Credits
- Storage Size
- API Calls
- Custom Types
Before resource consumption, the system evaluates:
If either company or project capacity is exceeded, the request fails
with AccessLimitExceeded.
Quota validation is mandatory before resource allocation.
8. Core Use Cases¶
8.1 User Requests a Model¶
- User sends request with JWT
- Gateway validates JWT
- Gateway calls PolicyVault
- Company → Project → Resource checks
- If allowed, request proceeds
8.2 Admin Adds User to Company¶
- Admin submits request
- Gateway verifies Admin scope
- PolicyVault updates User and Company atomically
- Events are recorded
- Versions increment
8.3 User Shares a Resource¶
- Project Admin sets resource to Personal scope
- PolicyVault updates sharing configuration
- Events are recorded
- Only listed users can access the resource; others do not see it
8.4 Quota Check Before Resource Allocation¶
- Service requests quota validation
- PolicyVault calculates remaining capacity
- If sufficient → allow
- If insufficient → deny
8.5 Convert Personal Project to Company Project¶
- Company Admin initiates conversion
- PolicyVault verifies authority
- Project is linked to company
- Quotas initialized
- Events emitted
9. Event Sourcing and Audit¶
Every significant change in the policy system—such as adding a user, modifying a role, sharing a resource, or updating quotas—is recorded as an immutable event, creating a complete and authoritative history. Instead of storing only the latest state, the system preserves the full sequence of changes, allowing the current state to be reconstructed by replaying that history.
-
A Command is issued
Someone intends to change something. For example:
- Add user to company
- Change project role
- Share resource
- Update quota
-
An Event is produced
If the command is valid, the system records what happened as an event:
CompanyUserAddedProjectRoleChangedResourceSharedQuotaLimitUpdated
-
The Aggregate Version is incremented
Each company, project, or user maintains a version number. Each new event increases this version. This ensures secure concurrency and avoids conflicting updates.
-
Projections update read models
Background processes consume events and optimize read models. PolicyVault uses these read models for fast access checking.
Every change to policy is recorded as an event, so we always know what changed, who changed it, and when. Since the current state is built from those events, we can rebuild it at any time if needed. Version numbers prevent conflicts when multiple updates happen at once, and commands are designed to reject duplicate or invalid changes. Together, this gives us a clear audit trail, protects against race conditions, and allows us to confidently explain why a specific access decision was made.
10. Multi-Tenancy and Isolation¶
Tenant ID is extracted from the JWT.
All entities are tenant-scoped:
- Users
- Companies
- Projects
- Resources
- Events
No cross-tenant access is permitted.
All queries must include tenant context.
11. Internal Service Security¶
- Even internal services authenticate using OAuth2 Client Credentials.
- There is no implicit trust inside the cluster.
- Defense-in-depth applies at every layer.
12. Engineering Rules¶
- Never bypass PolicyVault for authorization decisions.
- Never allow services to infer permissions.
- Always scope by tenant.
- Never assume project membership implies visibility.
- Always check quotas before resource consumption.
- Never mutate policy state without emitting events.