Skip to content

[APIM] [4.5.0] Unable to register and use local scopes with "/" #4659

@chandimajayawickrama

Description

@chandimajayawickrama

Description

It is not possible to register local scopes when the local scope has "/". For example the local scope looks like "dummy/sample".(tested this in resident key manager)

The following API call fails.

TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,342] DEBUG {org.apache.http.wire} - http-outgoing-93 >> "POST /api/identity/oauth2/v1.0/scopes HTTP/1.1[\r][\n]"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,342] DEBUG {org.apache.http.wire} - http-outgoing-93 >> "Authorization: Basic xxxxxxx[\r][\n]"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,342] DEBUG {org.apache.http.wire} - http-outgoing-93 >> "Content-Type: application/json[\r][\n]"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,342] DEBUG {org.apache.http.wire} - http-outgoing-93 >> "X-WSO2-Tenant: carbon.super[\r][\n]"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,342] DEBUG {org.apache.http.wire} - http-outgoing-93 >> "Accept: /[\r][\n]"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,342] DEBUG {org.apache.http.wire} - http-outgoing-93 >> "Content-Length: 109[\r][\n]"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,342] DEBUG {org.apache.http.wire} - http-outgoing-93 >> "Host: localhost:9443[\r][\n]"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,342] DEBUG {org.apache.http.wire} - http-outgoing-93 >> "Connection: Keep-Alive[\r][\n]"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,342] DEBUG {org.apache.http.wire} - http-outgoing-93 >> "User-Agent: Apache-HttpClient/4.5.13 (Java/21.0.9)[\r][\n]"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,342] DEBUG {org.apache.http.wire} - http-outgoing-93 >> "Accept-Encoding: gzip,deflate[\r][\n]"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,342] DEBUG {org.apache.http.wire} - http-outgoing-93 >> "[\r][\n]"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,342] DEBUG {org.apache.http.wire} - http-outgoing-93 >> "{[\n]"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,342] DEBUG {org.apache.http.wire} - http-outgoing-93 >> " "name": "dummy/sample",[\n]"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,342] DEBUG {org.apache.http.wire} - http-outgoing-93 >> " "displayName": "dummy/sample",[\n]"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,342] DEBUG {org.apache.http.wire} - http-outgoing-93 >> " "description": "",[\n]"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,342] DEBUG {org.apache.http.wire} - http-outgoing-93 >> " "bindings": [[\n]"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,342] DEBUG {org.apache.http.wire} - http-outgoing-93 >> " "api"[\n]"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,342] DEBUG {org.apache.http.wire} - http-outgoing-93 >> " ][\n]"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,342] DEBUG {org.apache.http.wire} - http-outgoing-93 >> "}"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,370] DEBUG {org.apache.http.wire} - http-outgoing-93 << "HTTP/1.1 400 [\r][\n]"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,371] DEBUG {org.apache.http.wire} - http-outgoing-93 << "X-WSO2-TraceId: 0c46fcd6-3a1a-40d5-967c-ae29462310ba[\r][\n]"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,371] DEBUG {org.apache.http.wire} - http-outgoing-93 << "X-Frame-Options: DENY[\r][\n]"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,371] DEBUG {org.apache.http.wire} - http-outgoing-93 << "X-Content-Type-Options: nosniff[\r][\n]"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,371] DEBUG {org.apache.http.wire} - http-outgoing-93 << "Date: Wed, 21 Jan 2026 11:58:49 GMT[\r][\n]"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,371] DEBUG {org.apache.http.wire} - http-outgoing-93 << "Content-Type: application/json[\r][\n]"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,371] DEBUG {org.apache.http.wire} - http-outgoing-93 << "Transfer-Encoding: chunked[\r][\n]"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,372] DEBUG {org.apache.http.wire} - http-outgoing-93 << "Connection: close[\r][\n]"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,372] DEBUG {org.apache.http.wire} - http-outgoing-93 << "Server: WSO2 Carbon Server[\r][\n]"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,372] DEBUG {org.apache.http.wire} - http-outgoing-93 << "[\r][\n]"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,372] DEBUG {org.apache.http.wire} - http-outgoing-93 << "c2[\r][\n]"
TID: [-1234] [api/am/publisher] [2026-01-21 14:58:49,372] DEBUG {org.apache.http.wire} - http-outgoing-93 << "{"code":"41011","message":"Bad Request","description":"Invalid scope name. Scope name dummy/sample cannot contain special characters ?,#,/,( or )","traceId":"0c46fcd6-3a1a-40d5-967c-ae29462310ba"}[\r][\n]"

The above causes the scopes in the token response to "default".

Steps to Reproduce

  1. Add the property in [1].
  2. Create a new user(ex: chandima) and a new role(ex: test). Assign this role to the user.
  3. Then, log in to the /publisher portal and create a sample API(ex: SampleAPI).
  4. Create a local scope(Ex: sample), assign the role in Step 1 to the scope.
  5. Now, assign this scope to an API resource. (ex: GET /sample) & save and deploy the API.
  6. Then, log in to the devportal using the user in Step 1 and create a sample application(used the DefaultApplication).
  7. Subscribe to the API in Step 2 and generate keys.
  8. Now, using a curl(or any other client), generate an access token.
  9. ex:
    curl --location 'https://localhost:9443/oauth2/token' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --header 'Authorization: Basic xxxxxxxxxxxxxx' \ --data-urlencode 'grant_type=client_credentials' \ --data-urlencode 'scope=sample'
  10. You can see the token contains the scope in Step 3.
  11. Then, create another local scope which has a "/". (ex: dummy/sample).
  12. Assign the same role in Step 1 and assign the scope to the same resource. Then save and deploy the API.
  13. The UI will show that the scope was added successfully.
  14. Now, try to invoke the token endpoint with the scope in Step 3.
  15. You can observe the response does not contain the scope and the only scope available is "default".

[1] https://apim.docs.wso2.com/en/4.5.0/manage-apis/design/api-security/oauth2/oauth2-scopes/fine-grained-access-control-with-oauth-scopes/#restrict-unassigned-scopes

Version

4.5.0

Environment Details (with versions)

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions