Skip to content

fix(registry): cache existing DB object on subset re-registration to preserve owner field#5971

Open
skamenan7 wants to merge 4 commits into
ogx-ai:mainfrom
skamenan7:feat/5906-clawpatch-code-audit-findings
Open

fix(registry): cache existing DB object on subset re-registration to preserve owner field#5971
skamenan7 wants to merge 4 commits into
ogx-ai:mainfrom
skamenan7:feat/5906-clawpatch-code-audit-findings

Conversation

@skamenan7
Copy link
Copy Markdown
Contributor

@skamenan7 skamenan7 commented May 27, 2026

CachedDiskDistributionRegistry.register() was unconditionally caching the incoming obj after any successful super().register() call. The parent class has two success paths: new registration and subset re-registration (a deliberate no-op). The cache layer wasn't distinguishing between them, so on a subset re-registration it'd write the incoming partial object into the cache — diverging silently from the DB.

On every server restart, config-provided objects re-register without owner. The no-op path fires, the cache ends up holding objects missing owner, and subsequent cache hits return incomplete data with no error or warning.

Fix: fetch the existing DB object before calling super().register(). If it's non-None (subset re-registration), cache it instead of the incoming partial object.

Test plan

uv run pytest tests/unit/registry/test_registry.py -x --tb=short -q

New test: test_cached_registry_preserves_owner_on_subset_reregistration — registers a full object with owner, re-registers a config-provided subset without owner, asserts both get_cached() and get() return the full object with owner intact.

Breaking changes

None.

Closes #5946

Part of #5906 issues

…preserve owner field

CachedDiskDistributionRegistry.register() was caching the incoming partial
config object on subset re-registration instead of the full DB object.  On
every server restart, config-provided objects re-register without owner set,
causing the cache to drop the owner field silently.  Under the default ABAC
policy (ResourceIsUnowned), a resource with owner=None in the cache appears
unowned, which can grant broader access than intended.  The DB was always
correct; only the in-memory cache view was wrong.

Fix: fetch the existing DB object before calling super().register().  On
success, cache existing_obj when it exists (re-registration no-op path) or
the incoming obj when it does not (first-time registration path).

The super().get() DB read is intentional: in multi-worker deployments each
process has its own in-memory cache, so reading from the DB directly is
required to get the authoritative stored object regardless of whether this
worker's cache was warmed by _ensure_initialized().

Also move inline User imports from two test bodies to module level, and add
an explicit get_cached() assertion to test_cached_registry_updates to cover
the else-obj branch of the new ternary (first-time registration).

Closes: ogx-ai#5946
Relates-to: ogx-ai#5906
Signed-off-by: skamenan7 <skamenan@redhat.com>
@skamenan7 skamenan7 force-pushed the feat/5906-clawpatch-code-audit-findings branch from bd93752 to 9fc2a18 Compare May 27, 2026 18:04
@skamenan7 skamenan7 marked this pull request as ready for review May 27, 2026 18:17
Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 4 additional findings.

Open in Devin Review

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: CachedDiskDistributionRegistry caches incomplete object on subset re-registration, silently dropping owner field

1 participant