Skip to content

feat(starter): wire host TaskAuthorizationProvider into the request handler - #75

Merged
Zhoujie628 merged 1 commit into
project-openan:mainfrom
tangzhiqiang:main
Sep 15, 2026
Merged

Zhoujie628 merged 1 commit into
project-openan:mainfrom
tangzhiqiang:main

Conversation

@tangzhiqiang

Copy link
Copy Markdown
Contributor

What changed

Exposes the A2A Java SDK's operation-level authorization SPI in the Spring Boot starter. When a
TaskAuthorizationProvider bean is present, the autoconfigured requestHandler is wrapped with the
SDK's AuthorizationRequestHandlerDecorator, so host-side validation runs before the agent
executor is invoked:

Guard Covers
checkCreate message:send, message:stream (new task creation)
checkRead / checkWrite task query/list, cancel, subscribe
recordOwnership / isTaskRecorded task ownership tracking
  • Rejections surface as a standard A2A error envelope: checkCreate returning false maps to a
    task-not-found error, while throwing a more specific A2AError subclass carries a custom reason.
  • The decorator carries CDI Instance fields like the delegate, so it also stays behind the
    SpringCompatibleRequestHandler facade.
  • The provider is resolved through ObjectProvider, so without such a bean the server is
    unchanged
    — no decorator is wired at all.

Why

Hosts receiving A2A traffic (e.g. a workbench behind an MSB gateway) need a business-owned
validation point before the agent executor runs. The secondary-authentication specification requires
every provider-side call to be validated against signature headers
(app-id / timestamp / sign-alg / sign / signature) before business execution. A2AController
already places all request headers into the ServerCallContext state, so a provider implementation
reads them directly from the context and applies its validation steps.

Breaking changes

None. The new constructor parameter is an ObjectProvider, and the requestHandler bean stays
@ConditionalOnMissingBean, so an explicitly declared handler still wins.

Test results

mvn -B clean verify -pl workflow-engine,spring-boot-starter -am
  • spring-boot-starter — A2AAutoConfigurationTest: 23 tests, 0 failures, 0 errors
    • new taskAuthorizationProviderRejectionRunsBeforeTheAgentExecutor — asserts the executor is
      never reached (executorRuns == 0) and a TaskNotFoundError is thrown
    • new requestHandlerIsCreatedWithoutAnAuthorizationProvider — asserts the handler still assembles
      with no provider present
  • workflow-engine — module build green
mvn -B -pl samples -am verify

Local note (not a regression): on the contributor's Windows machine the samples reactor fails with
PortInUseException: Port 62478 is already in use (2 failures / 4 errors in SpringSpnDemoE2ETest).
The identical failure — same port, same counts — reproduces on the pristine 6b1c2ec baseline
without this commit, so it is a local port-binding issue, not something this change introduces.
CI (ubuntu-latest) is the authoritative gate for the samples module.

Docs

docs/en/API_REFERENCE.md and docs/zh/API_REFERENCE.md are updated in the same commit (zh/en kept
in sync), documenting the requestHandler behaviour plus a usage example.

Related issues

No tracking issue exists for this change (searched the issue tracker for TaskAuthorizationProvider
and authorization).

@tangzhiqiang
tangzhiqiang requested a review from a team as a code owner September 15, 2026 11:59
…andler

Hosts receiving A2A traffic (e.g. a workbench behind an MSB gateway) need a
business-owned validation point before the agent executor runs. The A2A Java
SDK already ships an operation-level authorization SPI; this exposes it in
the starter: when a TaskAuthorizationProvider bean is present, the
autoconfigured request handler wraps the default handler with the SDK's
AuthorizationRequestHandlerDecorator so checkCreate guards message
send/stream, checkRead/checkWrite guard task query, cancel, and subscribe,
and rejections surface as standard A2A error envelopes. The decorator also
carries CDI Instance fields, so it stays behind the
SpringCompatibleRequestHandler facade like the delegate. Without such a
bean the server is unchanged.

Concrete use case: secondary authentication specifications require every
provider-side call to be validated against signature headers
(app-id/timestamp/sign-alg/sign/signature) before business execution. The
A2AController already places all request headers into the ServerCallContext
state, so a provider implementation reads them directly from the context
and applies its validation steps.

Includes context tests proving a rejecting provider stops the request
before the executor and that the handler still assembles without one,
plus API reference documentation (zh/en) with a usage example.

Signed-off-by: tangzhiqiang <23572557+tangzhiqiang@users.noreply.github.com>
@Zhoujie628
Zhoujie628 merged commit 714da3c into project-openan:main Sep 15, 2026
3 checks passed
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.

2 participants