Add five Orbit redaction resource types

What does this MR do and why?

Orbit asks GitLab to authorize each node it returns. This MR lets GitLab authorize five more node types. Orbit can then show SBOM occurrences, to-do items, Duo workflows, custom member roles, and AI catalog items. Existing types do not change.

Type Rows that GitLab loads Ability that Orbit sends Who can read a row
sbom_occurrence Sbom::Occurrence read_dependency Reporter and higher on the project, with the dependency scanning license
todo Todo read_todo Own to-dos whose target the owner can read; a to-do hidden only by an expired group SAML session is allowed, as in the product policy
duo_workflow Ai::DuoWorkflows::Workflow read_duo_workflow The invoker, users with Duo on the project for pipeline flows, compliance reviewers for non-chat flows
member_role MemberRole.non_admin read_member_role Members of the group, or each user for instance roles, with the custom roles license
ai_catalog_item Ai::Catalog::Item.not_deleted read_ai_catalog_item Public items, restricted items in the hierarchy, private items for project members

Each type uses the product policy. Admin member roles and soft-deleted catalog items are not loaded (redaction_service.rb#L69-72). The policies allow them, but the roles finder and the catalog finders hide them.

References

Screenshots or screen recordings

Before After
Not applicable, no UI change.

How to set up and validate locally

  1. Run bin/rspec ee/spec/services/ee/authz/redaction_service_spec.rb spec/services/authz/redaction_service_spec.rb.
  2. In a Rails console, call Authz::RedactionService.new(user:, resources_by_type: { 'todo' => { 'ids' => ids, 'ability' => 'read_todo' } }, source: 'test').execute with 1 id and with 100 ids. The statement count is the same for both.
Local results

The specs prove these query counts:

  • For each type, 3 rows under one parent run the same queries as 1 row.
  • For sbom_occurrence, member_role, and namespace-level duo_workflow, rows under 3 root groups run the same queries as 1 row.
  • For project-level duo_workflow and ai_catalog_item, each extra project adds one query, the cascading lock read of duo_features_enabled. The Duo and catalog license checks are not stubbed. The per-user allowed_to_use? check is stubbed.
  • A to-do adds queries for each new target project, and it loads the target with its API preloads. A to-do on a commit loads the commit from Gitaly for each row.

Duo workflow deletes reach the lake correctly on master; checked on VM-2. With the master table definition, the delete record of a workflow kept its traversal path and creation time. The node left the Orbit graph less than 31 seconds after the delete.

On VM-2 with Orbit v117, POST /api/v4/orbit/query returned the same allowed and denied rows as the Rails policy for each test user, for all five types. Without this MR, GitLab denied every row of the new types.

Not covered: blocked users. The service expects the caller to reject them, and the API does that at authentication.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Michael Angelo Rivera

Merge request reports

Loading
Loading