Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 

README.md

@aauth/fetch

CLI for making AAuth-authenticated HTTP requests. Handles HTTP Message Signatures, agent tokens, and the full AAuth authorization flow including R3 (Rich Resource Requests).

Part of aauth-dev/packages-js. Protocol spec: dickhardt/AAuth.

Prerequisites

The agent must be bootstrapped before making authorized requests — it needs a signing key and a person server in config. Use @aauth/bootstrap:

# Register an agent provider: generate a key, bind it, and bind the default
# person server (person.hello.coop) — all in one command.
npx @aauth/bootstrap create <your-agent-provider-url>

# ...or point at a specific person server
npx @aauth/bootstrap create <your-agent-provider-url> --person-server https://person.example

Quick Start

# Call an AAuth-protected API — handles 401 challenges and auth flow automatically
npx @aauth/fetch https://whoami.aauth.dev

# Request specific scopes
npx @aauth/fetch "https://whoami.aauth.dev?scope=email+profile"

Seeing what each operation needs

Fetch a resource's OpenAPI document and fetch reads its operation access annotations (x-aauth-access-mode / x-aauth-budget, AAuth R3) out of the body, grouping the operations by the credential each one needs — on stderr, so stdout is still the raw spec for jq:

$ npx @aauth/fetch https://notes.aauth.dev/openapi.json > openapi.json
Operation access annotations (advisory — the resource may return any AAuth-Requirement at runtime):

  agent-token — your agent token alone — no person involved
    getHealth        GET /health

  auth-token — an auth token — costs one authorization round trip
    listNotes        GET /notes
    exportNotes      POST /notes/export   [budget]

  per-call — authorized per invocation — will stop and wait for a person
    purchaseReport   POST /reports/{id}/purchase  [budget]

Annotations are advisory: a resource may return any AAuth-Requirement at runtime regardless of what it published, so fetch prints them and enforces nothing. When your agent has no person server, the groups it cannot complete say so.

Authorize-then-call (recommended for multi-call workflows)

Capture an auth token once, then reuse it for subsequent calls.

# 1. Authorize and capture tokens (writes JSON to stdout)
npx @aauth/fetch authorize "https://whoami.aauth.dev?scope=email"

# For R3 resources, POST to the authorize endpoint with operations:
npx @aauth/fetch authorize https://notes.aauth.dev/authorize \
  --operations listNotes,createNote

# Bind the grant to one of your accounts at the resource:
npx @aauth/fetch authorize https://googleapis-com.proxy.aauth.dev/authorize \
  --operations gmail.users.messages.send,calendar.events.list \
  --account dick@example.com

Returns the auth token and ephemeral signing key. Or capture the credential with the call using --emit, then export it so later calls reuse it:

OUT=$(npx @aauth/fetch --emit https://notes.aauth.dev/notes)
export AAUTH_AUTH_TOKEN=$(jq -r .auth_token  <<<"$OUT")
export AAUTH_SIGNING_KEY=$(jq -c .signingKey <<<"$OUT")
npx @aauth/fetch https://notes.aauth.dev/notes      # signs with the saved auth token

Tokens are never written to disk — you decide how to reuse them (export to env, pipe between commands). Only the public person-server metadata is cached, under ~/.aauth/cache/.

Usage

npx @aauth/fetch <resource> [flags]          # authenticated fetch (full flow)
npx @aauth/fetch authorize <resource> [flags] # auth flow only; print tokens for reuse
npx @aauth/fetch skill                   # print the fetch guide (+ site & protocol URLs)
npx @aauth/fetch help                    # show help (--help also works)

Request:
  -X, --method <method>       HTTP method (default: GET)
  -d, --data <body>           Request body
  -H, --header <header>       Additional header (repeatable)
  --json                      Read full request from stdin as JSON (input only)

AAuth:
  --agent-provider <url>      Agent provider to sign as (default: from config)
  --local <name>              Local part of agent identifier (default: from config)
  --person-server <url>       Override person server URL
  --poll-timeout <seconds>    Seconds to wait for the person to approve consent
                              (default: 900 — covers a human consent ceremony
                              including a chained upstream OAuth)

Modes:
  --agent-only                Sign with agent token only; don't handle 401
  --auth-token <jwt> --signing-key <jwk>   Use an existing auth token + signing key (three-party)
  --session-token <token>     Reuse a session token (two-party, carried in
                              AAuth-Access; no signing key)
  --emit                      Emit the reusable credential(s) to stdout alongside the body.
                              Three-party: { auth_token, expires_in, signingKey, response }
                              Two-party:   { session_token, response }  (no signingKey)
                              `response` is the body (same as bare fetch)

Authorize (with the `authorize` command):
  --operations <ops>          R3 operation ids (comma-separated), as they
                              appear in the resource's vocabulary
  --scope <scope>             Requested scopes
  --account <account>         Upstream account at the resource to bind the
                              authorization to (e.g. a Google email)

Person server (passed during consent) / consent handling:
  --login-hint / --domain-hint / --tenant / --justification
  --prompt-login / --prompt-consent   (force re-auth / force the consent prompt)
  --browser / --non-interactive   (consent URL + QR print by default; --browser auto-opens)

Output (response body → stdout; these add detail on stderr, clean for `… | jq`):
  --explain                   Teaching view: per-step request/response with
                              summaries, descriptions, real RFC 9421 signed
                              headers, and bodies. Pretty + colorized at a TTY;
                              compact JSONL when piped/captured.
  --explain-log <path>        Write the --explain event stream (JSONL) to this
                              file (default: ~/.aauth/fetch/logs/<timestamp>.jsonl).
  --debug, -v, --verbose      Raw wire view: every HTTP hop as { request } /
                              { response } objects (with bodies); no descriptions.

The CLI's full flag list is generated from one spec (src/args.ts) — run npx @aauth/fetch --help for the authoritative, always-current reference.

For AI Agents

Run npx @aauth/fetch skill to print the agent usage guide (markdown), which also links to https://www.aauth.dev, the llms.txt index, and the AAuth protocol spec.

Related Packages

  • @aauth/bootstrap — set up agent keys and configure a person server (run this first)
  • @aauth/agent — programmatic agent-side AAuth for use inside applications

License

MIT