Skip to content

Commit 2f52a4d

Browse files
committed
docs: ADR for Enforcement mechanisms - current user permission checks from MFEs and other remote clients
1 parent ec2e182 commit 2f52a4d

1 file changed

Lines changed: 200 additions & 0 deletions

File tree

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
0007: Enforcement mechanisms - current user permission checks from MFEs and other remote clients
2+
################################################################################################
3+
4+
Status
5+
********
6+
7+
**Draft**
8+
9+
Context
10+
*********
11+
12+
Authorization (AuthZ) decisions need to be enforced not only on the
13+
backend services, but also on the frontend applications, including
14+
Micro-Frontends (MFEs) and mobile apps. This ensures that users only see
15+
and can interact with the UI elements they are permitted to access based
16+
on their roles and permissions.
17+
18+
To achieve this, we need to establish effective communication mechanisms
19+
between the backend services and the frontend clients. This involves
20+
determining how AuthZ data is transmitted, how often it is updated, and
21+
how the frontend applications can use this data to enforce access
22+
control for the currently authenticated user.
23+
24+
We want an approach that:
25+
26+
- Minimizes the amount of requests and data transferred between the
27+
backend and frontend.
28+
- Is granular enough to match the functionality available on the
29+
backend.
30+
- Is easy to implement and maintain across different frontend
31+
applications.
32+
33+
**Please note:** The scope of this ADR is limited to enforcing permissions
34+
for the currently authenticated user.
35+
36+
Decision
37+
**********
38+
39+
I. REST API for authorization queries
40+
=====================================
41+
42+
We will implement a dedicated REST API endpoint that frontend
43+
applications can use to query for specific permissions for the currently
44+
authenticated user. Queries would be at the Subject-Action-Object-Context
45+
level, being the Subject always the current authenticated user. This allows
46+
the frontend to check if a user has permission to perform a specific action
47+
on a specific object within a given context.
48+
49+
To optimize performance and reduce latency, the API will support batch
50+
queries, allowing multiple permission checks in a single request. It
51+
will also have caching mechanisms in place.
52+
53+
API Definition
54+
--------------
55+
56+
POST /api/authz/v1/permissions/validate/me
57+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
58+
59+
Validate if the current user has specific permissions.
60+
61+
Request Body:
62+
"""""""""""""
63+
64+
Format:
65+
66+
.. code:: ts
67+
68+
Array<{
69+
action: string
70+
object?: string
71+
scope?: string
72+
}>
73+
74+
Example:
75+
76+
.. code:: json
77+
78+
[
79+
{
80+
"action": "act:read",
81+
"object": "lib:test-lib",
82+
"scope": "org:OpenedX"
83+
},
84+
{
85+
"action": "act:edit",
86+
"object": "lib:test-lib",
87+
"scope": "org:OpenedX"
88+
}
89+
]
90+
91+
**Please Note:**
92+
93+
- The user (subject) would be inferred from the authenticated user
94+
making the request.
95+
- The order of the permissions in the response array will match the order
96+
of the request. This must be guaranteed by the implementation.
97+
The frontend will rely on this order to match responses to requests.
98+
99+
Response Body:
100+
""""""""""""""
101+
102+
Format:
103+
104+
.. code:: ts
105+
106+
Array<{
107+
action: string
108+
object?: string
109+
scope?: string
110+
allowed: boolean
111+
}>
112+
113+
Example:
114+
115+
.. code:: json
116+
117+
[
118+
{
119+
"action": "act:read",
120+
"object": "lib:test-lib",
121+
"scope": "org:OpenedX",
122+
"allowed": true
123+
},
124+
{
125+
"action": "act:edit",
126+
"object": "lib:test-lib",
127+
"scope": "org:OpenedX",
128+
"allowed": false
129+
}
130+
]
131+
132+
Possible response codes:
133+
""""""""""""""""""""""""
134+
135+
- 200: Ok, includes the Response Body defined above.
136+
- 400: Bad Request, happens when the request body doesn't match the
137+
required format.
138+
- 401: Unauthorized, happens when the user is not authenticated/logged in.
139+
140+
**Please note:** There is no “404 not found” case here, if the action,
141+
object or scope doesn't exist, the “allowed” value in the response will
142+
be whatever Casbin evaluates in this case.
143+
144+
II. Frontend integration
145+
========================
146+
147+
Frontend applications will integrate with the REST API to enforce
148+
authorization decisions. This will involve:
149+
150+
#. Querying the API for permissions when rendering UI components.
151+
#. Using the API response to conditionally render or style UI elements
152+
based on the user's permissions.
153+
#. Implementing a caching strategy on the frontend to minimize API calls
154+
and improve performance.
155+
156+
The specifics on when and how to query the API will depend on the
157+
application's architecture and user interaction patterns.
158+
159+
Standard frontend library functions will be developed to facilitate
160+
permission queries, incorporating reasonable defaults for caching,
161+
request deduplication, and auto-refresh mechanisms. These functions will
162+
most likely be implemented as part of frontend-base.
163+
164+
Consequences
165+
**************
166+
167+
- The REST API approach provides a flexible and scalable way to enforce
168+
AuthZ decisions across different frontend applications.
169+
170+
- It allows for real-time updates to permissions, as the frontend can
171+
query the API as needed.
172+
173+
- The batch query and caching mechanisms help mitigate performance
174+
concerns, ensuring that the user experience remains smooth.
175+
176+
- Frontend developers will need to implement the necessary logic to
177+
interact with the REST API and enforce AuthZ decisions.
178+
179+
- The approach is adaptable to various frontend architectures,
180+
including MFEs and mobile apps, making it a versatile solution for
181+
the Open edX platform.
182+
183+
Rejected Alternatives
184+
***********************
185+
186+
- Embedding AuthZ data in JWT tokens: As discussed in `0003-jwt-usage`,
187+
embedding AuthZ data in JWT tokens can lead to large token sizes and
188+
stale permissions, in addition to having to re-implement Casbin model
189+
logic in the frontend.
190+
191+
- Depending solely on backend enforcement on resource endpoints:
192+
Relying solely on backend enforcement can lead to a poor user
193+
experience, as users may see UI elements they cannot interact with,
194+
leading to confusion and frustration.
195+
196+
References
197+
************
198+
199+
- `Open edX REST API Conventions
200+
<https://openedx.atlassian.net/wiki/spaces/AC/pages/18350757/Open+edX+REST+API+Conventions>`_

0 commit comments

Comments
 (0)