---
id: 12296
title: 'KB private owner read-back over OIDC/proxy: key ownership on userId (agentIdentityNodeId is null there)'
state: CLOSED
labels:
  - enhancement
  - ai
  - architecture
assignees:
  - neo-opus-ada
createdAt: '2026-06-01T08:30:27Z'
updatedAt: '2026-06-01T08:36:51Z'
githubUrl: 'https://github.com/neomjs/neo/issues/12296'
author: neo-opus-ada
commentsCount: 1
parentIssue: null
subIssues: []
subIssuesCompleted: 0
subIssuesTotal: 0
blockedBy: []
blocking: []
closedAt: '2026-06-01T08:36:51Z'
---
# KB private owner read-back over OIDC/proxy: key ownership on userId (agentIdentityNodeId is null there)

## Context

The KB read-side visibility work (PR #12290 / #12163) made `private` chunks owner-scoped, owner = the writer's `getAgentIdentityNodeId()`. That identity is populated in stdio / env / gh-cli contexts but **not** over the OIDC/proxy transport a cloud deployment uses (`TransportService.mjs` proxy path + `AuthService.mjs` OIDC path resolve a `userId`/`username`, never an `agentIdentityNodeId`).

## The Problem

In an OIDC/proxy cloud deployment a `private` chunk has **no resolvable owner on read**, so it fails safe — hidden from everyone, **including its writer**. This closes the cross-user leak (the #12163 core threat) but leaves owner read-back inert in exactly the shared-default-tenant cloud scenario #12163 targets: a user cannot read their own `private` content back.

## The Fix

Key per-chunk ownership on **`userId`** (the per-user identity the OIDC/proxy transport *does* populate, and which distinguishes users within a shared tenant) rather than `agentIdentityNodeId`. This requires aligning both sides:

- **Write:** stamp the owner from the authenticated `userId` (with the agent-identity path preserved for local stdio agents, or unified on `userId`).
- **Read:** match the ownership branch in `readVisibilityFilter.mjs` on `normalizeUserId(getUserId())`.
- Re-validate the dockerized integration specs can then exercise owner read-back (an owner-stamped `private` chunk is returned to its writer and to nobody else).

Consider whether `userId` should be the single owner key for both transports, or a fallback chain (`agentIdentityNodeId ?? userId`) — resolve in the PR.

## Acceptance Criteria

- [ ] In an OIDC/proxy deployment, a user can read back their own `private` chunk; another user in the same shared tenant cannot.
- [ ] Local stdio behavior preserved (agent-authored private content still owner-scoped).
- [ ] Dockerized integration coverage for owner read-back over the OIDC transport (currently only the tenant axis is exercised end-to-end).
- [ ] `readVisibilityFilter.mjs` JSDoc + `cloud-deployment/Security.md` updated to drop the "owner read-back not yet available over OIDC" limitation once delivered.

## Related

- Completes the owner-scoping intent of the KB read-side visibility work (the leak-close + fail-safe shipped first; this restores owner read-back over OIDC).

## Timeline

- 2026-06-01T08:30:28Z @neo-opus-ada assigned to @neo-opus-ada
- 2026-06-01T08:30:28Z @neo-opus-ada added the `enhancement` label
- 2026-06-01T08:30:29Z @neo-opus-ada added the `ai` label
- 2026-06-01T08:30:29Z @neo-opus-ada added the `architecture` label
- 2026-06-01T08:31:42Z @neo-opus-ada cross-referenced by PR #12290
### @neo-opus-ada - 2026-06-01T08:36:51Z

Closing — wrong direction (operator, 2026-06-01). This doubled down on the owner-key/visibility primitive that Discussion #12161 already identified as the wrong primitive for the KB. No userId owner-keying belongs in the KB read path: the KB is tenant-repo-based, tenant isolation (#11632) is the correct read model, and tiered entitlement-based access is the real future work in #12161 (post-v13). Closed alongside the #12290 PR + #12163 source ticket.

- 2026-06-01T08:36:52Z @neo-opus-ada closed this issue

