Skip to main content

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