-
Notifications
You must be signed in to change notification settings - Fork 155
docs(site): extract standalone pages and complete doc structure #977
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
kabir
wants to merge
2
commits into
a2aproject:main
Choose a base branch
from
kabir:docs-site-pr
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| --- | ||
| title: Task Authorization | ||
| description: Per-user access control for A2A tasks — ownership, read/write checks, and user identity across transports. | ||
| layout: page | ||
| --- | ||
|
|
||
| # Task Authorization | ||
|
|
||
| > **Security note:** For multi-user deployments, a `TaskAuthorizationProvider` **must** be configured. Without one, all operations are permitted regardless of authentication — any authenticated user can read, modify, or cancel any task. Production deployments should use a fail-closed ownership policy (deny access when ownership is unknown). | ||
|
|
||
| ## Implementing TaskAuthorizationProvider | ||
|
|
||
| Implement `TaskAuthorizationProvider` to control per-user access: | ||
|
|
||
| ```java | ||
| @ApplicationScoped | ||
| public class MyTaskAuthorizationProvider implements TaskAuthorizationProvider { | ||
|
|
||
| @Override | ||
| public boolean checkRead(ServerCallContext context, String taskId, TaskOperation op) { | ||
| return isOwner(context.getUser(), taskId); | ||
| } | ||
|
|
||
| @Override | ||
| public boolean checkWrite(ServerCallContext context, String taskId, TaskOperation op) { | ||
| return isOwner(context.getUser(), taskId); | ||
| } | ||
|
|
||
| @Override | ||
| public boolean checkCreate(ServerCallContext context, TaskOperation op) { | ||
| return context.getUser() != null && context.getUser().isAuthenticated(); | ||
| } | ||
|
|
||
| @Override | ||
| public boolean isTaskRecorded(String taskId) { | ||
| return ownershipStore.contains(taskId); | ||
| } | ||
|
|
||
| @Override | ||
| public void recordOwnership(ServerCallContext context, String taskId, TaskOperation op) { | ||
| if (context.getUser() != null) { | ||
| ownershipStore.put(taskId, context.getUser().getUsername()); | ||
| } | ||
| } | ||
|
kabir marked this conversation as resolved.
|
||
| } | ||
| ``` | ||
|
|
||
| The SDK discovers the bean via CDI automatically — no additional wiring needed. | ||
|
|
||
| > **Note:** When task authorization is required, always obtain `RequestHandler` through CDI injection. Manual instantiation via `DefaultRequestHandler.create()` bypasses the `AuthorizationRequestHandlerDecorator` and all authorization checks. | ||
|
|
||
| ## User Identity in ServerCallContext | ||
|
|
||
| Authorization decisions rely on `context.getUser()` returning the authenticated user. How the user is populated depends on the transport: | ||
|
|
||
| - **JSON-RPC and REST**: The Quarkus route handler extracts the user from the Vert.x routing context (`rc.userContext()`) and sets it on `ServerCallContext` directly. | ||
| - **gRPC**: The reference server includes a `QuarkusCallContextFactory` CDI bean that injects the Quarkus `SecurityIdentity` and maps it to the `ServerCallContext` `User`. This happens automatically when using the reference gRPC module. If you provide your own `CallContextFactory`, you are responsible for populating the user. | ||
|
|
||
| ## Authorization Checks | ||
|
|
||
| | Operation | Authorization check | | ||
| |-----------|---------------------| | ||
| | `getTask`, `subscribeToTask`, `getTaskPushNotificationConfig`, `listTaskPushNotificationConfigs` | `checkRead` | | ||
| | `cancelTask`, `createTaskPushNotificationConfig`, `deleteTaskPushNotificationConfig` | `checkWrite` | | ||
| | `messageSend` / `messageSendStream` (existing task) | `checkWrite` | | ||
| | `messageSend` / `messageSendStream` (new task) | `checkCreate`, then `recordOwnership` | | ||
| | `listTasks` | `checkRead` per task | | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,120 @@ | ||
| --- | ||
| title: Bill of Materials (BOM) | ||
| description: Dependency management BOMs for the A2A Java SDK — SDK, Extras, and Reference BOMs. | ||
| layout: page | ||
| --- | ||
|
|
||
| # Bill of Materials (BOM) | ||
|
|
||
| The A2A Java SDK provides three BOMs for different use cases, so you can manage dependency versions in one place. | ||
|
|
||
| ## BOM Modules | ||
|
|
||
| ### SDK BOM | ||
|
|
||
| **Artifact:** `org.a2aproject.sdk:a2a-java-sdk-bom` | ||
|
|
||
| Includes all A2A SDK core modules (spec, server, client, transport), core third-party dependencies, Jakarta APIs, and test utilities. | ||
|
|
||
| **Use this BOM when:** Building A2A agents with any framework (Quarkus, Spring Boot, vanilla Java, etc.) | ||
|
|
||
| ### Extras BOM | ||
|
|
||
| **Artifact:** `org.a2aproject.sdk:a2a-java-sdk-extras-bom` | ||
|
|
||
| Includes everything from the SDK BOM plus server-side enhancement modules (database persistence, distributed queue management, etc.). | ||
|
|
||
| **Use this BOM when:** Building production A2A servers needing advanced server-side features beyond the core SDK. | ||
|
|
||
| ### Reference BOM | ||
|
|
||
| **Artifact:** `org.a2aproject.sdk:a2a-java-sdk-reference-bom` | ||
|
|
||
| Includes everything from the SDK BOM plus the Quarkus BOM (complete Quarkus platform), A2A reference implementation modules, and the TCK module for testing. | ||
|
|
||
| **Use this BOM when:** Building Quarkus-based A2A agents or reference implementations. | ||
|
|
||
| ## Usage | ||
|
|
||
| ### SDK BOM (Any Framework) | ||
|
|
||
| ```xml | ||
| <dependencyManagement> | ||
| <dependencies> | ||
| <dependency> | ||
| <groupId>org.a2aproject.sdk</groupId> | ||
| <artifactId>a2a-java-sdk-bom</artifactId> | ||
| <version>$\{org.a2aproject.sdk.version}</version> | ||
| <type>pom</type> | ||
| <scope>import</scope> | ||
| </dependency> | ||
| </dependencies> | ||
| </dependencyManagement> | ||
|
|
||
| <dependencies> | ||
| <!-- No version needed - managed by BOM --> | ||
| <dependency> | ||
| <groupId>org.a2aproject.sdk</groupId> | ||
| <artifactId>a2a-java-sdk-server-common</artifactId> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>org.a2aproject.sdk</groupId> | ||
| <artifactId>a2a-java-sdk-transport-jsonrpc</artifactId> | ||
| </dependency> | ||
| </dependencies> | ||
| ``` | ||
|
|
||
| ### Extras BOM (Database Persistence, Distributed Deployments) | ||
|
|
||
| ```xml | ||
| <dependencyManagement> | ||
| <dependencies> | ||
| <dependency> | ||
| <groupId>org.a2aproject.sdk</groupId> | ||
| <artifactId>a2a-java-sdk-extras-bom</artifactId> | ||
| <version>$\{org.a2aproject.sdk.version}</version> | ||
| <type>pom</type> | ||
| <scope>import</scope> | ||
| </dependency> | ||
| </dependencies> | ||
| </dependencyManagement> | ||
|
|
||
| <dependencies> | ||
| <dependency> | ||
| <groupId>org.a2aproject.sdk</groupId> | ||
| <artifactId>a2a-java-sdk-server-common</artifactId> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>org.a2aproject.sdk</groupId> | ||
| <artifactId>a2a-java-extras-task-store-database-jpa</artifactId> | ||
| </dependency> | ||
| </dependencies> | ||
| ``` | ||
|
|
||
| ### Reference BOM (Quarkus) | ||
|
|
||
| ```xml | ||
| <dependencyManagement> | ||
| <dependencies> | ||
| <dependency> | ||
| <groupId>org.a2aproject.sdk</groupId> | ||
| <artifactId>a2a-java-sdk-reference-bom</artifactId> | ||
| <version>$\{org.a2aproject.sdk.version}</version> | ||
| <type>pom</type> | ||
| <scope>import</scope> | ||
| </dependency> | ||
| </dependencies> | ||
| </dependencyManagement> | ||
|
|
||
| <dependencies> | ||
| <!-- A2A SDK and Quarkus versions both managed --> | ||
| <dependency> | ||
| <groupId>org.a2aproject.sdk</groupId> | ||
| <artifactId>a2a-java-sdk-reference-jsonrpc</artifactId> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>io.quarkus</groupId> | ||
| <artifactId>quarkus-arc</artifactId> | ||
| </dependency> | ||
| </dependencies> | ||
| ``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,124 @@ | ||
| --- | ||
| title: Backward Compatibility | ||
| description: Serve v1.0 and v0.3 A2A protocol versions simultaneously — multi-version modules, version routing, and v0.3 client support. | ||
| layout: page | ||
| --- | ||
|
|
||
| # Backward Compatibility with v0.3 | ||
|
|
||
| Add compat modules alongside v1.0 modules to serve both protocol versions simultaneously. No changes to your `AgentExecutor` are needed. | ||
|
|
||
| ## Server: Multi-Version Module (recommended) | ||
|
|
||
| ```xml | ||
| <!-- JSON-RPC with automatic v1.0 + v0.3 routing --> | ||
| <dependency> | ||
| <groupId>org.a2aproject.sdk</groupId> | ||
| <artifactId>a2a-java-sdk-reference-multiversion-jsonrpc</artifactId> | ||
| <version>$\{org.a2aproject.sdk.version}</version> | ||
| </dependency> | ||
|
|
||
| <!-- REST with automatic v1.0 + v0.3 routing --> | ||
| <dependency> | ||
| <groupId>org.a2aproject.sdk</groupId> | ||
| <artifactId>a2a-java-sdk-reference-multiversion-rest</artifactId> | ||
| <version>$\{org.a2aproject.sdk.version}</version> | ||
| </dependency> | ||
| ``` | ||
|
|
||
| ## Server: Individual Compat Modules | ||
|
|
||
| ```xml | ||
| <!-- v0.3 JSON-RPC support --> | ||
| <dependency> | ||
| <groupId>org.a2aproject.sdk</groupId> | ||
| <artifactId>a2a-java-sdk-compat-0.3-reference-jsonrpc</artifactId> | ||
| <version>$\{org.a2aproject.sdk.version}</version> | ||
| </dependency> | ||
|
|
||
| <!-- v0.3 REST support --> | ||
| <dependency> | ||
| <groupId>org.a2aproject.sdk</groupId> | ||
| <artifactId>a2a-java-sdk-compat-0.3-reference-rest</artifactId> | ||
| <version>$\{org.a2aproject.sdk.version}</version> | ||
| </dependency> | ||
|
|
||
| <!-- v0.3 gRPC support --> | ||
| <dependency> | ||
| <groupId>org.a2aproject.sdk</groupId> | ||
| <artifactId>a2a-java-sdk-compat-0.3-reference-grpc</artifactId> | ||
| <version>$\{org.a2aproject.sdk.version}</version> | ||
| </dependency> | ||
| ``` | ||
|
|
||
| ## How Version Routing Works | ||
|
|
||
| - **JSON-RPC and REST**: When serving multiple protocol versions, version routing inspects the `A2A-Version` HTTP header on each request. If the header is `"1.0"`, the request is routed to the v1.0 handler. If it is `"0.3"` or absent, the request is routed to the v0.3 handler. | ||
| - **gRPC**: Version dispatch is implicit — v0.3 clients use the `a2a.v1` protobuf package and v1.0 clients use `lf.a2a.v1`, so requests are routed to the correct service automatically. | ||
| - **Agent card**: When both v1.0 and v0.3 are enabled, the v1.0 `AgentCard` takes precedence and is served at `/.well-known/agent-card.json`. The v0.3 `AgentCard_v0_3` is ignored. If only v0.3 is enabled, the v0.3 agent card is used. If only v1.0 is enabled, the v1.0 agent card is used as-is. | ||
|
|
||
| ## Making the v1.0 Agent Card Compatible with v0.3 Clients | ||
|
|
||
| When serving both protocol versions, you need to ensure the v1.0 agent card contains fields that v0.3 clients expect. Existing v0.3 client implementations (in any language) look for `url`, `preferredTransport`, and `additionalInterfaces` with `transport`/`url` entries — fields that don't exist in the v1.0 format by default. | ||
|
|
||
| To make your v1.0 `AgentCard` parsable by v0.3 clients, set these fields on the builder: | ||
|
|
||
| ```java | ||
| AgentCard card = AgentCard.builder() | ||
| .name("My Agent") | ||
| // ... other v1.0 fields ... | ||
| .supportedInterfaces(List.of( | ||
| new AgentInterface("jsonrpc", "http://localhost:9999"))) | ||
| // v0.3 backward-compatibility fields: | ||
| .url("http://localhost:9999") | ||
| .preferredTransport("jsonrpc") | ||
| .additionalInterfaces(List.of( | ||
| new Legacy_0_3_AgentInterface("jsonrpc", "http://localhost:9999"))) | ||
| .build(); | ||
| ``` | ||
|
|
||
| The two interface lists serve different clients: | ||
|
|
||
| - `supportedInterfaces` — used by **v1.0 clients** to discover endpoints (uses `AgentInterface` with `protocolBinding`/`url`/`tenant` fields) | ||
| - `additionalInterfaces` — used by **v0.3 clients** to discover endpoints (uses `Legacy_0_3_AgentInterface` with v0.3 field names: `transport`/`url`) | ||
| - `url` and `preferredTransport` — top-level fields that v0.3 clients use to discover the primary endpoint | ||
|
|
||
| ## Push Notification Behavior | ||
|
|
||
| Push notification payloads are automatically formatted to match the protocol version used when the push notification configuration was registered. When a v0.3 client registers a push notification configuration (via any transport), the server records the protocol version alongside the configuration. When a notification is later sent to that webhook, the payload is formatted as a v0.3 Task object. Configurations registered by v1.0 clients receive v1.0 `StreamResponse` payloads as usual. This happens transparently — no additional configuration is needed beyond adding the compat reference module. | ||
|
|
||
| ## Client: Communicating with v0.3 Agents | ||
|
|
||
| Use `Client_v0_3` to communicate with agents that only support protocol v0.3: | ||
|
|
||
| ```xml | ||
| <dependency> | ||
| <groupId>org.a2aproject.sdk</groupId> | ||
| <artifactId>a2a-java-sdk-compat-0.3-client</artifactId> | ||
| <version>$\{org.a2aproject.sdk.version}</version> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>org.a2aproject.sdk</groupId> | ||
| <artifactId>a2a-java-sdk-compat-0.3-client-transport-jsonrpc</artifactId> | ||
| <version>$\{org.a2aproject.sdk.version}</version> | ||
| </dependency> | ||
| ``` | ||
|
|
||
| gRPC and REST transports are also available: | ||
| - `a2a-java-sdk-compat-0.3-client-transport-grpc` | ||
| - `a2a-java-sdk-compat-0.3-client-transport-rest` | ||
|
|
||
| ```java | ||
| AgentCard card = A2ACardResolver.builder().baseUrl("http://localhost:1234") | ||
| .build().getAgentCard(); | ||
|
|
||
| AgentInterface v03Interface = card.supportedInterfaces().stream() | ||
| .filter(i -> A2AProtocol_v0_3.PROTOCOL_VERSION.equals(i.protocolVersion())) | ||
| .findFirst().orElseThrow(); | ||
|
|
||
| Client_v0_3 client = ClientBuilder_v0_3.forUrl(v03Interface.url()) | ||
| .withTransport(JSONRPCTransport_v0_3.class, new JSONRPCTransportConfigBuilder_v0_3()) | ||
| .build(); | ||
| ``` | ||
|
|
||
| **Note:** `Client_v0_3` exposes only operations available in protocol v0.3. For example, `listTasks()` is not available (it was added in v1.0). Return types use v0.3 domain objects from the `org.a2aproject.sdk.compat03.spec` package. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.