Wave 2: Epics: Enable granular PATs for Epics REST endpoints
## Summary Implement granular Personal Access Token (PAT) permissions for Epics REST API endpoints, following GitLab's authorization conventions. ## Endpoints Modified - `GET /groups/:id/epics` → `read_epic` - `GET /groups/:id/-/epics` → `read_epic` - `GET /groups/:id/epics/:epic_iid` → `read_epic` - `GET /groups/:id/-/epics/:epic_iid` → `read_epic` - `POST /groups/:id/epics` → `create_epic` - `POST /groups/:id/-/epics` → `create_epic` - `PUT /groups/:id/epics/:epic_iid` → `update_epic` - `PUT /groups/:id/-/epics/:epic_iid` → `update_epic` - `DELETE /groups/:id/epics/:epic_iid` → `delete_epic` - `DELETE /groups/:id/-/epics/:epic_iid` → `delete_epic` ## Permissions Created - `read_epic` – Grants the ability to read epics - `create_epic` – Grants the ability to create epics - `update_epic` – Grants the ability to update epics - `delete_epic` – Grants the ability to delete epics ### Files Created - `config/authz/permissions/epic/read.yml` - `config/authz/permissions/epic/create.yml` - `config/authz/permissions/epic/update.yml` - `config/authz/permissions/epic/delete.yml` - `config/authz/permissions/epic/_metadata.yml` ## Permission Groups Created - `read_epic` – Grants the ability to read epics - `create_epic` – Grants the ability to create epics - `update_epic` – Grants the ability to update epics - `delete_epic` – Grants the ability to delete epics ### Files Created - `config/authz/permission_groups/assignable_permissions/epic/read.yml` - `config/authz/permission_groups/assignable_permissions/epic/create.yml` - `config/authz/permission_groups/assignable_permissions/epic/update.yml` - `config/authz/permission_groups/assignable_permissions/epic/delete.yml` ## Requirements ### API Analysis Analyze the relevant API file under `lib/api/` and: - Identify all REST API endpoints (GET, POST, PUT, DELETE) - List each endpoint with its HTTP method and route pattern - Note the `feature_category` defined in the file - Determine the boundary type for each endpoint based on route patterns: - `/projects/:id/...` → project boundary - `/groups/:id/...` → group boundary - `/users/:id/...` → user boundary - No prefix → instance boundary ### Permission Design For each endpoint, define permissions using the following conventions: **Naming Pattern:** `action_resource(_subresource)` - Use singular form (e.g. `read_job`, not `read_jobs`) - Preferred actions: `create`, `read`, `update`, `delete`, `push`, `download` - Avoid: `admin_*`, `manage_*`, `access_*` **Permission Granularity Rules:** - List and Show operations → single `read_resource` permission - Nested resources → include parent in the name (e.g. `create_pipeline_schedule_variable`) - Special actions → unique permissions (e.g. `cancel_job`, `retry_job`, `download_artifact`) - Attribute updates → single `update_resource` permission (do not create attribute-specific permissions) ### Permission YAML File ```yaml --- name: <permission_name> description: Grants the ability to <action description> boundaries: - <boundary_type> # project, group, user, or instance ``` ### Permission Group YAML File ```yaml --- name: <permission_name> description: Grants the ability to <action description> boundaries: - <boundary_type> # project, group, user, or instance permissions: - <permission_name> ``` ### Add Authorization Decorators Add the route_setting :authorization decorator immediately before each route definition in the API file: ```ruby route_setting :authorization, permissions: :<permission_name>, boundary_type: :<boundary_type> get ':id/resource' do # endpoint implementation end ``` ### Add Test Coverage In the corresponding spec file under spec/requests/api/, add the following for each endpoint: ```ruby it_behaves_like 'authorizing granular token permissions', :<permission_name> do let(:boundary_object) { <boundary_object> } # project, group, user, or nil for instance let(:user) { <user_variable> } let(:request) do <http_method> api(\"<endpoint_path>\", personal_access_token: pat), params: <params_hash_if_needed> end end ```
task