Skip to content

is_owner_of single-hop limitation: nested agent trees > 1 level break credential ownership checks #35

@hanwencheng

Description

@hanwencheng

Problem

crates/agentkeys-mock-server/src/auth.rs::is_owner_of only walks one parent_token hop:

SELECT 1 FROM sessions AS child
WHERE child.wallet_address = ?1
  AND child.parent_token IN (
      SELECT token FROM sessions WHERE wallet_address = ?2
  )
LIMIT 1

So if the session tree is master → child → grandchild, calling any of read_credential / store_credential / list_credentials / teardown_agent from the master session against the grandchild wallet returns 403 DENIED, even though the master is the transitive owner.

Why this surfaced now

Codex flagged it on PR #19 (third pass) because the new agentkeys run master-session path always calls /credential/list first when scope = None. So a master invoking agentkeys run <grandchild-wallet> -- ... now fails fast rather than only on the eventual /credential/read (which had the same limit but was never exercised against grandchildren by anyone).

Proper fix (out of scope for #19)

Make is_owner_of recursive — either with an iterative SQL CTE or a small loop in Rust that walks the parent_token chain until a session owned by caller_wallet is found or the chain terminates. Add an integration test that builds a 3-level nested session tree and asserts the master can read/store/list/teardown against the grandchild.

Touches the security model for all four credential handlers, so this needs its own PR and review pass — not a drive-by fix on #19.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions