Skip to content

Add Authorization: Bearer header to A2A client — CIRIS agents require auth as of CIRISAgent#855 (2.9.5) #6

Description

@emooreatx

Summary

CIRIS Agent release/2.9.5 (CIRISAgent#855, commit 2c7a6317e) now requires authentication on the agent's /a2a endpoint. CIRISBench currently POSTs to that endpoint without an Authorization header and will get 401 Unauthorized when targeting a 2.9.5+ agent.

What changed agent-side

  • POST /a2a is gated by FastAPI Depends(require_admin) (accepts SERVICE_ACCOUNT tokens at the same tier as human ADMIN).
  • CORS wildcard origins are rejected at config time.
  • Per-source-IP rate limit (default 60 req/min) + global concurrency cap (default 32) on benchmark.evaluate + tasks/send.
  • The vestigial deferrals/receive, deferrals/resolve, credits/notify methods are deleted from the dispatcher and schemas — they declared an Ed25519-signed peer trust model that the handlers never verified.

The discovery manifest at /.well-known/agent.json advertises the new auth requirement so peers can self-discover:

"auth": {
  "required": true,
  "schemes": ["bearer"],
  "tier": "admin"
}

What CIRISBench needs

CIRISBench's HE-300 / A2A client must send Authorization: Bearer <token> on every POST to /a2a (and any future peer methods). Suggested:

  1. Config surface: add a ciris_agent.service_token config entry to CIRISBench's per-agent connection profile. The token is provisioned per-agent through the agent's existing API auth flow (create a service account, mint a service token, paste into CIRISBench config).
  2. Wire it: the A2A HTTP client should include Authorization: Bearer service:{token} on every JSON-RPC POST.
  3. Failure mode: on 401, surface "agent requires CIRISBench to authenticate — set ciris_agent.service_token". Don't retry without auth.

The agent accepts both formats:

  • Authorization: Bearer service:<service_token_id>:<secret> (service token; recommended for CIRISBench)
  • Authorization: Bearer <admin_user_token> (manual benchmark runs by a human admin)

Why

CIRISAgent#855 — pre-2.9.5 the agent's /a2a was unauthenticated with allow_origins=["*"] + allow_credentials=True. A web page or remote attacker could drive 120-second LLM reasoning bursts at any agent. Per CEG §5.8, HE-300 benchmark outcomes are signed contributions to a per-agent namespace, not anonymous — there's no "anyone can benchmark me" semantics to preserve. CIRISBench is the canonical (and now only) peer that should be calling /a2a.

Forward-compat note

The 2.9.6 LensCore cohort is expected to add new A2A peer methods for lens contributions (per CEG §5.8). Same auth requirement; same Bearer token. Building the config / client wiring now is forward-compatible.

Coordination

Until both sides land, the HE-300 QA harness in CIRISAgent (tools/qa_runner/modules/he300_benchmark_tests.py, custom_handler=cirisbench_agentbeats) will fail with 401 in CI when running against 2.9.5+ agents. Once CIRISBench ships the auth-header client change, we can flip the QA harness to provision a service token per run and pass it through.

Happy to review the client patch — ping when there's a draft.

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions