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:
- 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).
- Wire it: the A2A HTTP client should include
Authorization: Bearer service:{token} on every JSON-RPC POST.
- 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.
Summary
CIRIS Agent
release/2.9.5(CIRISAgent#855, commit2c7a6317e) now requires authentication on the agent's/a2aendpoint. CIRISBench currently POSTs to that endpoint without anAuthorizationheader and will get 401 Unauthorized when targeting a 2.9.5+ agent.What changed agent-side
/a2ais gated by FastAPIDepends(require_admin)(acceptsSERVICE_ACCOUNTtokens at the same tier as humanADMIN).benchmark.evaluate+tasks/send.deferrals/receive,deferrals/resolve,credits/notifymethods 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.jsonadvertises the new auth requirement so peers can self-discover: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:ciris_agent.service_tokenconfig 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).Authorization: Bearer service:{token}on every JSON-RPC POST.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
/a2awas unauthenticated withallow_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.