OAuth Scopes and Permissions Overview OAuth scopes provide granular, fine-grained permission control within Genesys Cloud. They define exactly what resources an application can access and what actions it can perform. Scopes are requested during authorization and enforced on every API call. Scope Fundamentals What Are Scopes? Definition: ├─ Granular permissions for API access ├─ Limit what an application can do ├─ User consent on what app can access ├─ Enforced on every API request └─ Principle of least privilege Scope Format: resource:action OR resource:action:scope Examples: ├─ conversations:readonly # View conversations ├─ conversations:call:add # Make calls ├─ conversations:call:control # Transfer, hold ├─ users:manage # Create/modify users ├─ routing:queue:view # View queues └─ scheduling:manage # Manage schedules Space-Separated Combination: "conversations:readonly users:readonly scheduling:manage" User Sees During Authorization: ├─ App name ├─ All requested scopes ├─ What the app can do └─ User grants all or none (all-or-nothing) Enforcement: ├─ Every API request validated against token scopes ├─ If endpoint requires scope not in token: 403 Forbidden ├─ User permissions AND scopes both required (AND logic) ├─ Whichever is more restrictive applies └─ Better to have both than just one Scope Categories Conversation Management: ├─ conversations:readonly # GET conversations ├─ conversations:call:add # POST/make calls ├─ conversations:call:control # Transfer, hold, disconnect ├─ conversations:call:pull # Pull calls ├─ conversations:call:coach # Coach calls ├─ recordings:view # Access recordings ├─ recordings:download # Download recording files ├─ transcripts:readonly # View transcripts └─ conversations:external:contact:add # Add external contacts User Management: ├─ users:readonly # Read user info ├─ users:manage # Create/update/delete users ├─ authorization:grant:readonly # View user permissions ├─ authorization:grant:manage # Modify user permissions ├─ presence:readonly # View presence status └─ presence:manage # Change presence Contact Center Configuration: ├─ routing:queue:view # View queue config ├─ routing:queue:manage # Create/edit queues ├─ routing:skill:view # View skills ├─ routing:skill:manage # Manage skills ├─ directory:organization:view # View org structure ├─ telephony:phone:manage # Manage phones ├─ outbound:campaign:view # View campaigns └─ outbound:campaign:execute # Run campaigns Workforce Management: ├─ forecasting:readonly # View forecasts ├─ forecasting:manage # Create/edit forecasts ├─ scheduling:readonly # View schedules ├─ scheduling:manage # Create/edit schedules ├─ timeoff:view # View time-off requests ├─ timeoff:manage # Approve time-off ├─ adherence:view # View adherence └─ adherence:manage # Manage adherence Analytics & Reporting: ├─ analytics:conversationDetail # Detailed conversation analytics ├─ analytics:aggregate:view # Aggregated analytics ├─ quality:evaluation:view # Quality evaluations ├─ quality:evaluation:manage # Create/edit evaluations ├─ speechanalytics:data:view # Speech analytics └─ reporting:analytics:view # Analytics reports Integration & External: ├─ externalcontacts:manage # CRM synchronization ├─ webhooks:manage # Webhook configuration ├─ webhooks:view # View webhooks ├─ scim:write # SCIM provisioning ├─ knowledge:manage # Knowledge articles └─ knowledge:readonly # View knowledge Platform Management: ├─ oauth:client:view # View OAuth clients ├─ oauth:client:manage # Create/edit OAuth clients ├─ admin:org:view # View org settings ├─ admin:org:manage # Modify org settings └─ audit:readonly # View audit logs Scope Selection Best Practices Principle of Least Privilege: Definition: ├─ Grant minimum scopes needed ├─ Only request what app actually uses ├─ Reduce impact if app compromised ├─ Easier to review and audit └─ Better security posture How to Select: 1. List API Endpoints Used: ├─ /conversations → conversations:readonly ├─ /v2/users/{id} → users:readonly ├─ /v2/conversations/{id}/notes → conversations:readonly └─ Map each endpoint to scope 2. Check Endpoint Documentation: ├─ Visit API Explorer ├─ View each endpoint ├─ Note required scope └─ Collect all scopes 3. Start with Read-Only: ├─ conversations:readonly (not call:add) ├─ users:readonly (not manage) ├─ Only add write scopes if needed └─ Safer starting point 4. Add Write Scopes Only If Needed: ├─ Review which operations require writes ├─ Add specific action scopes ├─ Example: call:add (not call:control) └─ One scope per action where possible 5. Remove Unused Scopes: ├─ Quarterly review ├─ Check OAuth client usage ├─ Remove unneeded scopes ├─ Reduce security surface └─ Document rationale 6. Document Your Choices: ├─ Why each scope is needed ├─ Which endpoints use it ├─ When to update scopes └─ Version control reasons Example Selection: App: Contact center agent desktop ├─ Endpoints needed: │ ├─ GET /conversations → conversations:readonly │ ├─ POST /conversations/{id}/participants/calls/transfer │ │ → conversations:call:control │ ├─ GET /users/me → users:readonly │ └─ PATCH /v2/users/{id}/presence → presence:manage │ └─ Final scopes: "conversations:readonly conversations:call:control users:readonly presence:manage" NOT these (too permissive): ├─ conversations:manage (not needed) ├─ users:manage (not needed) └─ conversations:call:add (can't initiate calls) Scope Enforcement Mechanism How Scopes Are Enforced: Every API Request Validation: 1. Client Sends Request: GET /api/v2/users/123 Authorization: Bearer {access_token} 2. Genesys Validates Token: ├─ Token signature valid? ├─ Token not expired? ├─ Token not revoked? └─ Check scopes and permissions 3. Endpoint Requires: ├─ Endpoint /v2/users/{id} requires scope: users:readonly ├─ Check if token has "users:readonly" scope └─ Check if user has permission to read users 4. Dual Validation (Both Required): ├─ Must have OAuth scope: ✓ users:readonly ├─ Must have user permission: ✓ (has role allowing read) ├─ Both? → Grant access ├─ Only one? → 403 Forbidden └─ Neither? → 403 Forbidden 5. Enforce Rules: ├─ User has scope but not permission → 403 ├─ User has permission but not scope → 403 ├─ User has both → 200 OK (success) └─ User has neither → 403 Example Scenarios: Scenario 1: Has Scope, Has Permission ├─ Token scope: users:readonly ✓ ├─ User role permission: can read users ✓ ├─ Result: 200 OK (access granted) └─ API call succeeds Scenario 2: Has Scope, No Permission ├─ Token scope: users:readonly ✓ ├─ User role permission: cannot read users ✗ ├─ Result: 403 Forbidden └─ API call denied Scenario 3: No Scope, Has Permission ├─ Token scope: users:readonly ✗ ├─ User role permission: can read users ✓ ├─ Result: 403 Forbidden └─ API call denied Scenario 4: No Scope, No Permission ├─ Token scope: users:readonly ✗ ├─ User role permission: cannot read users ✗ ├─ Result: 403 Forbidden └─ API call denied Example Error Response: HTTP 403 Forbidden { "error": { "message": "This application is not authorized to perform this action", "code": "PERMISSIONS_INSUFFICIENT", "status": 403 } } Checking Available Scopes: In API Explorer: 1. Visit: https://developer.genesys.cloud/api/rest/v2/ 2. Click any endpoint 3. See "Authorization" section 4. Lists required scope 5. Copy exact scope name Common Scope Combinations Agent Desktop Application: conversations:readonly conversations:call:control users:readonly presence:manage recordings:view (Read conversations, manage calls, see presence, view recordings) Admin Dashboard: users:readonly routing:queue:view routing:skill:view scheduling:readonly analytics:conversationDetail (Read-only access to key admin features) WFM Application: scheduling:manage forecasting:manage timeoff:manage adherence:manage users:readonly (Full WFM management) Integration Service (Salesforce Sync): externalcontacts:manage users:readonly conversations:readonly (Sync contacts, read-only other data) Chatbot / Virtual Agent: conversations:external:contact:add knowledge:readonly (Add external contacts, access knowledge) Analytics Reporter: analytics:conversationDetail analytics:aggregate:view quality:evaluation:view speechanalytics:data:view (Read-only analytics access) API Automation (Least Privilege): users:readonly (query users) outbound:campaign:view (check campaign status) (Minimal access for specific automation) Scope Changes & Updates Adding Scopes to Existing OAuth Client: Scenario: ├─ App previously only read conversations ├─ Now needs to transfer calls ├─ Must add conversations:call:control scope Steps: 1. Stop Using Old Client (or keep both briefly): ├─ Update app configuration ├─ Point to updated client └─ Test thoroughly 2. Navigate to OAuth Client in Admin: ├─ Admin → Integrations → OAuth ├─ Find your OAuth client ├─ Click Edit └─ Select Scopes 3. Update Scopes: ├─ Old: "conversations:readonly" ├─ New: "conversations:readonly conversations:call:control" ├─ Add all needed scopes └─ Save changes 4. User Must Re-Authorize: ├─ For Authorization Code Grant: Yes ├─ Users see new permissions consent screen ├─ Users must grant new scope └─ New token includes updated scopes 5. Test Thoroughly: ├─ Test new functionality ├─ Verify old functions still work ├─ Check error responses └─ Monitor for issues 6. Gradual Rollout (Optional): ├─ Update small group first ├─ Monitor for errors ├─ Expand to more users └─ Full rollout when confident Removing Unused Scopes: Scenario: ├─ App no longer uses contact creation ├─ Can remove conversations:external:contact:add ├─ Reduce security surface Steps: 1. Verify Not Used: ├─ Check code for usage ├─ Search for endpoint calls ├─ Verify in logs (not used) └─ Confirm removal safe 2. Update OAuth Client: ├─ Admin → Integrations → OAuth ├─ Click Edit ├─ Deselect unused scope └─ Save 3. No Re-Authorization Needed: ├─ Existing tokens still work ├─ New tokens won't have old scope ├─ Endpoints still work (user has permission) └─ Gradual transition 4. Monitor for Errors: ├─ Watch logs for 403 errors ├─ Verify no broken functionality └─ Quick rollback if issues Scope Testing Testing Scope-Based Authorization: Setup Test OAuth Client: 1. Create OAuth client with specific scopes 2. Authenticate with that client 3. Test that allowed endpoints work 4. Test that forbidden endpoints fail Testing Allowed Scope: Endpoint: GET /conversations Scope: conversations:readonly Token has scope: Yes Test: curl -H "Authorization: Bearer {token}" \ https://api.mypurecloud.com/api/v2/conversations Expected: HTTP 200 (success) Actual: ? Testing Denied Scope (Negative Test): Endpoint: POST /conversations (create) Scope needed: conversations:manage Token has scope: No Test: curl -X POST \ -H "Authorization: Bearer {token}" \ https://api.mypurecloud.com/api/v2/conversations Expected: HTTP 403 Forbidden Actual: ? Test Multiple Scopes: Token has scopes: ├─ conversations:readonly ├─ users:readonly └─ NOT: scheduling:manage Tests to Run: ├─ GET /conversations → 200 (has scope) ├─ GET /users → 200 (has scope) ├─ GET /schedules → 403 (no scope) ├─ DELETE /conversations/{id} → 403 (no manage scope) └─ DELETE /users/{id} → 403 (no manage scope) Automated Testing: Example Test Suite: Test Cases: ├─ [✓] conversations:readonly allows GET ├─ [✓] conversations:readonly denies POST ├─ [✓] conversations:call:control allows transfer ├─ [✓] users:readonly allows GET /users ├─ [✓] users:readonly denies PUT /users ├─ [✓] Multiple scopes work correctly ├─ [✓] Missing scopes return 403 └─ [✓] Expired token returns 401 Before Deployment: ├─ Run all scope tests ├─ Verify expected 403s ├─ Verify expected 200s └─ Document scope requirements Troubleshooting Scope Issues Problem: Getting 403 Forbidden on Valid Endpoint Check List: ┌─ Token Valid? │ ├─ Is token expired? │ ├─ Try making another call │ └─ Get fresh token if needed │ ├─ Scope Correct? │ ├─ Check API Explorer for required scope │ ├─ Verify token has that scope │ ├─ Look at token claims if JWT │ └─ Add missing scope to OAuth client │ ├─ User Has Permission? │ ├─ User role has permission? │ ├─ Check user's roles in Admin UI │ ├─ Check division assignments │ └─ Add necessary role if missing │ └─ Both Needed? ├─ User permission: Required ├─ OAuth scope: Required ├─ Have both? Should work └─ Missing one? 403 error Example Troubleshooting: Error: POST /v2/users returns 403 ├─ Required scope: users:manage ├─ Check 1: Token has users:manage? NO ✗ │ └─ Solution: Add users:manage scope to OAuth client │ ├─ Check 2: User has create user permission? YES ✓ │ └─ OK (permission is good) │ ├─ Root Cause: Missing scope in token ├─ Solution: Update OAuth client scopes └─ Retry after user re-authenticates Error: GET /v2/conversations returns 403 ├─ Required scope: conversations:readonly ├─ Check 1: Token has conversations:readonly? YES ✓ │ └─ OK (scope is good) │ ├─ Check 2: User has read conversations permission? NO ✗ │ └─ Solution: Add user to role with permission │ ├─ Root Cause: User lacks role permission ├─ Solution: Assign appropriate role to user └─ Retry after role assignment takes effect Common Mistakes: ❌ Wrong Scope Name: ├─ Requested: "conversation:view" (wrong) ├─ Correct: "conversations:readonly" └─ Solution: Check API Explorer for exact scope ❌ Typo in Scope: ├─ Requested: "users :manage" (space) ├─ Correct: "users:manage" └─ Solution: Check spacing carefully ❌ Missing Scope Entirely: ├─ Requested: "users:readonly" only ├─ Needed: "users:readonly users:manage" └─ Solution: Add missing scopes ❌ Wrong Colon Format: ├─ Requested: "users-manage" (dash) ├─ Correct: "users:manage" (colon) └─ Solution: Use colons, not dashes Scope Documentation For Your Team: Document Your Scopes: Application: [App Name] ├─ conversations:readonly │ ├─ Used for: Display conversation history │ ├─ Endpoints: GET /v2/conversations │ └─ Rationale: Need to show past interactions │ ├─ conversations:call:control │ ├─ Used for: Transfer calls between agents │ ├─ Endpoints: POST /v2/conversations/{id}/participants/calls/transfer │ └─ Rationale: Core feature for agent desktop │ ├─ users:readonly │ ├─ Used for: List available agents │ ├─ Endpoints: GET /v2/users │ └─ Rationale: Show agent list for transfers │ └─ Updated: March 2026 └─ Next Review: September 2026 Scope Change Log: Date | Change | Reason ------------|---------------|---------------------------------- 2026-03-01 | Added: call:control | New transfer feature 2026-01-15 | Added: users:readonly | Show agent list 2025-11-20 | Initial: conversations:readonly | Read-only access API Endpoint to Scope Mapping: Endpoint | Method | Scope Required ---------|--------|---------------- /v2/conversations | GET | conversations:readonly /v2/conversations | POST | conversations:readonly (new) /v2/conversations/{id} | GET | conversations:readonly /v2/users | GET | users:readonly /v2/users/{id}/presence | PATCH | presence:manage Key Takeaways: Chapter 5 Granular Permissions - Scopes define exactly what app can do Least Privilege - Request minimum scopes needed User Consent - Users see all scopes during authorization Dual Enforcement - User permissions AND OAuth scopes both required 403 Means Missing - Either scope or permission (or both) missing Standard Format - Use resource:action or resource:action:scope Space-Separated - Combine multiple scopes with spaces Review Regularly - Quarterly scope audits reduce security risk Interview Prep: OAuth Scopes Question Answer What are scopes? Granular permissions defining what app can access/do Scope format? resource:action or resource:action:scope (e.g., conversations:readonly) How combined? Space-separated list (e.g., "conversations:readonly users:manage") User sees scopes? Yes, during authorization consent screen All-or-nothing? Yes, user grants all requested scopes or none How enforced? Every API request checked against token scopes User + scope? BOTH required (AND logic), not OR 403 means? Missing scope or missing permission (or both) Best practice? Principle of least privilege - request minimum needed How update? Edit OAuth client, add/remove scopes, user must re-auth Document Version Chapter : 5 of 8 Last Updated : March 2026 Status : Current with OAuth 2.0 standards Scope : Scope management, enforcement, best practices