Skip to content

Name-based identity takeover is reachable through at least three independent paths — the invariant belongs at the identity layer #314

Description

@khaliqgant

This is a parent issue, not a fix. It proposes no implementation and adds no new evidence. It exists to state a claim that none of the child issues can state on their own. Do not implement this issue; implement its children.

The claim

Presenting an agent name you do not own can yield a working credential for that agent's existing record. Three independent code paths reach that outcome today, and each was found separately.

Each child issue reads as "this one call is unsafe". Together they say something different: there is no invariant at the identity layer, and each path is enforcing — or failing to enforce — its own local rule.

The three paths

# path mechanism
#310 PATCH /v1/agents/:name workspace-key-only, shallow-merges caller metadata onto any agent, so metadata.identity_key can be planted and the admission gate then satisfied with the caller's own proof. POST /agents/:name/rotate-token reaches the same outcome in one step.
#311 SDK registerOrRotate catches the 409 and calls agents.get + agents.rotateToken. The name string alone is sufficient.
#306 engine registerAgentViaNode node-control agent.register reclaims via onConflictDoUpdate with a token_hash overwrite. Demonstrated: the reply returns the incumbent's existing row id with a fresh at_live_ token and evicts the incumbent's token.

Different entry points, different auth surfaces, different owners — same outcome on the same column.

Why this needs to exist as a parent

Fixing three call sites is not the same as establishing an invariant. If each is closed independently:

The question they are all answering is: what must a caller prove before an existing agent's identity is transferred to it? Today the answer is path-dependent, and on at least one path it is "nothing but the name".

What would close this

Not code. An agreed statement of the invariant, and a check that each path enforces it. Something a future registration surface can be held to, and against which the three child fixes can be reviewed for agreement rather than merely for individual correctness.

Children

Related: AgentWorkforce/relay#1438 gates one of the three on the Rust broker's own registration path.

Not in scope

Presence and status reporting (#312, #313). Those made this area hard to reason about but are not identity decisions.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions