Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 1 addition & 8 deletions .github/workflows/hardware-keys.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ on:
description: 'Publish platform packages to npm'
type: boolean
default: false
secrets:
NPM_TOKEN:
required: false

permissions:
contents: read
Expand Down Expand Up @@ -165,7 +162,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
node-version: 24
registry-url: https://registry.npmjs.org
- uses: actions/download-artifact@v4
with:
Expand All @@ -185,8 +182,6 @@ jobs:
path: hardware-keys/npm/win32-x64-msvc/

- name: Publish platform packages
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
VERSION=$(node -p "require('./hardware-keys/package.json').version")
for pkg in darwin-arm64 darwin-x64 linux-x64-gnu win32-x64-msvc; do
Expand All @@ -200,8 +195,6 @@ jobs:
done

- name: Publish main hardware-keys package
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
VERSION=$(node -p "require('./hardware-keys/package.json').version")
published=$(npm view "@aauth/hardware-keys" version 2>/dev/null || echo "0.0.0")
Expand Down
6 changes: 1 addition & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ jobs:
uses: ./.github/workflows/hardware-keys.yml
with:
publish: true
secrets:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
permissions:
contents: read
id-token: write
Expand All @@ -40,7 +38,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
node-version: 24
cache: npm
registry-url: https://registry.npmjs.org
- run: npm ci
Expand Down Expand Up @@ -81,8 +79,6 @@ jobs:
echo "✅ All packages at version $VERSION"

