Repository navigation
Description
Requirement
Conditionally show pages and actions based on the authenticated user's permissions:
- Administrators can manage elements and purposes and view all consents.
- DPOs can view all consents and will later access grievances.
- End users can view and manage only their own consents.
Backend APIs must enforce the same permissions independently of UI visibility (It already does as at now).
Reference: APIM Portals
APIM maps roles to OAuth scopes. The frontend does not communicate directly with the identity provider. It calls APIM’s backend introspection endpoint, which reconstructs the access token and sends it to the identity provider for introspection (introspect.jsp).
The backend returns the introspection result to the frontend. The frontend extracts the granted scopes and stores them on the current user (AuthManager.js).
UI elements are wrapped with ScopeValidation, which compares the user’s scopes with those required by the API operation. For example, the Delete API button is conditionally displayed using this component (DeleteApiButton.jsx).
The APIs independently enforce the same scopes. UI visibility is therefore a usability feature rather than the security boundary.
Suggested approach
Use the existing API scopes as the common permission model for frontend visibility and backend authorization. Avoid checking role names such as Admin or DPO directly in the frontend.
The frontend should call the backend /me endpoint and must not interact directly with the identity provider. The backend should:
- Reconstruct the access token from its split-token storage.
- Validate the JWT signature using the identity provider’s JWKS.
- Validate claims such as issuer, audience, expiry, subject, and organization.
- Extract the granted scopes from the validated token.
- Return a minimal current-user response:
{
"authenticated": true,
"userId": "user-123",
"organizationId": "org-1",
"scopes": [
"portal:consents:read:any",
"portal:elements:read"
]
}The frontend should load /me during application initialization and provide reusable authorization utilities for:
- Hiding inaccessible navigation items.
- Protecting routes from direct navigation.
- Hiding or disabling create, edit, delete, and revoke actions.
- Checking whether the user has any or all required scopes.
Use the following role-to-scope mappings:
- Administrator: consent read/write-any and element/purpose read/write scopes.
- DPO: consent read-any and future grievance scopes.
- End user: consent read/write-self scopes.
Every backend endpoint must continue enforcing its required scope using the validated principal. Frontend checks are only for presentation and navigation and are not the security boundary.
Reuse API scopes when a page represents access to the corresponding API capability. Add a new scope only for a genuinely distinct permission, such as grievance access, rather than introducing separate UI-only scopes.
Activity
rashmithachamikara commentedon Jul 31, 2026
@hasithakn @anjuchamantha @Lihini0202 @ParameswaranSajeenthiran
rashmithachamikara commentedon Jul 31, 2026
Example from reference
APIM uses a reusable React wrapper called
ScopeValidationto conditionally render UI elements.Example: showing the “Delete API” button
Source:
AuthManager.jslines 92–100ScopeValidation, identified by its API resource path and HTTP method:Source:
DeleteApiButton.jsxlines 292–310ScopeValidationobtains:AuthManager.APIClient.It returns
trueif the user has at least one accepted scope:Source:
ScopeValidation.jsxlines 88–98APIClient.getScopeForResource()reads the accepted scopes from the Publisher OpenAPI definition:Source:
APIClient.jslines 88–104For
DELETE /apis/{apiId}, the API declares these accepted scopes:Source:
ApisApi.javalines 448–457ScopeValidation.render()either returns the wrapped button ornull:Source:
ScopeValidation.jsxlines 115–134Therefore:
A notable design choice is that the component does not hardcode
apim:api_delete. It identifies the operation asDELETE /apis/{apiId}and derives the accepted scopes from the API specification. The backend still enforces those scopes when the delete request is made; hiding the button is only the frontend presentation layer.rashmithachamikara commentedon Aug 4, 2026
Implemented in #81