Azure DevOps Permissions
This document outlines the minimum permissions required for azdw to function properly with Azure DevOps.
Using GitHub or GitHub Enterprise instead? See GitHub & GitHub Enterprise Permissions for the equivalent classic and fine-grained personal access token permissions.
Quick Reference
PAT Token Scopes
| Feature | Required Scopes (OAuth Scope Names) |
|---|---|
| Query work items (WIQL) | Work Items (Read & Write) [vso.work_write] + Project and Team (Read) [vso.project] |
| Create/update work items | Work Items (Read & Write) [vso.work_write] + Project and Team (Read) [vso.project] |
| Cross-org relationships | Same scopes on all organizations |
File content extraction (--resolve-file-content) | Code (Read) [vso.code] - Required to fetch Git file contents for field extraction |
Note: Azure DevOps does not have separate “Read”, “Write”, and “Manage” scopes for Work Items. The actual scopes are:
- Work Items (Read) =
vso.work- Read-only access- Work Items (Read & Write) =
vso.work_write- Read, create, update, execute WIQL queries- Code (Read) =
vso.code- Read source code and metadata (required for--resolve-file-content)
User Access Requirements
- Access Level: Basic (minimum) - Stakeholder access is insufficient
- Organization: Must be a member (not guest) of Azure DevOps organization
- Project Permissions: View/Edit work items as needed
Detailed Permission Requirements
Query Operations (WIQL Queries, Metadata)
Required PAT Scopes:
- ✅ Work Items (Read & Write) [
vso.work_write] - Execute WIQL queries, read work items - ✅ Project and Team (Read) [
vso.project] - Access project metadata for validation
Why “Read & Write” is required for queries: According to the official Azure DevOps REST API documentation, the vso.work_write scope grants the ability to:
“read, create, and update work items and queries, update board metadata, read area and iterations paths other work item tracking related metadata, execute queries, and to receive notifications about work item events via service hooks.”
WIQL query execution (POST /_apis/wit/wiql) requires the vso.work_write scope, not just vso.work (read-only).
API Endpoints Used:
POST /_apis/wit/wiql- Execute WIQL queries (requiresvso.work_write)GET /_apis/wit/workitems- Get work item details (requiresvso.work_write)GET /_apis/wit/workitemtypes- Get work item type metadata (requiresvso.work_write)GET /_apis/wit/fields- Get field definitions (requiresvso.work_write)GET /_apis/projects- Get project information (requiresvso.projectorvso.profile)
User Requirements:
- Basic access level (minimum)
- View work items permission in target projects
Write Operations (Create, Update)
Required PAT Scopes:
- ✅ Work Items (Read & Write) [
vso.work_write] - Create and modify work items - ✅ Project and Team (Read) [
vso.project] - Access project metadata
API Endpoints Used:
POST /_apis/wit/workitems/${type}- Create new work itemsPATCH /_apis/wit/workitems/{id}- Update existing work items
User Requirements:
- Basic access level (minimum)
- Create/Edit work items permission in target projects
Cross-Connection Operations
Requirements:
- Separate PAT or OAuth credentials for each organization
- Same permission requirements apply to each organization
- User must be a member of all target organizations
Setting Up PAT with Correct Scopes
- Navigate to Azure DevOps
- Go to https://dev.azure.com/[your-organization]
- Click User Settings (profile icon) → Personal Access Tokens
- Create New Token
- Click “New Token”
- Give it a descriptive name (e.g., “azdw-tool-2025”)
- Set expiration (30-90 days recommended)
- Select Scopes (Custom Defined)
- For query and read operations:
- ✅ Work Items: Select Read & Write (this is required for WIQL queries, not just “Read”)
- ✅ Project and Team: Select Read
- For full functionality (same as above):
- ✅ Work Items: Select Read & Write
- ✅ Project and Team: Select Read
- For file content extraction (
--resolve-file-content):- ✅ Code: Select Read (required to fetch Git file contents for extracting fields like ADR status)
- For query and read operations:
- Copy Token
- Copy the generated token immediately
- Store it securely (azdw will encrypt it locally)
Common Permission Errors
“Unauthorized” (401) or HTTP 302 Redirects to Sign-In Page
Error: Access denied to organization 'myorg'
or
Error: Authentication redirect detected. Azure DevOps returned 302.
Possible Causes:
- PAT token expired or invalid
- PAT missing “Read & Write” scope for Work Items (only has “Read”)
- User not a member of the organization
- Stakeholder access level (insufficient)
Solutions:
- Check PAT expiration in Azure DevOps
- Verify PAT has “Work Items (Read & Write)” scope, not just “Read”
- Verify organization membership
- Request Basic access level from admin
“Forbidden” (403)
Error: Access forbidden for operation
Possible Causes:
- Missing required PAT scopes
- No permission to specific project
- Trying to write without Write scope
Solutions:
- Add missing scopes to PAT
- Request project access from project admin
- Ensure PAT includes Work Items (Read & Write) for all operations
“File content extraction fails” (401 with --resolve-file-content)
Failed to fetch file content from '...': HTTP 401 Unauthorized.
To use --resolve-file-content, your PAT requires 'Code (Read)' permission.
Possible Causes:
- PAT does not have “Code (Read)” scope
- Attempting to use
--resolve-file-contentwithout Git repository access
Solutions:
- Add Code (Read) scope to your PAT in Azure DevOps
- Navigate to User Settings → Personal Access Tokens → Edit → Add “Code (Read)”
- The Code scope is required to access Git repository content via the Azure DevOps REST API
“Work item type not found”
Error: Work item type 'Epic' not found
Possible Causes:
- Missing “Project and team (Read)” scope
- No access to target project
- Project name incorrect
Solutions:
- Add “Project and team (Read)” to PAT
- Verify project name and access
- Check organization URL is correct
Verification Commands
Test your permissions with these azdw commands:
# Test basic connectivity
azdw connection check --name MyOrg
# Test read permissions
azdw query --connections MyOrg --types Epic --limit 1
# Test metadata access
azdw metadata types --connection MyOrg
# Test project access
azdw metadata projects --connection MyOrg
Best Practices
- Start with minimum scopes (read-only) and add write permissions only when needed
- Use descriptive PAT names that indicate purpose and expiration
- Set reasonable expiration dates (30-90 days for security)
- Never commit PATs to source control or share them
- Use separate PATs for different purposes (read-only vs. read-write)
- Regularly audit and rotate tokens
OAuth Alternative
Consider using OAuth (Device Code Flow or Interactive Browser) instead of PAT for:
- Better security (MFA support, automatic refresh)
- Multi-tenant scenarios
- Long-running operations (no manual token renewal)
OAuth tokens inherit your user permissions, so no separate scope configuration is needed.