- name: Publish packages with provenance
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
for pkg in local-keys mcp-agent mcp-server bootstrap fetch mcp-openclaw mcp-stdio; do
published=$(npm view "@aauth/$pkg" version 2>/dev/null || echo "0.0.0")
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ const token = await createResourceToken({ resource, authServer, agent, agentJkt
### Local development

```bash
# Generate keys, configure a person server, and publish them
npx @aauth/bootstrap --ps <your-ps-url>
# Generate keys and bind the default person server (person.hello.coop)
npx @aauth/bootstrap generate --agent <your-agent-url> --ps
```

See [`@aauth/bootstrap`](./bootstrap) for the full setup flow.
Expand Down
11 changes: 8 additions & 3 deletions bootstrap/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,15 @@ Part of [aauth-dev/packages-js](https://github.com/aauth-dev/packages-js). Proto
## Quick Start

```bash
# Generate keys, configure a person server, and walk through hosting setup
npx @aauth/bootstrap --ps <your-ps-url>
# Generate keys, bind the default person server (person.hello.coop), and walk through hosting setup
npx @aauth/bootstrap generate --agent <your-agent-url> --ps

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

`--ps` with no URL binds the default person server (`https://person.hello.coop`). Once an agent exists, you can re-run just `npx @aauth/bootstrap --ps` to (re)configure its person server.

The bootstrap flow detects available key backends (YubiKey PIV, macOS Secure Enclave, software), generates keys on the strongest available backend, configures a person server for your agent, and bundles agent skills that walk you through publishing keys on platforms like GitHub Pages, GitLab Pages, Cloudflare Pages, and Netlify.

Per [draft-hardt-aauth-bootstrap §Self-Hosted Enrollment](https://github.com/dickhardt/AAuth), publication of the JWKS is the enrollment — there is no separate enrollment step. Person binding to a user happens lazily on the agent's first authorized request, per [§Agent-Person Binding](https://github.com/dickhardt/AAuth) in the protocol spec.
Expand Down Expand Up @@ -54,7 +59,7 @@ Commands:
Can be combined with any command:

```
--person-server <url> Bootstrap with person server (alias: --ps)
--person-server [url] Bootstrap with person server (alias: --ps; default: https://person.hello.coop)
--local <name> Local part of agent identifier (default: "local")
--login-hint <hint> Hint about who to authorize
--domain-hint <domain> Domain/org routing hint
Expand Down
2 changes: 1 addition & 1 deletion bootstrap/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@aauth/bootstrap",
"version": "0.11.1",
"version": "0.11.3",
"description": "CLI for bootstrapping AAuth agent keys and configuration",
"type": "module",
"bin": {
Expand Down
25 changes: 17 additions & 8 deletions bootstrap/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ import { createRequire } from 'node:module'

const pkg = createRequire(import.meta.url)('../package.json') as { version: string }

/** Person Server used when `--ps`/`--person-server` is given without a URL. */
const DEFAULT_PERSON_SERVER = 'https://person.hello.coop'

function computeJkt(jwk: Record<string, unknown>): string {
const kty = jwk.kty as string
const crv = jwk.crv as string
Expand Down Expand Up @@ -286,8 +289,9 @@ function cmdShow(flags: Record<string, string> = {}) {
// Getting-started footer: shown for both `bootstrap` (no command) and `bootstrap show`.
console.log('')
if (agents.length === 0) {
console.log('No agents configured yet. Quick start:')
console.log(' npx @aauth/bootstrap --ps https://person.hello-beta.net')
console.log('No agents configured yet. Quick start (use your own agent URL):')
console.log(' npx @aauth/bootstrap generate --agent https://me.github.io --ps')
console.log(' (generates a key, then binds the default person server person.hello.coop)')
} else {
console.log('Try calling an AAuth-protected resource:')
console.log(' npx @aauth/fetch https://whoami.aauth.dev --log')
Expand All @@ -296,7 +300,7 @@ function cmdShow(flags: Record<string, string> = {}) {
console.log('Common commands:')
console.log(' npx @aauth/bootstrap discover List available key backends')
console.log(' npx @aauth/bootstrap generate [opts] Generate a signing key')
console.log(' npx @aauth/bootstrap --ps <url> Configure a person server')
console.log(' npx @aauth/bootstrap --ps [url] Configure a person server (default: person.hello.coop)')
console.log(' npx @aauth/bootstrap sign-token Sign a one-off agent_token')
console.log(' npx @aauth/bootstrap help Full help')
}
Expand Down Expand Up @@ -350,7 +354,7 @@ Add-agent options:
--algorithm <alg> Key algorithm

Person server configuration (can be combined with any command):
--person-server <url> Person server URL (alias: --ps)
--person-server [url] Person server URL (alias: --ps; default: https://person.hello.coop)
--local <name> Local part of agent identifier (default: "local")

Output:
Expand All @@ -362,14 +366,19 @@ Examples:
npx @aauth/bootstrap generate --backend secure-enclave --agent https://me.github.io
npx @aauth/bootstrap sign-token --agent https://me.github.io
npx @aauth/bootstrap add-agent https://me.github.io
npx @aauth/bootstrap --ps <your-ps-url>
npx @aauth/bootstrap generate --agent https://me.github.io --ps <your-ps-url>
npx @aauth/bootstrap --ps (defaults to https://person.hello.coop)
npx @aauth/bootstrap --ps https://person.example
npx @aauth/bootstrap generate --agent https://me.github.io --ps
npx @aauth/bootstrap public-key --agent https://me.github.io`)
}

async function runBootstrapPS(flags: Record<string, string>) {
const personServerUrl = flags['person-server']
if (!personServerUrl) return
// The arg parser stores a value-less `--ps` as the string 'true'. Treat that
// (or an empty value) as "use the default Person Server" so `bootstrap --ps`
// works without typing the URL.
const psFlag = flags['person-server']
if (!psFlag) return
const personServerUrl = psFlag === 'true' ? DEFAULT_PERSON_SERVER : psFlag

const urlError = validateUrl(personServerUrl)
if (urlError) {
Expand Down
10 changes: 8 additions & 2 deletions fetch/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,18 @@ Part of [aauth-dev/packages-js](https://github.com/aauth-dev/packages-js). Proto

## Prerequisites

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

```bash
npx @aauth/bootstrap --ps <your-ps-url>
# Generate a key for your agent and bind the default person server (person.hello.coop)
npx @aauth/bootstrap generate --agent <your-agent-url> --ps

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

Once an agent is configured, you can re-bind the person server on its own with `npx @aauth/bootstrap --ps` (defaults to person.hello.coop).

## Quick Start

```bash
Expand Down
2 changes: 1 addition & 1 deletion fetch/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@aauth/fetch",
"version": "0.11.1",
"version": "0.11.3",
"description": "CLI for making AAuth-authenticated HTTP requests",
"type": "module",
"bin": {
Expand Down
10 changes: 7 additions & 3 deletions fetch/skills/fetch.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@ Make HTTP requests to AAuth-protected APIs. Handles HTTP message signatures, age

## Prerequisites

The agent must be configured with a person server before making authorized requests:
The agent must have a signing key and a person server configured before making authorized requests:

```bash
npx @aauth/bootstrap --ps <your-ps-url>
# Generate a key for your agent and bind the default person server (person.hello.coop)
npx @aauth/bootstrap generate --agent <your-agent-url> --ps

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

This validates the PS metadata and stores the PS URL plus agent identifier (e.g., `aauth:local@yourdomain.com`) in `~/.aauth/config.json`. Person binding then happens lazily on the first authorized request.
`--ps` with no URL binds the default person server (`https://person.hello.coop`). This validates the PS metadata and stores the PS URL plus agent identifier (e.g., `aauth:local@yourdomain.com`) in `~/.aauth/config.json`. Person binding then happens lazily on the first authorized request. Once an agent exists, `npx @aauth/bootstrap --ps` re-binds its person server on its own.

## Discovery

Expand Down
4 changes: 2 additions & 2 deletions fetch/src/getting-started.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ export function printGettingStarted(): void {
if (!configured) {
console.log('You don\'t have an agent configured yet.')
console.log('')
console.log('Set one up first:')
console.log(' npx @aauth/bootstrap --ps https://person.hello-beta.net')
console.log('Set one up first (use your own agent URL):')
console.log(' npx @aauth/bootstrap generate --agent https://me.github.io --ps')
console.log('')
}

Expand Down
2 changes: 1 addition & 1 deletion hardware-keys/npm/darwin-arm64/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@aauth/hardware-keys-darwin-arm64",
"version": "0.11.1",
"version": "0.11.3",
"os": [
"darwin"
],
Expand Down
2 changes: 1 addition & 1 deletion hardware-keys/npm/darwin-x64/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@aauth/hardware-keys-darwin-x64",
"version": "0.11.1",
"version": "0.11.3",
"os": [
"darwin"
],
Expand Down
2 changes: 1 addition & 1 deletion hardware-keys/npm/linux-x64-gnu/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@aauth/hardware-keys-linux-x64-gnu",
"version": "0.11.1",
"version": "0.11.3",
"os": [
"linux"
],
Expand Down
2 changes: 1 addition & 1 deletion hardware-keys/npm/win32-x64-msvc/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@aauth/hardware-keys-win32-x64-msvc",
"version": "0.11.1",
"version": "0.11.3",
"os": [
"win32"
],
Expand Down
10 changes: 5 additions & 5 deletions hardware-keys/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@aauth/hardware-keys",
"version": "0.11.1",
"version": "0.11.3",
"description": "Hardware key backends for AAuth: YubiKey PIV and macOS Secure Enclave",
"main": "index.js",
"files": [
Expand Down Expand Up @@ -30,9 +30,9 @@
"@napi-rs/cli": "^2.18.0"
},
"optionalDependencies": {
"@aauth/hardware-keys-darwin-arm64": "0.11.1",
"@aauth/hardware-keys-darwin-x64": "0.11.1",
"@aauth/hardware-keys-linux-x64-gnu": "0.11.1",
"@aauth/hardware-keys-win32-x64-msvc": "0.11.1"
"@aauth/hardware-keys-darwin-arm64": "0.11.3",
"@aauth/hardware-keys-darwin-x64": "0.11.3",
"@aauth/hardware-keys-linux-x64-gnu": "0.11.3",
"@aauth/hardware-keys-win32-x64-msvc": "0.11.3"
}
}
2 changes: 1 addition & 1 deletion local-keys/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Library for managing AAuth agent signing keys across hardware and software backe

Part of [aauth-dev/packages-js](https://github.com/aauth-dev/packages-js). Protocol spec: [dickhardt/AAuth](https://github.com/dickhardt/AAuth).

> **Looking for a CLI?** This package is a library. The CLI for setting up agent keys, configuring a person server, and publishing keys is [`@aauth/bootstrap`](../bootstrap). Run `npx @aauth/bootstrap --ps <your-ps-url>` to get started.
> **Looking for a CLI?** This package is a library. The CLI for setting up agent keys, configuring a person server, and publishing keys is [`@aauth/bootstrap`](../bootstrap). Run `npx @aauth/bootstrap generate --agent <your-agent-url> --ps` to get started (`--ps` with no URL binds the default person server, person.hello.coop).

## Install

Expand Down
2 changes: 1 addition & 1 deletion local-keys/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@aauth/local-keys",
"version": "0.11.1",
"version": "0.11.3",
"description": "Manage AAuth agent signing keys across hardware and software backends",
"type": "module",
"exports": {
Expand Down
2 changes: 1 addition & 1 deletion mcp-agent/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@aauth/mcp-agent",
"version": "0.11.1",
"version": "0.11.3",
"description": "Authenticated MCP transport with HTTP Signatures for AAuth agents",
"type": "module",
"exports": {
Expand Down
2 changes: 1 addition & 1 deletion mcp-openclaw/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@aauth/mcp-openclaw",
"version": "0.11.1",
"version": "0.11.3",
"description": "OpenClaw plugin for AAuth-authenticated MCP server connections",
"type": "module",
"exports": {
Expand Down
2 changes: 1 addition & 1 deletion mcp-server/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@aauth/mcp-server",
"version": "0.11.1",
"version": "0.11.3",
"description": "AAuth server-side building blocks: challenge headers, interaction management, resource tokens",
"type": "module",
"exports": {
Expand Down
2 changes: 1 addition & 1 deletion mcp-stdio/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@aauth/mcp-stdio",
"version": "0.11.1",
"version": "0.11.3",
"description": "Stdio-to-HTTP proxy for MCP with AAuth signatures",
"type": "module",
"exports": {
Expand Down
Loading
Loading