docs/ implements the specification’s
Identity profile. Delegated authority (§5) is opt-in: see
Delegated authority. Example implementations
and seed data are provided as reference. The code calls Brands customers
(CUSTOMER_ID, the customers table).
These apps are local demos, not production-ready services. The Brand app uses
fixed demo credentials and in-memory account data. Before deploying publicly,
replace demo authentication, add rate limits, and restrict outbound JWKS requests
to public IP addresses after DNS resolution.
Run it locally
Node 20+ and pnpm 11.21.0.DATABASE_POOL_MAX=1 matters: PGlite is a single-session database, so with
the default pool of 5 the Provider’s connections interleave and it fails with
prepared statement "" requires N parameters.
Once the database is up, migrate and seed it. Any PostgreSQL works; point
DATABASE_URL at it. PA_ variables and -pa ids refer to the personal agent:
demo-pa):
Put them in
reference/personal-agent/client/.env.local:
http://localhost:3001. With OPENAI_API_KEY set on either side the
agents use OpenAI; without it they use scripted replies.
Delegated authority (optional)
WithDELEGATION_ENABLED=1 on the Provider, Skyline Airways’ card also offers
OAuth 2.0 device-code delegation (§5) with three scopes:
flights:upcoming:read, flights:history:read and flights:rebook. The other
Brands stay Identity-only. Without the variable, nothing changes.
Roles follow the spec: the Provider is the authorization server (device and token
endpoints, consent page, signing key, token checks on every message). The Brand
app owns login, accounts and the account API. After login it posts a signed,
single-use assertion (keys at {BRAND_URL}/.well-known/jwks.json) to the
Provider’s consent page.
Start the Brand app and restart the Provider with delegation on:
Demo hostnames
For browser-facing demo URLs that look like a production deployment, start the Provider with:http://agent.localhost:3001. This mirrors production, where consent
is served by the Provider on a Brand subdomain (Provider guide).
In the demo personal agent, ask “Can you check my upcoming Skyline flight?”.
Skyline replies TASK_STATE_AUTH_REQUIRED, and the agent shows a Sign in with Skyline Airways card that opens the Brand login in a new tab (demo account
alex.rivera@example.com / skyline). Choose scopes on the consent page; the
agent polls the token endpoint, re-sends the message with
X-A2A-User-Delegation, and shows the signed receipt on the Skyline thread.
Asking to rebook without flights:rebook triggers step-up.
Delegated conformance tests (skipped when the card has no delegation):
Register a personal agent
The reference Provider registers personal agents atPOST {PROVIDER_URL}/api/platforms
(the spec leaves registration to each Provider):
REGISTRATION_TOKEN is a JWT signed with the personal agent’s key: iss = issuer,
sub = iss, aud = the endpoint URL, exp ≤ 300 s. The JWKS URI must share
the issuer’s origin. 201 registers (audience = A2A_AUDIENCE), 409 means
the name or issuer is taken. The demo personal agent’s Register button makes this call.
Conformance tests
PA_PRIVATE_JWK comes from the environment or the personal-agent client’s .env.local.
Against another Provider add E2E_PROVIDER=any, which skips only the
reference Provider’s seeded card text and canned replies.
E2E_TEST_TIMEOUT_MS (default 60000) bounds each test.