Skip to content

Complete mint-site coverage on conversation APIs and land whole-branch review hardening #1935

Description

@serguei-gorokhov

Parent: #1930

What to build

Two halves, deliberately shipped as one story — reviewers should treat the mixed diff as intentional:

Half 1 — mint-site coverage on the conversation APIs. ResolveResourceDependenciesFn now runs in the same chain position on the Anthropic Messages (MessagesBaseController.prepareUpstreamRoute) and Responses (ResponsesController.handleRequestBody) entry points, completing the v1 conversation mint-site coverage (route/feature/deploy sites remain a documented v1 limitation — an app invoked through those surfaces gets no dependency grants in v1).

An e2e suite (ResourceDependencyApiTest) covers the v1 checklist as test cases: the consented flow, required-without-consent failing the call explicitly, optional-without-consent degrading silently (target stays off-limits), withdrawal stopping the run immediately, declaration change invalidating the grant (content binding), public-target grants following the originating user's own reach exactly (pointer semantics), and the audit events carrying app, targets, user and trace id (the grant line also carries access types).

Half 2 — whole-branch review hardening (found by the whole-branch security/review pass; its commit is chronologically adjacent and folds in here):

  • Root-call-only guard semantics. The timing guard threw on every hop that arrives with a per-request key — the normal state for an interceptor's final call back to a declaring app (breaking even the root user request) and for every chained call into one. Resolution is now honestly root-call-only: hops under a per-request key are skipped — callable, just without grants — because the originating user's reach is not evaluable under a key context. Chained composition is recorded as phase-2 machinery.
  • Internal-type ban. The placeholder type segment enforces the validator's vocabulary: ResourceTypes.of() maps internal engine types, so a current-user/credentials/ declaration from a config-file or admin-authored app could otherwise resolve into the user's secret-bearing blobs.
  • Union grants. Two records sharing a target combine rights instead of overwriting each other; malformed concrete paths are caught (unresolvable, never a crash); target permission lookups are batched into one rule-chain walk; consent is checked before any resolution work; the audit's access-type join tolerates null elements. The perRequestReceivers[app] half of the bake — which never propagated on plain chained calls and served no reachable flow — is removed; the grant lives solely in the key's own shared map.

New e2e: a chained call into a declaring app stays callable without receiving grants (the case the old guard broke).

Acceptance criteria

  • Consented flow works on the chat, Anthropic Messages, and Responses entry points; required-without-consent fails the call explicitly (403 + runtime-fail audit line).
  • Optional-without-consent degrades silently; withdrawal stops the run immediately; declaration change invalidates the grant.
  • Public-target grants follow the originating user's own reach exactly (public is not exempt).
  • A chained call into a declaring app stays callable without receiving grants; interceptor-protected declaring apps work on root calls.
  • current-user/credentials/ (internal types) never resolve; records sharing a target combine rights (union), never overwrite.
  • Audit events carry app, targets, user and trace id — verified by content, not just presence; the grant line also carries access types.
  • Full :server:test green on CI Linux (modulo the documented pre-existing Windows-environmental failures that fail identically on pristine development).

Blocked by

#1934

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    • Status
      No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions