Skip to content

Capability introspection task + attestation_verifier scope + RBAC error codes #2964

Description

@bokelley

Problem

Today a caller has no way to ask "given my identity and this account, what tasks am I allowed to call and what fields can I modify?" They try a task, catch an error, try another. This is adequate for single-purpose integrations but increasingly awkward as AdCP surfaces multiply (governance, compliance verifiers, multi-tenant sellers, sandbox vs. prod).

It's also a blocking gap for continuous production observability (tracked separately), where the compliance engine needs a narrow, named scope: read + update_media_buy{reporting_webhook} only, nothing else. No standard way to advertise or request that scope exists.

Enforcement of RBAC is correctly a seller-local concern — sellers reject unauthorized requests, full stop. But discovery, naming, and error semantics benefit from standardization.

Proposal

1. Capability introspection task

New task: get_agent_capabilities

Request:

{
  "account": { "account_id": "acc_123" }
  // or { "brand": {...}, "operator": "..." } per account-ref rules
}

Response:

{
  "identity": { "agent_id": "...", "brand": {...}, "operator": "..." },
  "account": { "account_id": "acc_123", "sandbox": false },
  "allowed_tasks": [
    "get_media_buys",
    "get_media_buy_delivery",
    "update_media_buy"
  ],
  "field_scopes": {
    "update_media_buy": ["reporting_webhook"]
  },
  "scope_name": "attestation_verifier",
  "read_only": false
}

field_scopes is an optional per-task allowlist of request fields the caller may set. When present, any field outside the allowlist MUST cause the task to return FIELD_NOT_PERMITTED.

2. Standard named scope: attestation_verifier

Defined as:

  • allowed_tasks: get_media_buys, get_media_buy_delivery, update_media_buy, get_agent_capabilities
  • field_scopes.update_media_buy: ["reporting_webhook"]
  • No create_media_buy, no sync_creatives, no budget/date/cancellation updates

Sellers advertising production-verified readiness MUST support the attestation_verifier scope.

Other named scopes (admin, operator, viewer, governance) are deliberately not standardized — taxonomies vary too much across sellers. Only attestation_verifier is spec-mandated because it binds to a protocol-level flow.

3. RBAC error codes

Add to the standard error taxonomy:

  • PERMISSION_DENIED — generic authz failure (may already exist; confirm)
  • SCOPE_INSUFFICIENT — caller's scope does not include this task
  • READ_ONLY_SCOPE — caller's scope is read-only; mutation rejected
  • FIELD_NOT_PERMITTED — caller's scope does not permit the specified field in this task

What this is not

  • Not a user/role management API. Sellers manage their own IAM.
  • Not enforcement. Sellers enforce locally; this only makes enforcement observable and named.
  • Not a fixed role taxonomy. Only attestation_verifier is named; everything else is seller-specific.

SDK implications (tracked separately)

Both @adcp/client and the Python SDK should fold authorization into the existing account-resolve hook so sellers get RBAC enforcement by default. A single resolveContext function returns {identity, account, authorization}, and the SDK enforces before task dispatch. Not part of this spec issue, but worth flagging the intended SDK shape.

Affected spec files

  • New: docs/capability-discovery/task-reference/get_agent_capabilities.mdx
  • Update: error code taxonomy (location TBD)
  • Update: specification.mdx — add RBAC/scope concept section

Metadata

Metadata

Assignees

No one assigned

    Labels

    claude-triagedIssue has been triaged by the Claude Code triage routine. Remove to re-triage.

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions