Repository navigation
feat: sign in to OAuth agents from the CLI and add a2a auth commands - #130
mykytanetipa wants to merge 1 commit into
Conversation
Calling an OAuth-protected agent meant fetching a token elsewhere and
passing it with --auth until it expired. Agent commands now sign in when
the agent requires it and retry once, with new --timeout contexts after
the sign-in, which has its own 5 minute limit. A stream that already
printed events is not restarted.
--oauth selects auto (default: sign in when a terminal is attached),
cached (stored grants only, for scripts and sandboxed agents) or off.
--oauth-clients takes client registrations as JSON or, in config files,
a list of {authority, client_id, scopes} objects, and is not read from a
discovered .env. --oauth-default-client-id changes or disables the
Client ID Metadata Document used when no registration matches. Grants
are kept in the file store. No OAuth runs when --auth, --svc-param or a
credential helper supplies the Authorization header. Requests to
authorization servers go through the same transport as agent requests,
so --unix-socket and --ca-cert apply to them.
a2a auth login gets a grant without sending a message (--device,
--scope), auth logout revokes and deletes the grants that apply to the
agent, auth list lists them, and auth get shows stored grants next to
credential helper headers. Errors use A2ACLI_ERR_CREDENTIALS_MISSING and
A2ACLI_ERR_AUTH_FAILED, both with exit code 4, as in SPEC Appendix D.
internal/README.md documents where the CLI learns how to sign in, the
sign-in flows, grant storage and refresh, the --oauth flags, client
registrations and the auth commands. The skill tells agents to run with
--oauth cached and to ask the user to run the a2a auth login command
from the error's hint.
Refs #98
| } | ||
| var out []oauth.Grant | ||
| for _, gr := range grants { | ||
| if oauth.ResourceCovers(gr.Key.Resource, target) { |
There was a problem hiding this comment.
card grants are stored under the interface url, so auth logout https://agent.example.com finds nothing when the interface is at /a2a/v1, and it revokes a parent grant shared by sibling agents. let's resolve the card to interface urls like auth login does. let's please also add a test with an agent served under a path
There was a problem hiding this comment.
Fixed in mykytanetipa#6. auth get and auth logout resolve the card and select the grant for the URL plus the card's interface URLs. A parent grant shared with sibling agents is kept, and the output shows the command that removes it. TestAuthAgentUnderPath covers an agent at /a2a/v1 next to a sibling.
|
|
||
| // challengeRequirement asks an interface without credentials for its Bearer | ||
| // challenge and follows it, or the well-known locations, to the authorization server. | ||
| func (g *globalConfig) challengeRequirement(ctx context.Context, baseURL string) (*oauth.Requirement, error) { |
There was a problem hiding this comment.
let's move this to oauth.Manager, it mostly duplicates transport.go and we keep logic out of the cli package
There was a problem hiding this comment.
Moved. Manager.RequirementForURL in a2aproject/a2a-go#570 does the probe, and auth login in mykytanetipa#6 calls it after a real A2A call. The CLI copy is gone.
|
Closing in favor of the a2a-go OAuth client (a2aproject/a2a-go#568, a2aproject/a2a-go#569, a2aproject/a2a-go#570) and the CLI changes built on it (mykytanetipa#6, mykytanetipa#7). |
Calling an OAuth-protected agent previously meant fetching a token elsewhere and passing it by hand until it expired. This wires OAuth into agent commands so they sign in on demand and retry once. It also adds login, logout, list, and get support under the auth command group.
Example:
When an agent command hits an interaction-required error on an interactive terminal, the CLI runs the sign-in prompt on stderr under its own five-minute timeout. Once authorized, it saves the grant and reruns the command once with a fresh request timeout, skipping the retry if a stream already printed events. In pipes, scripts, CI, or explicit cached mode, the CLI never waits on a browser and exits immediately with a hint showing the login command to run. The bundled agent skill instructions use cached mode the same way so coding agents ask the user to log in rather than hanging.
Explicit credentials stay in charge: when the auth flag, a service parameter, or a credential helper already supplies the Authorization header, OAuth stays out of the way. Pre-registered clients are configured per authorization server on the command line or in the user config file, and ignored in any discovered local .env file; a separate setting changes or turns off the default client metadata document. Logging out of one agent revokes its grants upstream when the server supports revocation, deletes them locally, and leaves other agents on the same host signed in.
Refs #98