DataWarehouse Authorization and Permission

Overview of DataWarehouse access control and user permissions

DataWarehouse uses Django Auth Module with Users, Groups and Permissions that limit operations. On top of that, we have object-level permission, combining Groups with our custom PolicyAuthorizationBackend to distinguish between Public and Internal (Red Hat) data, and also data from retriggered pipelines.

Creating an Account

If you are a Red Hat associate, your account will be created once you have logged in successfully via OIDC for the first time. Otherwise, accounts are currently managed by the CKI team, reachable through cki-project@redhat.com, Red Hat associates can also ping us in the internal Slack channel: #team-kernel-cki.

Consuming the API

The API follows the same permission policies from standard website usage, which will be explained below, other than that, see API auth documentation for information regarding out-of-browser authentication.

Permission Groups

Policies

There are 3 levels of visibility, in DataWarehouse: public, internal and retrigger, each with a DW group associated with read and write permissions. The policies apply to KCIDBCheckouts and Issues, and are propagated to their children, i.e. KCIDBBuild, KCIDBTest, KCIDBTestResults, Artifacts, IssueOccurrences, and IssueRegexes:

  1. public: (read=None,write="policy_public_write")

    Public data allows read operations (GET requests) without authentication, while write operations (POST, PUT, DELETE requests), e.g. who can submit results, require basic permissions, which are granted to members of the policy_public_write DW group.

  2. internal:(read="policy_internal_read",write="policy_internal_write")

    Certain records pertaining to Red Hat data are restricted to internal users with appropriate read and write permissions, which are granted to members of policy_internal_read and policy_internal_write, respectively.

  3. retrigger:(read="policy_retrigger_rw",write="policy_retrigger_rw")

    Users in the policy_retrigger_rw DW group can access and update objects with this policy. This data has a debug nature, and is submitted by the cki-ci-bot’s pipelines, triggered when testing merge requests. This policy is used only by service-accounts, however superusers have the same privileges.

If you are a DataWarehouse contributor, you might want to know that the implementation is based on Django Rest Framework framework of custom permissions, which we’ve used to define our PolicyAuthorizationPermission and PolicyAuthorizationBackend, then applied it to most models’ default queryset subclassing AuthorizedQuerySet.

Triaging permissions for QE Teams

To enable an user to manipulate issues, their occurrences and regexes, in addition to the relevant object-level read/write policy groups, they need to be part of the Triagers DW group, which will grant them permission to read/write operations on those objects.

How to be a member of a DW group?

DataWarehouse admins don’t manage DW groups directly, instead they manage admin/LDAP-group-link, where they assign DW groups:

  • to service-accounts and external users listed as “extra users” in the LDAP-group-link.
  • to users who match an LDAP/Rover query (for Red Hat associates), synced either through LDAP (see LDAP/Rover Group Sync) or through OIDC (see OIDC Group Sync), depending on how the user authenticates.

LDAP/Rover Group Sync

For users authenticating via LDAP, group membership is kept in sync with LDAP/Rover by matching each LDAPGroupLink.filter_query against the LDAP server. This sync happens when the query is created or updated, but also in an hourly cronjob (UpdateLdapGroupMembers). Unlike the OIDC sync described below, this only adds/removes users from the DW groups tied to synced LDAPGroupLinks, leaving any other group membership (e.g. manually assigned groups) untouched.

Nowadays, there are a few ways of granting triaging permissions to a user, in order of preference:

  1. cki-kernel-tests-reviewers group 1: nowadays our preferred, main triaging permission group, handled directly by the kernel Product Owners/Managers.
  2. Team-based permission: granting triaging permissions to all members of an interested QE team, by creating a LDAP group link for the four permission groups mentioned above.
  3. Specific permission groups: for narrower cases, individual/existing Rover groups linked to just a subset of the permission groups.

Team-based permission

Currently, these teams have a LDAP group link granting Triagers, policy_public_write, policy_internal_read and policy_internal_write to all of their members:

Specific permission groups

There are still some users managed manually through narrower Rover groups, each linked to a subset of the DW groups:

Rover Group DW Groups
cki-datawarehouse-public-write public-write
cki-datawarehouse-internal-write internal-write
linux-eng-pe internal-read
bugzilla-redhat internal-read

OIDC Group Sync

When FF_OIDC_ENABLED is on, Red Hat associates authenticate through OIDC (Keycloak) instead of LDAP. In that case, group membership isn’t managed by the LDAP cronjob at all; instead it’s derived from the OIDC access token on every login and on every OIDC session refresh/API request, using OIDCAuthBackend:

  1. Keycloak embeds the user’s Rover/LDAP group CNs (e.g. kernel-qe) in a claim, by default realm_access.roles, configurable through the OIDC_GROUPS_CLAIM setting.
  2. Each CN present in that claim is matched against the CN parsed out of every LDAP group link’s filter_query, and the corresponding DW groups are assigned to the user.
  3. DW groups forced through extra_users on a LDAPGroupLink are also (re-)applied on every sync, since, unlike the LDAP cron sync, the OIDC sync fully replaces the user’s group membership on every login/request rather than merging with it.