Skip to content

feat(a2a): add optional Bearer auth support for JWT-protected agents - #78

Open
nemerna wants to merge 5 commits into
RHEcosystemAppEng:mainfrom
nemerna:feat/a2a-bearer-auth
Open

feat(a2a): add optional Bearer auth support for JWT-protected agents#78
nemerna wants to merge 5 commits into
RHEcosystemAppEng:mainfrom
nemerna:feat/a2a-bearer-auth

Conversation

@nemerna

@nemerna nemerna commented Aug 18, 2026

Copy link
Copy Markdown

Summary

Adds optional Bearer auth support to the A2A Harbor adapter for JWT-protected agents, plus TLS/blocking config fixes and pipeline wiring — all backward compatible with existing no-auth agents.

Changes

  • A2AAgent: new optional auth_token (+ AGENT_AUTH_TOKEN env fallback), blocking, and verify_ssl kwargs; verify_ssl defaults to False to match prior hardcoded behavior
  • message/send payload now sends configuration.blocking and explicit "kind": "text" parts
  • Konflux + monitoring Tekton tasks: optional agent-auth-token-secret param (default a2a-agent-credentials) sourced via secretKeyRef, forwarded into the generated Harbor config only when set
  • Docs + secrets template updated for the new secret

Test plan

  • pytest tests/test_a2a_adapter_auth.py tests/test_a2a_adapter_config.py — 15/15 pass
  • ruff check — clean
  • Pipeline YAML validated with yaml.safe_load
  • [ x] End-to-end verification against a real JWT-protected agent in the OCP test environment

Related

A2AAgent accepts auth_token kwargs and AGENT_AUTH_TOKEN env, sending
Authorization: Bearer on JSON-RPC requests. Backward compatible when unset.

Adds unit tests and declares aiohttp as a runtime dependency (already used
by the adapter). Harbor is listed under dev deps for test BaseAgent wiring.
Three related fixes surfaced while running A2AAgent against a real
JWT-protected, self-signed-cert A2A server (google-lightspeed-agent):

- message/send requests omitted configuration.blocking. Some A2A
  servers return before the agent has finished processing when this
  is unset, so the caller gets back an empty/partial result even
  though the agent later completes successfully. Now sent as
  configuration.blocking, defaulting to True (synchronous), and
  overridable via the new `blocking` kwarg.

- Text message parts were sent as {"text": instruction}, omitting the
  "kind" discriminator from the A2A Part schema. Now sent as
  {"kind": "text", "text": instruction}.

- TLS verification was hardcoded to ssl=False (always skipped) in
  _send_request. This is now configurable via a `verify_ssl` kwarg
  (default True, i.e. secure by default), so users only opt out of
  verification for endpoints with self-signed/internal certificates
  instead of it being silently disabled for everyone.
…auth into pipeline

verify_ssl now defaults to False again (matching the previously hardcoded
ssl=False), since most internal OpenShift/Kubernetes Routes use self-signed
certs and the earlier default of True would have broken existing external
A2A endpoints with no way to opt back out.

Also wires the new auth_token kwarg into the Konflux and monitoring Tekton
tasks via an optional agent-auth-token-secret secretKeyRef (default name
a2a-agent-credentials), so JWT-protected agents can be evaluated through
the pipeline, not just via direct Harbor CLI usage. When the secret doesn't
exist, no Authorization header is sent, so existing no-auth pipeline runs
are unaffected.
The harbor package (added as a dev dependency for A2A adapter tests)
requires Python >=3.12 on every published release, but CI was pinned
to 3.11, causing `pip install -e ".[dev]"` to fail with no matching
distribution found. Bumps CI, requires-python, ruff target-version,
and docs/README badges to 3.12 for consistency.
CI runs both ruff check and ruff format --check; this file only
satisfied the former.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant