Access Control
Access Control defines who can execute an action and under what conditions. It consists of two components:
- Authorization Policy: Role-based access control
- Pre-conditions: Business rule validation
Authorization Policy
The Authorization Policy determines which users can execute an action based on their roles.
┌─────────────────────────────────────────────────────────────────────┐
│ ACCESS CONTROL FLOW │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ │
│ │ API Request │ │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Authorization │ Does user have │
│ │ Policy │ required role(s)? │
│ └────────┬────────┘ │
│ │ │
│ ┌──────┴──────┐ │
│ │ │ │
│ Yes No ────► 401 Unauthorized │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Pre-conditions │ Do all business │
│ │ Evaluation │ rules pass? │
│ └────────┬────────┘ │
│ │ │
│ ┌──────┴──────┐ │
│ │ │ │
│ Yes No ────► 400/403/etc (custom error) │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Execute Action │ │
│ │ (if all pass) │ │
│ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
Policy Types
| Policy Type | Description | Use Case |
|---|---|---|
| Demand All | User must possess ALL specified roles | Admin actions requiring multiple role memberships |
| Demand Any | User must possess at least ONE of the specified roles | Standard access where any authorized role suffices |
| Demand User Role | User must possess ONE specific role | Actions restricted to a single specific role |
| Demand Authenticated User | Any authenticated user can access | General endpoints available to all logged-in users |
| Demand Anonymous User | No authentication required | Public endpoints (e.g., public product catalog) |
Policy Type Comparison
┌─────────────────────────────────────────────────────────────────────┐
│ POLICY TYPE COMPARISON │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Policy Type │ Roles Config │ Requirement │
│ ─────────────────────────┼───────────────┼─────────────────────── │
│ Demand All │ Multiple │ Must have ALL roles │
│ Demand Any │ Multiple │ Must have ANY role │
│ Demand User Role │ Single │ Must have THIS role │
│ Demand Authenticated User│ None │ Just be logged in │
│ Demand Anonymous User │ None │ No login required │
│ │
└─────────────────────────────────────────────────────────────────────┘
Authorization Policy Configuration
Access Control:
└── Authorization Policy:
├── Type: Demand Any
└── Roles:
├── Administrator
├── SalesManager
└── CustomerServiceRep
Examples by Policy Type
Demand All Example:
Action: ApproveHighValueOrder
Authorization Policy:
├── Type: Demand All
└── Roles:
├── SalesManager ← User must have BOTH roles
└── FinanceApprover ← to execute this action
Demand Any Example:
Action: ViewAccountDetails
Authorization Policy:
├── Type: Demand Any
└── Roles:
├── Administrator ← User needs at least
├── SalesRep ← ONE of these roles
└── CustomerService ← to execute this action
Demand User Role Example:
Action: ManageSystemConfiguration
Authorization Policy:
├── Type: Demand User Role
└── Role: SystemAdministrator ← User must have exactly this role
Action: ProcessPayroll
Authorization Policy:
├── Type: Demand User Role
└── Role: PayrollManager ← Only PayrollManager role can execute
Demand Authenticated User Example:
Action: GetMyProfile
Authorization Policy:
└── Type: Demand Authenticated User
└── Any logged-in user can access their own profile
Demand Anonymous User Example:
Action: GetPublicProductCatalog
Authorization Policy:
└── Type: Demand Anonymous User
└── No login required - public access
When to Use Each Policy Type
| Scenario | Recommended Policy |
|---|---|
| Highly sensitive actions requiring multiple approvals | Demand All |
| Standard CRUD operations with multiple authorized roles | Demand Any |
| Role-specific actions (e.g., only HR can access employee data) | Demand User Role |
| User's own data (profile, preferences, history) | Demand Authenticated User |
| Public-facing data (product catalog, public announcements) | Demand Anonymous User |
Pre-conditions
Pre-conditions add business rule validation that must pass before the action executes. Even if a user has the required authorization, pre-conditions can block execution based on data conditions.
Pre-condition Structure
| Component | Description |
|---|---|
| Condition | Expression that must evaluate to true |
| Error Code | HTTP status code or custom error code returned on failure |
| Error Message | Human-readable message explaining the failure |
Pre-condition Configuration
Access Control:
└── Pre-conditions:
├── Pre-condition 1:
│ ├── Condition: Account.statecode = 0
│ ├── Error Code: 400
│ └── Error Message: "Cannot modify inactive accounts"
│
└── Pre-condition 2:
├── Condition: Account.creditlimit > 0
├── Error Code: 403
└── Error Message: "Account has no credit limit assigned"
Pre-condition Examples
Business Rule Validation:
Pre-condition: Order Amount Validation
├── Condition: OrderTotal <= Customer.CreditLimit
├── Error Code: 400
└── Error Message: "Order total exceeds customer credit limit"
State-Based Access:
Pre-condition: Case Must Be Open
├── Condition: Case.statecode = 0
├── Error Code: 409
└── Error Message: "Cannot add comments to closed cases"
Ownership Validation:
Pre-condition: User Owns Record
├── Condition: Record.ownerid = CurrentUser.Id OR CurrentUser.HasRole("Administrator")
├── Error Code: 403
└── Error Message: "You do not have permission to modify this record"
Time-Based Access:
Pre-condition: Within Business Hours
├── Condition: Hour(Now()) >= 8 AND Hour(Now()) <= 18
├── Error Code: 403
└── Error Message: "This action is only available during business hours"
Complete Access Control Example
Action: UpdateAccount
Access Control:
├── Authorization Policy:
│ ├── Type: Demand Any
│ └── Roles:
│ ├── Administrator
│ ├── AccountManager
│ └── SalesManager
│
└── Pre-conditions:
├── Pre-condition 1:
│ ├── Condition: Account.statecode = 0
│ ├── Error Code: 400
│ └── Error Message: "Cannot update inactive accounts"
│
├── Pre-condition 2:
│ ├── Condition: Account.ownerid = CurrentUser.Id OR
│ │ CurrentUser.HasRole("Administrator")
│ ├── Error Code: 403
│ └── Error Message: "You can only update accounts you own"
│
└── Pre-condition 3:
├── Condition: NOT Account.IsLocked
├── Error Code: 423
└── Error Message: "Account is locked for editing"