Skip to content

fix(BA-6955): grant kernel scheduling-history read alongside session read#13000

Closed
jopemachine wants to merge 1 commit into
mainfrom
fix/BA-6955-kernel-history-permission-migration
Closed

fix(BA-6955): grant kernel scheduling-history read alongside session read#13000
jopemachine wants to merge 1 commit into
mainfrom
fix/BA-6955-kernel-history-permission-migration

Conversation

@jopemachine

@jopemachine jopemachine commented Jul 21, 2026

Copy link
Copy Markdown
Member

Resolves #12999 (BA-6955)

Summary

POST /v2/scheduling-history/kernels/scoped/search (and the scopedKernelSchedulingHistories GQL query) is registered with auth_required and its action declares kernel:history as the entity being read, yet every non-superadmin caller — including the owner of the kernel — was rejected, because nothing ever granted kernel:history read:

  • Migration a1c4e7b93f22 mirrored grants from entity_type = 'kernel', which nothing creates (kernels are reached through their owning session), so its SELECT matched zero rows. The empty result also masked the INSERT omitting the NOT NULL permission column.
  • Runtime scope-role creation never included kernel:history either, so even a corrected backfill would have left users created afterwards without access.

Per the scope-chain model in proposals/BEP-1048/permission-check-scope-chain-examples.md §2, the subject of the check is the entity being read, with grants expected at ancestor scopes — so the fix supplies the grants rather than changing the action's entity type:

Half Change Precedent
Existing roles Rewrite the (unreleased) migration to mirror session READ grants, carrying the source permission bits 21159a293dfb and the other migrate-to-rbac backfills
New roles Grant kernel:history READ natively in the user owner, project admin, project member, and domain admin scope roles *_admin_page entries in the same entity_operations() methods
Downgrade Documented no-op — a mirror-based DELETE cannot tell backfilled rows from natively granted ones f2b9a4c7e103

Reading a session is what carries kernel visibility (search_kernel.py authorizes via session), so kernel scheduling history follows the same boundary: it is exactly as visible as the session it belongs to, including domain-scoped session read grants.

Test plan

Verified on a live stack (kernel f53384a7… owned by user@lablup.com):

  • Runtime half: a freshly created user's owner role receives kernel:history read (permission=1) natively, with no migration involved
  • Backfill half: the upgrade SQL inserted 16 mirrored rows; re-running inserted 0 (idempotent, ON CONFLICT DO NOTHING)
  • Owner passes the scoped query end-to-end (GQL v2, same adapter → action → RBAC path as REST)
  • Negative control: deleting the kernel:history rows makes the same owner query fail with NotEnoughPermission; restoring them makes it pass — the check is enforced by exactly these rows
  • Unit tests added for the four entity_operations() changes (tests/unit/manager/data/{user,group,domain}/test_types.py)
  • Responses containing actual history rows — kernel scheduling-history rows are never written in this environment (session history recorded 4 rows for the same session while kernel history stayed empty); unrelated to authorization, tracked separately

🤖 Generated with Claude Code

@github-actions github-actions Bot added the size:M 30~100 LoC label Jul 21, 2026
@github-actions github-actions Bot added comp:manager Related to Manager component require:db-migration Automatically set when alembic migrations are added or updated labels Jul 21, 2026
jopemachine added a commit that referenced this pull request Jul 21, 2026
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…read

The scoped kernel scheduling-history endpoint is registered with auth_required
and its action declares kernel:history as the entity being read, yet every
non-superadmin caller -- including the owner of the kernel -- was rejected,
because nothing ever granted kernel:history read:

- Migration a1c4e7b93f22 mirrored grants from entity_type 'kernel', which
  nothing creates (kernels are reached through their owning session), so its
  SELECT matched zero rows. The empty result also masked the INSERT omitting
  the NOT NULL permission column.
- Runtime scope-role creation never included kernel:history either, so even a
  corrected backfill would have left users created afterwards without access.

Per the BEP-1048 scope-chain model, the subject of the check is the entity
being read, with grants expected at ancestor scopes -- so the fix supplies the
grants rather than changing the action:

- Rewrite the (unreleased) migration to mirror session READ grants, carrying
  the source permission bits. Reading a session is what carries kernel
  visibility, so its history follows the same boundary.
- Make the downgrade a documented no-op: once roles receive the grant natively
  at creation, a mirror-based DELETE cannot tell backfilled rows from native
  ones (same rationale as f2b9a4c7e103).
- Grant kernel:history READ natively in the user owner, project admin, project
  member, and domain admin scope roles, following the *_admin_page precedent.

Verified on a live stack: a freshly created user's role receives kernel:history
read natively; the backfill inserts mirrored rows idempotently; the kernel
owner passes the scoped query while deleting the rows makes the same query
fail with NotEnoughPermission.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jopemachine jopemachine reopened this Jul 21, 2026
@jopemachine
jopemachine force-pushed the fix/BA-6955-kernel-history-permission-migration branch from 8a5bc35 to 4a9e0c2 Compare July 21, 2026 10:37
@github-actions github-actions Bot added size:L 100~500 LoC and removed size:M 30~100 LoC labels Jul 21, 2026
@jopemachine jopemachine changed the title fix(BA-6955): grant kernel scheduling-history reads from session grants fix(BA-6955): grant kernel scheduling-history read alongside session read Jul 21, 2026
@jopemachine

Copy link
Copy Markdown
Member Author

Reopened with a reworked scope. The earlier close comment claimed the migration approach itself was wrong — re-verification against BEP-1048/permission-check-scope-chain-examples.md showed the opposite: the designed model checks the entity being read (kernel:history) at ancestor scopes, so the grant-seeding approach was correct and the EntityType.SESSION change attempted in #13003 violated the design.

What the earlier attempt was actually missing was the runtime half: scope roles created after the backfill also need the grant, following the *_admin_page precedent (f2b9a4c7e103 + native entity_operations() entries). This PR now carries both halves, plus the precedent-mandated no-op downgrade.

@jopemachine

Copy link
Copy Markdown
Member Author

This will be addressed when we introduce virtual scopes and add the permission migration for kernel records. For now, I'll work around the issue by changing the entity type itself to session.

@jopemachine

Copy link
Copy Markdown
Member Author

For the record: the design owner confirmed that kernel-entity permission records are intentionally kept empty, so this PR's grant-seeding approach (backfill + native role-creation grants) contradicts the intended data model and stays closed. The kernel-owner 403 is fixed in #12866 by authorizing the scoped search through session read (EntityType.SESSION), which needs no permission rows.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp:manager Related to Manager component require:db-migration Automatically set when alembic migrations are added or updated size:L 100~500 LoC

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix kernel scheduling-history read permission migration granting nothing

1 participant