From 7260064187e9fb63185aa43ac2e47fd1d1f56330 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Thu, 27 Aug 2026 17:20:26 +0200 Subject: [PATCH 1/3] docs: define the authorization catalog API --- .../0021-authorization-definition-api.rst | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 docs/decisions/0021-authorization-definition-api.rst diff --git a/docs/decisions/0021-authorization-definition-api.rst b/docs/decisions/0021-authorization-definition-api.rst new file mode 100644 index 00000000..6cc39059 --- /dev/null +++ b/docs/decisions/0021-authorization-definition-api.rst @@ -0,0 +1,103 @@ +0021: Expose Authorization Definitions Through APIs +#################################################### + +Status +****** + +**Draft** + +Context +******* + +``GET /api/authz/v1/roles/?scope=`` already derives role and permission IDs from the loaded Casbin policy and returns the number of assigned users. However, it does not include the display names, descriptions, categories, icons, or source information defined in the authz schema, nor does it distinguish static roles from user-defined roles. The client applications must keep their own copy of the missing fields, which means that a role contributed by an application still requires frontend changes even when Casbin can already assign and enforce it. + +Decision +******** + +#. Stored definitions +===================== + +The AuthZ API reads static and user-defined roles from the authz model, where both kinds are stored after deployment. It returns roles, permissions, and categories in the format clients need, without exposing the Casbin rows used for permission checks. + +#. Extend the roles endpoint +============================ + +Role listing and assignment screens continue to use the existing scope-based roles endpoint, with each role gaining: + +* the stable role identifier; +* localized display name and description; +* supported scope namespaces; +* complete permission identifiers; +* whether the role is ``static`` or ``user_defined``; and +* whether the caller may edit or delete the definition. + +The response keeps ``user_count`` alongside the new fields, so existing clients that read only ``role``, ``permissions``, and ``user_count`` remain compatible. + +Because a static role is owned by its schema, clients cannot edit or delete it through the user-defined role API. + +#. Permission and category definitions +====================================== + +The API also provides the information needed to display permissions and categories, including: + +* the schema version used by the static definitions; +* permissions with the complete stable ID, separate ``namespace`` and ``name`` fields, translated display fields, categories, supported scopes, and optional icons; and +* normalized permission categories with translated display fields. + +#. Source information +===================== + +Responses may identify a role as ``static`` or ``user_defined`` so clients can tell where it came from. Whether the API should expose more detailed source information, such as the application and schema path behind a static role, remains an open question. + +The standard roles endpoint may return the following object. + +.. code-block:: json + + { + "role": "course_observer", + "display_name": "Course observer", + "permissions": ["courses.view_course"], + "definition_kind": "static", + "user_count": 3 + } + +The exact field name and whether it belongs in the default response remain open API-contract decisions. + +#. Role assignment and localization +=================================== + +Assignment and validation endpoints read the roles available for the requested scope from the authz model instead of a static Python list. When returning those roles, the API translates static display fields into the requested language but keeps role and permission IDs unchanged. + +Consequences +************ + +* Frontend clients can render roles and permissions contributed by applications without its own definition arrays. +* Existing clients keep using the current endpoint and response fields. +* Responses containing translated display fields need locale-aware caching. + +Rejected Alternatives +********************* + +Return raw Casbin policy rows +============================= + +They expose engine-specific namespaces and omit the display fields clients need. + +Keep role and permission metadata in the frontend +================================================= + +Applications would still require frontend releases, and the frontend definitions could drift from the policy enforced by Casbin. + +Replace the existing roles endpoint +=================================== + +The current endpoint already serves scope-based role discovery and assignment screens. Extending it preserves the established entry point and response fields. + +References +********** + +* `ADR 0016`_ +* `ADR 0020`_ + +.. _ADR 0016: 0016-static-and-dynamic-roles.rst +.. _ADR 0020: 0020-authorization-schema-internationalization.rst From 1642f0543cb84b3eef84cc737abe1acccf19d883 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Tue, 1 Sep 2026 18:35:39 +0200 Subject: [PATCH 2/3] docs: render decision section numbers --- docs/decisions/0021-authorization-definition-api.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/decisions/0021-authorization-definition-api.rst b/docs/decisions/0021-authorization-definition-api.rst index 6cc39059..cc9464f6 100644 --- a/docs/decisions/0021-authorization-definition-api.rst +++ b/docs/decisions/0021-authorization-definition-api.rst @@ -14,12 +14,12 @@ Context Decision ******** -#. Stored definitions +1. Stored definitions ===================== The AuthZ API reads static and user-defined roles from the authz model, where both kinds are stored after deployment. It returns roles, permissions, and categories in the format clients need, without exposing the Casbin rows used for permission checks. -#. Extend the roles endpoint +2. Extend the roles endpoint ============================ Role listing and assignment screens continue to use the existing scope-based roles endpoint, with each role gaining: @@ -35,7 +35,7 @@ The response keeps ``user_count`` alongside the new fields, so existing clients Because a static role is owned by its schema, clients cannot edit or delete it through the user-defined role API. -#. Permission and category definitions +3. Permission and category definitions ====================================== The API also provides the information needed to display permissions and categories, including: @@ -44,7 +44,7 @@ The API also provides the information needed to display permissions and categori * permissions with the complete stable ID, separate ``namespace`` and ``name`` fields, translated display fields, categories, supported scopes, and optional icons; and * normalized permission categories with translated display fields. -#. Source information +4. Source information ===================== Responses may identify a role as ``static`` or ``user_defined`` so clients can tell where it came from. Whether the API should expose more detailed source information, such as the application and schema path behind a static role, remains an open question. @@ -63,7 +63,7 @@ The standard roles endpoint may return the following object. The exact field name and whether it belongs in the default response remain open API-contract decisions. -#. Role assignment and localization +5. Role assignment and localization =================================== Assignment and validation endpoints read the roles available for the requested scope from the authz model instead of a static Python list. When returning those roles, the API translates static display fields into the requested language but keeps role and permission IDs unchanged. From 6e933d244ccb1566bd46a5d096eb09985b1cc6de Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Wed, 2 Sep 2026 21:07:53 +0200 Subject: [PATCH 3/3] docs: remove API editability field --- docs/decisions/0021-authorization-definition-api.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/decisions/0021-authorization-definition-api.rst b/docs/decisions/0021-authorization-definition-api.rst index cc9464f6..752503bc 100644 --- a/docs/decisions/0021-authorization-definition-api.rst +++ b/docs/decisions/0021-authorization-definition-api.rst @@ -28,8 +28,7 @@ Role listing and assignment screens continue to use the existing scope-based rol * localized display name and description; * supported scope namespaces; * complete permission identifiers; -* whether the role is ``static`` or ``user_defined``; and -* whether the caller may edit or delete the definition. +* whether the role is ``static`` or ``user_defined``. The response keeps ``user_count`` alongside the new fields, so existing clients that read only ``role``, ``permissions``, and ``user_count`` remain compatible.