Skip to Content
Use CasesExternal Services Auth
View .md

Service Authentication

Alien Agent ID supports two authentication models: DPoP-signed calls (RFC 9449) for Alien-aware services, and vault credentials for external services like GitHub, AWS, and Slack.

Alien-Aware Services

Services that integrate with Alien Agent ID authenticate agents with RFC 9449 DPoP. Each request carries two headers:

  • Authorization: DPoP <access_token> — the SSO-issued, agent-bound access token
  • DPoP: <proof JWT> — a fresh per-request proof signed by the agent’s Ed25519 key

No API keys, no shared secrets, no envelope token. Owner ↔ agent binding lives entirely in standard claims: the access token carries sub (the human owner) and cnf.jkt (the agent key thumbprint, RFC 7800 §3.1), and the DPoP proof binds the request to that same key.

Let the CLI sign and send the request for you — this avoids the single-use-proof footgun:

node plugins/agent-id-auth/bin/cli.mjs call --url https://service.example.com/api/whoami node plugins/agent-id-auth/bin/cli.mjs call --url https://service.example.com/api/posts \ --method POST --body-file ./body.json

Useful flags: --method <verb> (defaults to GET), --body <inline> or --body-file <path>, --content-type <type>. Output is JSON: { ok, status, method, url, contentType, body }.

Two-Header Path

When you need to drive the HTTP call yourself, emit the headers and pass them in. The --url is required — the DPoP proof’s htu claim binds to a specific request target:

node plugins/agent-id-auth/bin/cli.mjs header \ --url https://service.example.com/api/whoami --method GET --raw # → Authorization: DPoP <access_token> # → DPoP: <proof JWT>

Never hand-roll DPoP headers, and never call an Alien-aware service with plain curl/fetch. The CLI generates the per-request proof; a raw request will get a 401.

DPoP Proof Anatomy

The DPoP header is a compact JWS (header {typ: "dpop+jwt", alg: "EdDSA", jwk}) whose payload binds the proof to one specific request:

ClaimDescription
jtiUnique identifier (fresh per proof) — single-use, replay-resistant
htmHTTP method of the request
htuRequest target URL (query and fragment stripped, per RFC 9449 §4.2)
iatIssued-at time (unix seconds) — servers validate freshness
athbase64url(SHA-256(access_token)) — binds the proof to this specific access token

Each proof is single-use and request-bound. Reusing a proof on a different URL, or after the authorization server rotates the access token, will be rejected. The embedded jwk is the agent’s public Ed25519 key; the server checks its thumbprint against the access token’s cnf.jkt.

Services verify with @alien-id/sso-agent-id’s verifyDPoPRequest — see Service Integration to add verification to your own service.

Service Discovery

Alien-aware services publish a JSON manifest at https://<host>/.well-known/alien-agent-id.json. Fetch and validate it before talking to the service:

node plugins/agent-id-auth/bin/cli.mjs discover --url https://example.com

The CLI enforces an 8 KiB body cap, rejects redirects, requires application/json, and validates against a closed schema. Every URL in the manifest must share the same authority as the service URL you gave the agent (exact host[:port], or a subdomain of it). A manifest declaring api.operations[] (manifest v2) can be rendered as actionable markdown:

node plugins/agent-id-auth/bin/cli.mjs capabilities --url https://example.com

Services may also advertise support with an optional closed-enum HTML meta tag — it only signals whether a service claims support, never where to go:

<meta name="alien-agent-id" content="v1">
node plugins/agent-id-auth/bin/cli.mjs support --url https://example.com/ # → { ok: true, supported: <bool>, version: <"v1" | null> }

The well-known JSON manifest is the only supported discovery mechanism. An earlier ALIEN-SKILL.md Markdown file was removed — free-form Markdown is too permissive a channel for a third-party server to feed an LLM.

External Services

External services (GitHub, AWS, Slack) don’t know about Alien Agent ID. The agent authenticates using credentials stored in the Credential Vault.

Retrieve and Use Credentials

# Retrieve stored credential TOKEN=$(node plugins/agent-id-vault/bin/cli.mjs get --service github | jq -r .credential) # Use it for API calls curl -H "Authorization: Bearer $TOKEN" https://api.github.com/user/repos

get returns JSON { ok, service, type, credential, url, username }. If the credential doesn’t exist in the vault, ask the user to provide it using the secure storage flow.

Next Steps

Last updated on