## Summary
Getting persistent 401 Unauthorized errors when using atlassian-python-api with a properly configured Scoped API Token that has all necessary read permissions enabled.
## Environment
- **Library**: atlassian-python-api v4.0.7
- **Python**: 3.x
- **OS**: Windows (CYGWIN_NT-10.0-26200)
- **Confluence**: Cloud (bitsensing.atlassian.net)
- **Authentication**: Username + API Token (Basic Auth)
## Issue Description
When attempting to access Confluence REST API v1 endpoints using a Scoped API Token with all read permissions enabled, the requests fail with 401 Unauthorized error. However, using an "Automatic (Allow all operations)" token works successfully.
## API Token Configuration
### Scoped Token (FAILING - 401 Error)
**Classic Scopes Enabled:**
- ✅ `read:confluence-content.all` - Read pages, blogposts, and comments
- ✅ `read:confluence-space.summary` - Read space information
- ✅ `readonly:content.attachment:confluence` - Read and download attachments
- ✅ All other `read:*` scopes available in Classic tab
**Granular Scopes Enabled:**
- ✅ `read:page:confluence`
- ✅ `read:content:confluence`
- ✅ `read:content-details:confluence`
- ✅ `read:space:confluence`
- ✅ `read:space-details:confluence`
- ✅ `read:attachment:confluence`
- ✅ `read:hierarchical-content:confluence`
- ✅ All other `read:*` scopes available in Granular tab
Despite enabling ALL available read permissions in both Classic and Granular scopes, the API still returns 401 Unauthorized.
### Automatic Token (WORKING)
Using "Automatic (Allow all operations)" token works without any issues, which confirms:
- Username and authentication method are correct
- User account has permission to access the resources
- Base URL and API endpoints are correct
## Code to Reproduce
### Test Script
```python
import os
import requests
from dotenv import load_dotenv
load_dotenv()
username = os.getenv("CONFLUENCE_USERNAME") # eugene@bitsensing.com
token = os.getenv("CONFLUENCE_TOKEN") # Scoped token with all read permissions
# Test 1: Get current user
url = f"{base_url}/rest/api/user/current"
response = requests.get(url, auth=(username, token))
print(f"Status: {response.status_code}") # Returns 401
# Test 2: Get page content
url = f"{base_url}/rest/api/content/987037719"
response = requests.get(url, auth=(username, token))
print(f"Status: {response.status_code}") # Returns 401
# Test 3: Search content
url = f"{base_url}/rest/api/content/search"
params = {"cql": "type=page", "limit": 1}
response = requests.get(url, auth=(username, token), params=params)
print(f"Status: {response.status_code}") # Returns 401
```
### Using atlassian-python-api
```python
from atlassian import Confluence
confluence = Confluence(
username="eugene@bitsensing.com",
password="<scoped_token_with_all_read_permissions>",
cloud=True
)
# All methods fail with 401
page = confluence.get_page_by_id("987037719") # HTTPError: Unauthorized (401)
```
## API Endpoints Being Called
Based on source code analysis of atlassian-python-api v4.0.7:
1. `get_page_by_id()` → `rest/api/content/{page_id}` (v1 API)
2. `get_all_pages_from_space()` → `rest/api/content` (v1 API)
3. `get_page_child_by_type()` → `rest/api/content/{page_id}/child/{type}` (v1 API)
4. `get_attachments_from_content()` → `rest/api/content/{page_id}/child/attachment` (v1 API)
All endpoints are v1 REST API, which should require Classic scopes according to Atlassian documentation.
## Error Message
```
requests.exceptions.HTTPError: Unauthorized (401)
```
## Expected Behavior
- API requests should succeed with a Scoped API Token that has all necessary read permissions enabled
- Should be able to read pages, spaces, and attachments using Classic scopes: `read:confluence-content.all`, `read:confluence-space.summary`, `readonly:content.attachment:confluence`
## Actual Behavior
- All API requests return 401 Unauthorized when using Scoped API Token
- Same requests work perfectly with "Automatic (Allow all operations)" token
- User account has permission to view the resources (verified via browser)
## Attempts to Resolve
1. ✅ Verified authentication method (Basic Auth with username + token)
2. ✅ Verified base URL includes `/wiki` path
3. ✅ Enabled ALL Classic scopes (all `read:*` permissions)
4. ✅ Enabled ALL Granular scopes (all `read:*` permissions)
5. ✅ Verified user account has access to resources via browser
6. ✅ Verified API endpoints are v1 (should use Classic scopes)
7. ✅ Tested with direct HTTP requests (not library-specific issue)
8. ❌ Still getting 401 with Scoped Token
## Questions
1. **Is there a known issue with Scoped API Tokens and Confluence REST API v1?**
- Our analysis shows all endpoints use v1 API (`/rest/api/*`)
- Classic scopes should be sufficient for v1 API
- Why are all read permissions insufficient?
2. **Are there hidden/undocumented permissions required?**
- We enabled ALL available `read:*` scopes in both Classic and Granular tabs
- Is there a scope that's required but not visible in the token creation UI?
3. **Is "Automatic (Allow all operations)" the only supported method?**
- This seems to defeat the purpose of Scoped API Tokens
- Security best practices require principle of least privilege
## Additional Context
- Token format: `ATATT3x...` (Scoped API Token)
- Authentication tested with both `atlassian-python-api` library and direct `requests` library
- Same behavior across multiple test scripts
- User account: `eugene@bitsensing.com`
- Confluence instance: `bitsensing.atlassian.net`
## Workaround
Currently using "Automatic (Allow all operations)" token, but this is not acceptable for production use due to security concerns.
## Request
Please provide guidance on:
1. The exact scopes required for Confluence REST API v1 read operations
2. Whether this is a bug in scope validation
3. Documentation on proper Scoped API Token configuration for read-only access
Thank you for your assistance.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.