6.1

Security schemes and in-task authorization

The card declares which credentials an agent accepts, HTTP checks them on every request, and a running task can still stop to ask for an approval.

The planner's last delegation goes to deployer, the only agent in the kit that guards its endpoint. A request without a token gets HTTP 401 before any A2A method runs. A request with the token starts a deploy that stops again, in TASK_STATE_AUTH_REQUIRED, until an operator approves it.

Figure 6.1 follows that credential from the card to the approval. When you finish this section, you can read a card's security fields, send what they ask for, and scope tasks to their owner.

Fig. 6.1one credential, from the card to an in-task approvalflow
From the card to an enforced request and an in-task approval Five steps for the deployer agent. Step one: the card declares a bearer scheme and requires it, and the platform team issues a token outside A2A. Step two: GetExtendedAgentCard without a token gets HTTP 401 with a WWW-Authenticate challenge. Step three: the same call with the token gets the extended card with a rollback skill. Step four: a streamed deploy with the token stops the task in TASK_STATE_AUTH_REQUIRED. Step five: an operator approves at the deployer outside A2A and the task works and completes on the same stream. 1 · THE CARD DECLARES, THE CLIENT OBTAINS 2 · HTTP CHECKS BEFORE ANY A2A METHOD RUNS 3 · THE TASK ASKS FOR MORE, OUTSIDE A2A deployer card securitySchemes: bearer httpAuthSecurityScheme, Bearer securityRequirements: bearer platform team issues the token dpl_test_7c1e4b outside A2A, before any request GetExtendedAgentCard no Authorization header HTTP 401 Unauthorized WWW-Authenticate: Bearer realm="deployer" refused GetExtendedAgentCard Authorization: Bearer dpl_test_7c1e4b 200 OK, extended card one more skill: rollback shown only to authenticated callers accepted SendStreamingMessage Deploy build 2026.10.06-1 to staging, with the token TASK_STATE_AUTH_REQUIRED task ecf2dcb6 waits, stream open an operator must approve deploy operator approves POST /approve/ecf2dcb6 at the deployer, not in A2A TASK_STATE_COMPLETED after TASK_STATE_WORKING on the same stream the approval link resumes
The card names the scheme, HTTP rejects a request without the token before A2A runs, and a running task can still stop for an approval. Read top to bottom, in five steps. From step 2 on, the left box is what the planner sends and the right box is what deployer answers. Grey boxes sit outside A2A. The task id is shortened to 8 characters.

What the card declares

Only the deployer's card carries security fields, so test-runner and code-reviewer accept any caller.

the security fields on the deployer cardjsonFull log
  "securitySchemes": {
    "bearer": {
      "httpAuthSecurityScheme": {
        "description": "A token issued by the platform team.",
        "scheme": "Bearer"
      }
    }
  },
  "securityRequirements": [
    {
      "schemes": {
        "bearer": {
          "list": []
        }
      }
    }
  ],
Cut from the deployer card. The two fields sit between capabilities and defaultInputModes.

Security scheme: one entry in the card's securitySchemes map. The key, here bearer, is a name the agent picks. The value holds exactly one of five variants: apiKeySecurityScheme, httpAuthSecurityScheme, oauth2SecurityScheme, openIdConnectSecurityScheme, or mtlsSecurityScheme.

Security requirement: one entry in securityRequirements. Its schemes map names schemes from securitySchemes, and each name maps to "the required scopes" in a StringList whose only field is list. The deployer names bearer with an empty list, so the token alone is enough.

The §8.5 sample card still says security where the proto says securityRequirements (conflict D6). The migration guide calls the implicit and password flows removed, while the proto keeps both as deprecated (conflict D11), so offer neither.

How credentials travel

The client gets the credential outside A2A and sends it in the headers or metadata of the transport on every A2A request. That header carries a secret, so a production deployment must encrypt its traffic: HTTPS for the HTTP bindings, and TLS for gRPC. The specification recommends TLS 1.3 or later, and the enterprise guide TLS 1.2 or later (conflict D18).

Without it, deployer answers HTTP 401 with a WWW-Authenticate challenge before any A2A method runs, as extended cards and signatures shows.

Authorization scope: a task you cannot see does not exist

Each implementation decides its own authorization logic. The specification fixes how a refusal looks: a server must not reveal that a resource exists when the client has no access to it. So another caller's task gets the same TaskNotFoundError as a task that never existed. The same section lists one case for an authorization error: access to a task that another user created. That error would confirm that the task exists (conflict D36). Answer with the not-found error.

The check runs first: authorization checks must happen before any database query or operation that could leak information. ListTasks must scope its results to the caller even when the request has no filter. The SDKs differ on who the owner is:

ImplementationOwner scopeAnother caller's task
Kitnone, and the deployer needs one shared bearer tokenreturned
a2a-python 1.2.2task stores keyed by the call context's user_name, and every unauthenticated caller has the empty nameTaskNotFoundError
a2a-js 1.3.0tenant and owner in every store, with unknown for an anonymous callerTaskNotFoundError
a2a-java 1.4.0.Finala TaskAuthorizationProvider interface with no implementation in the release, and without one every task operation fails closedTaskNotFoundError
a2a-go 2.6.0the in-memory store records the call's user name, and an empty name makes ListTasks fail with ErrUnauthenticatedErrTaskNotFound once a name is set
a2a-dotnet 1.0.0-preview2none, because the store and the handler carry no principalreturned
a2a-rs a2a-server-lf-v0.5.1none in the stores, and an opt-in RequestAuthorizer sees only the headers and the task idreturned

Without an authentication middleware that fills in the user, every task is visible to every caller.

In-task authorization

In-task authorization: an agent's request for permission partway through a task, through TASK_STATE_AUTH_REQUIRED, which interrupted states follows frame by frame. The kit's POST /approve/<task id> checks no credentials, so anyone who learns the task id can approve. A real approval channel authenticates the operator and records who approved.

A client that is itself an agent can pass the request up a chain of tasks in TASK_STATE_AUTH_REQUIRED. An in-band credential then passes through every agent in the chain. So bind it to the agent that asked, and only that agent can use it.

PR #2081 added §7.6.4 to main on 2026-07-30, after v1.0.1, and no release carries it yet. It says that an agent must not treat the move to TASK_STATE_AUTH_REQUIRED on its own as permission for any operation. A credential obtained there does not authorize later messages unless the implementation, the issuer, or an extension says so. The kit keys each approval by task id, so one approval resumes one deploy, and its bearer check runs on every later request.

A2A protocol 1.0.1 · 3303592 · 2026-05-28 · Edition 2026.10