User Permissions¶
Set up Business Roles and map them to application permissions for user access control.
| Property | Value |
|---|---|
| Goal | Configure which users can access your application |
| Prerequisites | Forge API project created, understanding of Business Roles |
| Time Estimate | 15-30 minutes |
| Difficulty | Intermediate |
📋 Overview¶
User permissions control which Business Roles can access your application and what they can do. Configuration must be done in both identity providers to support corporate and external users.
User Permission Flow¶
User → Authenticates via → Has Business Role → Granted App Roles → Can Access Features
(Entra or Okta) (Claims Adjuster) (App.Read, App.Write) (based on roles)
Step 1: Define Application Roles¶
Define the roles available in your application in infra/api/config.yml:
# App Roles - assigned to users/groups and applications
app_roles:
- value: App.Read
display_name: Read Access
description: Allows reading data
- value: App.Write
display_name: Write Access
description: Allows writing data
- value: App.Admin
display_name: Administrator
description: Full administrative access
Entra ID Constraint
App roles and scopes cannot share the same value in Entra ID. Use a naming convention like App.Read for app roles and User.Read for scopes to avoid deployment errors.
For external (Okta) authentication, also define permissions in infra/auth/ext/okta-client/user_groups.yml:
# Keep in sync with infra/api/config.yml app_roles
app_permissions:
App.Read: Allows reading data
App.Write: Allows writing data
App.Admin: Full administrative access
Keep Files Synchronized
Both files must contain the same role values. Changes to one should be reflected in the other.
Step 2: Map Business Roles to App Roles¶
Configure which Business Roles have access to which roles in both identity providers.
File: infra/auth/corp/config.yml
Step 3: Deploy Your API¶
Before running authentication pipelines, your API must be deployed:
- Deploy your API using the standard pipeline (
azure-dotnet-api.yml) - This creates the Entra app registration and Okta client
- Required: API must be deployed to all environments including production before auth pipelines will work
Step 4: Run Authentication Pipeline¶
Apply your security configuration:
Option A: Standalone Auth Pipeline
Run azure-pipelines-auth.yml to deploy auth configuration independently:
- Use when you only need to update auth configuration
- Deploys both corporate (Entra) and external (Okta) auth
- Useful for granting new apps access without redeploying your API
Option B: With API Deployment
Auth configuration also deploys automatically with your API:
- Standard API deployment includes auth configuration
- Use for regular deployments where both code and auth change
✅ Verification¶
After deploying, verify the configuration:
- Check Entra ID: Verify app roles appear in the Enterprise Application
- Check Okta: Verify groups are created for each app role
- Test Access: Log in as a user with a mapped Business Role and verify permissions
🔍 Troubleshooting¶
Users Can't Access the Application¶
✅ Check:
- Business Role is correctly mapped in the appropriate config file:
- Corporate users:
infra/auth/corp/config.yml→business_roles - External users:
infra/auth/ext/user/business-role-app-role.yml→authorized_business_roles
- Corporate users:
- User has the correct Business Role assigned in the identity system
- Application roles are defined in
infra/api/config.yml - Auth pipeline has been run after configuration changes
"Insufficient Permissions" Errors¶
✅ Check:
- The Business Role has the necessary app roles assigned
- The app roles match what the application code expects
- Both corp and ext configurations are in sync
Configuration Out of Sync¶
✅ Check:
- App roles in
infra/api/config.ymlmatchinfra/auth/ext/okta-client/user_groups.yml - Auth pipeline has been run after all configuration changes
📋 TypeSpec Auth Configuration¶
Your API's TypeSpec definition includes an @useAuth decorator that specifies required authentication:
| API Type | Tenant | TypeSpec Auth | Description |
|---|---|---|---|
| Experience | External (Okta) | Scopes<["access"]> \| Roles<["App.Read"]> |
Supports OIDC login flow |
| Experience | Internal (Entra) | Roles<["App.Read"]> |
Role-based access only |
| System/Process | Either | Scopes<["User.Read"]> \| Roles<["App.Read"]> |
Service-to-service |
Ensure your TypeSpec auth decorator matches your configuration files:
| TypeSpec Reference | Configuration File | Key |
|---|---|---|
Roles<["App.Read"]> |
infra/api/config.yml |
app_roles |
Scopes<["User.Read"]> |
infra/api/config.yml |
scopes |
Tip
The template generates the correct @useAuth decorator based on your API type. If you add custom roles, update both the TypeSpec file and configuration files.
📚 Related Documentation¶
- Understanding Business Roles - How Business Roles work
- Configure App Permissions - Allow other apps to call your API
- Calling Downstream APIs - Configure Kiota clients with scopes