Application-Level Database Isolation

What does this MR do and why?

Adds transparent row-level data isolation for the organization model. Queries for tables with an organization_id column are automatically scoped to Current.organization without any per-callsite changes.

Two pieces of work land together:

  1. Organization-aware primary key lookups — PostgreSQL functions find_<table>_by_id_and_organization_id that make Rails find organization-safe, plus a statement-cache patch that keys the cache on the current organization.

  2. gitlab-database-data_isolation gem — a configurable query transformer with three strategies:

    Strategy Mechanism Overhead Coverage
    arel Patches ActiveRecord::Relation#arel globally ~5 µs SELECT
    default_scope Per-model concern, opt-in medium SELECT
    pg_query Rust extension rewrites serialised SQL ~27 µs SELECT + DML + raw SQL

    All three strategies are wired up intentionally so each can be exercised in tests. Arel is active in production; switching to another strategy requires only changing config.strategy — no redeploy needed.

Notes for reviewers

Bypassing isolation — wrap with:

Gitlab::Database::DataIsolation::ScopeHelper.without_data_isolation { ... }

Rust extension — not compiled by bundle install for PATH gems; build once with:

cd gems/gitlab-database-data_isolation && bundle exec rake compile

Zeitwerk fixconfig/initializers/0_load_gitlab_database.rb explicitly loads lib/gitlab/database.rb because the gem opens Gitlab::Database during Bundler.require, preventing Zeitwerk from autoloading it.

References

How to set up and validate locally

TBD

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.

Merge request reports

Loading