Add securityTrackedContextQuota query to OrganizationType

What does this MR do and why?

This MR adds a GraphQL field that shows the tracked security context quota of an organization. The Admin Area UI (#585970) and API clients use it to read the quota limit, the usage, and the remaining capacity.

This field is the organization-level part of the quota API. A follow-up MR adds a quota for each root namespace (see &20475).

Changes

  1. A new GraphQL type Types::Security::TrackedContextQuotaType (SecurityTrackedContextQuota). It has these fields:

    Field Type Description
    limit Int The maximum number of tracked contexts. null when no limit applies.
    usage Int! The number of tracked contexts in use.
    remaining Int The remaining quota. null when no limit applies.
    explicitlySet Boolean! true when the quota is set on the organization. false when the default applies.
  2. A new field securityTrackedContextQuota on OrganizationType (EE extension). It resolves through Security::TrackedContextQuotaService#quota_info. The field is an Experiment, introduced in 19.6.

Authorization

  • The field returns data only to users who can update_organization (administrators and organization owners). Other users who can read the organization get null for this field.
  • Fine-grained tokens use the read_organization permission for the type. The token holder must also be able to update the organization to get data.
  • The field does not check the vulnerabilities_across_contexts feature flag. That flag is on by default, and we plan to remove it.

Example

query {
  organization(id: "gid://gitlab/Organizations::Organization/1") {
    securityTrackedContextQuota {
      limit
      usage
      remaining
      explicitlySet
    }
  }
}

How to set up and validate locally

  1. Set a quota in the Rails console:

    org = Organizations::Organization.first
    Organizations::OrganizationSetting.for(org.id).update!(security_tracked_context_quota: 5)
  2. Run the query above as an organization owner, or as an administrator with Admin Mode on. On GDK without SaaS mode, an unset quota returns limit: null. To see the default quota, unset the quota and run GDK in SaaS mode.

  3. Run the specs:

    bundle exec rspec ee/spec/graphql/types/security/tracked_context_quota_type_spec.rb \
      ee/spec/graphql/ee/types/organizations/organization_type_spec.rb \
      ee/spec/requests/api/graphql/organization/security_tracked_context_quota_spec.rb

MR acceptance checklist

  • New GraphQL type and field, with regenerated doc/api/graphql/reference, the introspection result, and the fine-grained token permissions table
  • Field gated on update_organization
  • Field marked as an Experiment (milestone 19.6)
  • Type, field presence, and request specs

Follow-ups

  • The field description does not say that only administrators and organization owners see data. The Graphql/AuthorizeTypes disable comment says that the parent type authorizes, but the field checks update_organization. The root namespace follow-up MR fixes both.
  • The request spec does not test non-zero usage, an instance administrator who is not an organization member, or the SaaS default quota. The nil quota case relies on SaaS features being off in specs, instead of stubbing gitlab_com_subscriptions. The follow-up MR adds these cases.
  • Query.organizations can select this field for each node. That runs about three queries for each organization (N+1). This is acceptable for the Experiment. #627755 adds batch loading, and #602702 removes the root namespace pluck, before the field leaves Experiment.

Closes #585971 (closed)

Part of &20475 (Tracked Context Quota Management)

Edited by Gregory Havenga

Merge request reports

Loading
Loading