|
| 1 | +# CSS Scope Issue - Root Cause Analysis |
| 2 | + |
| 3 | +## The Problem |
| 4 | + |
| 5 | +Access tokens have `"scope": ""` (empty) even though: |
| 6 | +- ✅ Client is registered with `"scope":"openid webid offline_access"` |
| 7 | +- ✅ CSS server supports `["openid", "profile", "offline_access", "webid"]` |
| 8 | +- ✅ Our code requests `['openid', 'webid', 'offline_access']` |
| 9 | + |
| 10 | +## Investigation Findings |
| 11 | + |
| 12 | +### 1. Client Registration (CORRECT) |
| 13 | + |
| 14 | +File: `/data/.internal/idp/adapter/Client/jwRIERi9-RW7LU_42zM3f$.json` |
| 15 | + |
| 16 | +```json |
| 17 | +{ |
| 18 | + "client_id": "jwRIERi9-RW7LU_42zM3f", |
| 19 | + "client_name": "Fleetbase-v2", |
| 20 | + "scope": "openid webid offline_access", ← Registered correctly |
| 21 | + "dpop_bound_access_tokens": false ← Should this be true? |
| 22 | +} |
| 23 | +``` |
| 24 | + |
| 25 | +### 2. CSS Server Configuration (CORRECT) |
| 26 | + |
| 27 | +File: `/config/config/identity/handler/base/provider-factory.json` |
| 28 | + |
| 29 | +```json |
| 30 | +{ |
| 31 | + "scopes": ["openid", "profile", "offline_access", "webid"], ← Server supports these |
| 32 | + "features": { |
| 33 | + "dPoP": { "enabled": true } |
| 34 | + } |
| 35 | +} |
| 36 | +``` |
| 37 | + |
| 38 | +### 3. Grant Storage (ISSUE FOUND!) |
| 39 | + |
| 40 | +File: `/data/.internal/idp/adapter/Grant/-HGiJLKCUJ7CZcU0ePOWQdw84p_WSNKWp3ajB3Q_mf3$.json` |
| 41 | + |
| 42 | +```json |
| 43 | +{ |
| 44 | + "accountId": "http://solid:3000/test/profile/card#me", |
| 45 | + "clientId": "jwRIERi9-RW7LU_42zM3f", |
| 46 | + "openid": { |
| 47 | + "scope": "openid webid" ← Only these two! Missing offline_access! |
| 48 | + } |
| 49 | +} |
| 50 | +``` |
| 51 | + |
| 52 | +**Problem:** The grant only includes `"openid webid"`, not `"offline_access"`. |
| 53 | + |
| 54 | +### 4. Access Token (RESULT) |
| 55 | + |
| 56 | +From logs: |
| 57 | +```json |
| 58 | +{ |
| 59 | + "webid": "http://solid:3000/test/profile/card#me", |
| 60 | + "scope": "", ← Empty! |
| 61 | + "client_id": "jwRIERi9-RW7LU_42zM3f" |
| 62 | +} |
| 63 | +``` |
| 64 | + |
| 65 | +## Root Cause |
| 66 | + |
| 67 | +The scope is stored in the Grant under the `"openid"` key: |
| 68 | +```json |
| 69 | +"openid": {"scope": "openid webid"} |
| 70 | +``` |
| 71 | + |
| 72 | +But CSS might not be extracting it correctly when issuing access tokens, resulting in empty scope. |
| 73 | + |
| 74 | +## Possible Solutions |
| 75 | + |
| 76 | +### Option 1: Fix Grant Scope Storage |
| 77 | + |
| 78 | +CSS might be storing scopes incorrectly. This could be: |
| 79 | +- A CSS bug |
| 80 | +- A configuration issue |
| 81 | +- Expected behavior for certain grant types |
| 82 | + |
| 83 | +### Option 2: Use Different Grant Type |
| 84 | + |
| 85 | +The current grant type might not support scopes properly. Try: |
| 86 | +- Client credentials grant (already tried, same issue) |
| 87 | +- Refresh token flow |
| 88 | +- Different authorization parameters |
| 89 | + |
| 90 | +### Option 3: Manual Scope Injection |
| 91 | + |
| 92 | +Modify CSS code or configuration to ensure scopes are included in access tokens. |
| 93 | + |
| 94 | +### Option 4: Workaround - Use ACL Without Scope |
| 95 | + |
| 96 | +Since the ACL is already correct and grants full permissions, the issue is that CSS requires `webid` scope to authenticate as the WebID. |
| 97 | + |
| 98 | +**Workaround:** Use a different authentication method that doesn't require scope: |
| 99 | +- CSS credential tokens (tried, same scope issue) |
| 100 | +- Direct WebID authentication |
| 101 | +- Bearer tokens without scope validation |
| 102 | + |
| 103 | +## Next Steps |
| 104 | + |
| 105 | +1. **Check if `dpop_bound_access_tokens` should be true** |
| 106 | + - Current: `false` |
| 107 | + - Might affect scope handling |
| 108 | + |
| 109 | +2. **Verify authorization request includes scope parameter** |
| 110 | + - Check if scope is being sent during auth code exchange |
| 111 | + - Verify it's not being filtered out |
| 112 | + |
| 113 | +3. **Test with explicit scope in token request** |
| 114 | + - Add scope parameter to token exchange request |
| 115 | + - See if CSS honors it |
| 116 | + |
| 117 | +4. **Check CSS logs for scope-related warnings** |
| 118 | + - CSS might be logging why scopes are being dropped |
| 119 | + |
| 120 | +## CSS Configuration Files Analyzed |
| 121 | + |
| 122 | +- `/config/config/oidc.json` - Main OIDC config |
| 123 | +- `/config/config/identity/oidc/default.json` - OIDC handler |
| 124 | +- `/config/config/identity/handler/base/provider-factory.json` - Scope definitions |
| 125 | +- `/config/config/ldp/metadata-writer/writers/www-auth.json` - WWW-Authenticate header |
| 126 | +- `/data/.internal/idp/adapter/Client/*` - Client registrations |
| 127 | +- `/data/.internal/idp/adapter/Grant/*` - Authorization grants |
| 128 | + |
| 129 | +## Conclusion |
| 130 | + |
| 131 | +The issue is NOT with: |
| 132 | +- ❌ Client registration (correct) |
| 133 | +- ❌ Server configuration (correct) |
| 134 | +- ❌ Our code (correct) |
| 135 | + |
| 136 | +The issue IS with: |
| 137 | +- ✅ Grant scope storage (only `"openid webid"`, missing `"offline_access"`) |
| 138 | +- ✅ Access token scope extraction (returns empty instead of grant scopes) |
| 139 | + |
| 140 | +This appears to be a CSS behavior or bug where scopes are not properly propagated from grants to access tokens. |
0 commit comments