Skip to content

feat(agents): consistent existence-hiding 404 across all agent-registry routes #2106

Description

@hognek

Problem

The agent-registry surface currently leaks existence: an unauthorized caller can distinguish "agent ID does not exist" (404) from "agent ID exists but you do not own it" (403). This affects every route that fetches a registry record, checks it exists, then authorizes.

Affected routes in routes/agent_auth_requests.py:

  • create_scope_request — fetches registry record → 404 on unknown → require_owner_or_admin → 403 on not-owned
  • approve_scope_request — same pattern
  • deny_scope_request — same pattern
  • approve_auth_request (consent approve) — same pattern
  • deny_auth_request (consent deny) — same pattern

The GET /api/agents/registry/{id} route in routes/agent_registry.py already documents "owner or admin; else 404" — it is existence-hiding. The scope-request and consent routes should match that.

Context

PR #1921 added the scope-request flow. During review jaylfc noted the 404-vs-403 pattern and wrote (#1921 (comment)):

The 404-unknown vs 403-not-owner distinction is the file-wide pattern and matches the sibling consent approve/deny, so making only these two routes existence-hiding would introduce a new inconsistency rather than remove one. [...] happy to switch the whole agent-registry surface to existence-hiding 404 as a separate pass if preferred.

The create-path reorder in #1921 moved authz before the scope-vocabulary check, but not before the record-existence check — so the leak remains.

Proposed solution

Make every agent-registry route existence-hiding: return 404 for both "does not exist" and "exists, not yours". The pattern is:

  1. Fetch the registry record (without revealing whether it exists)
  2. Authorize the caller (owner/admin check)
  3. If authz fails → 404 (same as "not found")
  4. Only then proceed with scope validation, grant writes, etc.

The GET /api/agents/registry/{id} route already does this — the scope-request and consent routes should follow the same pattern.

Affected code

  • tinyagentos/routes/agent_auth_requests.py — the scope-request create/approve/deny handlers and the consent approve/deny handlers
  • Tests that assert 403 on not-owned will need to become 404 assertions

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions