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
1 change: 0 additions & 1 deletion .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ body:
label: Affected package
options:
- "@authmesh/cli"
- "@authmesh/agent"
- "@authmesh/sdk"
- "@authmesh/core"
- "@authmesh/keystore"
Expand Down
1 change: 0 additions & 1 deletion .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ body:
label: Related package
options:
- "@authmesh/cli"
- "@authmesh/agent"
- "@authmesh/sdk"
- "@authmesh/core"
- "@authmesh/keystore"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
- run: bun run test

- run: |
for pkg in packages/core packages/keystore packages/cli packages/sdk packages/relay packages/agent; do
for pkg in packages/core packages/keystore packages/cli packages/sdk packages/relay; do
(cd $pkg && npm publish --no-git-checks --access public) || echo "Skipped $pkg (already published or error)"
done
env:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ jobs:

def install
bin.install "amesh"
bin.install "amesh-agent" if File.exist?("amesh-agent")
bin.install "amesh" if File.exist?("amesh")
bin.install "amesh-se-helper" if File.exist?("amesh-se-helper")
end

Expand Down
20 changes: 10 additions & 10 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

- **Install script** served at `authmesh.dev/install` — one-liner install for headless devices: `curl -fsSL https://authmesh.dev/install | sh`
- **arm64 .deb package** — release workflow now produces both `amd64` and `arm64` Debian packages
- **amesh-agent in .deb** — the `.deb` package now includes both `amesh` and `amesh-agent` binaries
- **amesh-agent in .deb** — the `.deb` package now includes both `amesh` and `amesh` binaries
- **Blog post** — "Your AI just wrote another .env file"

### Changed
Expand Down Expand Up @@ -82,11 +82,11 @@ Full external-pen-tester-style security audit. All findings (2 critical, 4 high,

### Added

- **Prebuilt `amesh-agent` binaries** for macOS arm64/x64 and Linux x64/arm64, built by the release pipeline and shipped in the same `amesh-{version}-{platform}-{arch}.tar.gz` tarball as the main `amesh` binary. Fixes the "install fails on every platform" issue — `npm install -g @authmesh/agent` and `brew install ameshdev/tap/amesh` now both produce a working `amesh-agent` without the `bun $(which amesh-agent) ...` wrapper. Raspberry Pi 3 and earlier (armv7, 32-bit Pi OS) remain unsupported because Bun itself does not ship for that architecture.
- **Prebuilt `amesh` binaries** for macOS arm64/x64 and Linux x64/arm64, built by the release pipeline and shipped in the same `amesh-{version}-{platform}-{arch}.tar.gz` tarball as the main `amesh` binary. Fixes the "install fails on every platform" issue — `npm install -g @authmesh/cli` and `brew install ameshdev/tap/amesh` now both produce a working `amesh` without the `bun $(which amesh-agent) ...` wrapper. Raspberry Pi 3 and earlier (armv7, 32-bit Pi OS) remain unsupported because Bun itself does not ship for that architecture.
- **`linux-arm64` target** added to the release matrix (cross-compiled from `ubuntu-latest` via Bun's `--target` flag). Unblocks Raspberry Pi 4/5 on 64-bit Pi OS and ARM cloud VMs.
- **npm postinstall binary downloader** (`packages/agent/scripts/postinstall.mjs`) detects host platform and arch, downloads the matching prebuilt binary from the GitHub release, extracts it into `node_modules/@authmesh/agent/bin/amesh-agent`, and chmods it executable. Unsupported architectures (e.g. armv7) get a clear "install Bun and use wrapper" message and a graceful exit-0 so `npm install` never fails.
- **npm postinstall binary downloader** (`packages/agent/scripts/postinstall.mjs`) detects host platform and arch, downloads the matching prebuilt binary from the GitHub release, extracts it into `node_modules/@authmesh/cli/bin/amesh-agent`, and chmods it executable. Unsupported architectures (e.g. armv7) get a clear "install Bun and use wrapper" message and a graceful exit-0 so `npm install` never fails.
- **Launcher script** (`packages/agent/scripts/launcher.mjs`) — the new `bin` entry that execs the prebuilt binary when present and falls back to the JS oclif entry otherwise. Same pattern esbuild/swc use.
- **Compiled-binary entry point** for the agent (`packages/agent/src/sea.ts`) — mirrors `packages/cli/src/sea.ts` with explicit nested-command dispatch for `amesh-agent agent start` since the CLI sea.ts only handled top-level commands.
- **Compiled-binary entry point** for the agent (`packages/agent/src/sea.ts`) — mirrors `packages/cli/src/sea.ts` with explicit nested-command dispatch for `amesh agent start` since the CLI sea.ts only handled top-level commands.
- **Docs IA restructure (vite.dev / bun.com style)** on the landing page: nested sidebar sections (Introduction / Getting Started / Guides / Reference / Packages), redesigned `/docs` landing with feature-grid layout, cross-section prev/next navigation.
- **Five new doc pages**: `/docs/introduction`, `/docs/quickstart`, `/docs/faq`, `/docs/troubleshooting`, `/docs/changelog`.
- **`/blog` section** with two seed posts: "Why we built amesh" (essay) and "Introducing amesh 0.3" (release notes). Includes `BlogPosting` JSON-LD schema and proper `article:*` Open Graph meta.
Expand All @@ -96,23 +96,23 @@ Full external-pen-tester-style security audit. All findings (2 critical, 4 high,

### Changed

- **`@authmesh/agent` oclif config** — added `topicSeparator: " "` so `amesh-agent agent start` (space-separated) resolves correctly under the JS fallback path. Previously only colon syntax (`agent:start`) worked under Node, which meant users hitting the fallback path saw topic help instead of the Bun runtime guard error.
- **`packaging/build-bun.mjs`** refactored to a shared `compile()` helper invoked once for `amesh` and once for `amesh-agent`. Both binaries land in `packaging/dist/` and are packed into the same release tarball.
- **Homebrew formula** (`packaging/homebrew/amesh.rb` + the heredoc in `release-packages.yml`) installs `amesh-agent` alongside `amesh` from a single `brew install ameshdev/tap/amesh`. Added the `on_linux/on_arm` block for the new linux-arm64 target.
- **`@authmesh/cli` oclif config** — added `topicSeparator: " "` so `amesh agent start` (space-separated) resolves correctly under the JS fallback path. Previously only colon syntax (`agent:start`) worked under Node, which meant users hitting the fallback path saw topic help instead of the Bun runtime guard error.
- **`packaging/build-bun.mjs`** refactored to a shared `compile()` helper invoked once for `amesh` and once for `amesh`. Both binaries land in `packaging/dist/` and are packed into the same release tarball.
- **Homebrew formula** (`packaging/homebrew/amesh.rb` + the heredoc in `release-packages.yml`) installs `amesh` alongside `amesh` from a single `brew install ameshdev/tap/amesh`. Added the `on_linux/on_arm` block for the new linux-arm64 target.
- **Hero chip** on the landing page: `Production ready` → `Beta`. The 0.3.x line is a pre-1.0 product and "production ready" was overclaiming.
- **Comparison table** on the landing page: `Vault` column renamed to `Secrets Manager`. Matches the genericize-company-names policy below.
- **Genericize company mentions across prose.** Removed `AWS Secrets Manager`, `HashiCorp Vault`, `Doppler`, `Uber`, `Samsung`, `Toyota`, `Twitch`, `Ethereum`, `Signal`, `Cloudflare` from the landing page, blog, `/docs/introduction`, `/docs/faq`, and `docs/why-amesh.md`. The technical critique of the secrets-manager pattern is preserved; the name-dropping is gone. Product/infrastructure names required for instructions (Cloud Run, Homebrew, npm, Bun, TPM, Secure Enclave, etc.) are kept.
- **Flattened navigation** — removed the Use Cases dropdown. Nav is now a flat list: `Docs | Use Cases | Blog | GitHub | Get Started`.
- **Hero visual upgrades** — trust strip below hero with `@noble/*` dependency credits, card lift hovers with shadow on all feature/replace/CTA cards, tightened h1 typography.
- **ADR-011** (`docs/architecture-decisions.md`) — marked partially superseded. The "one package, one binary" design was reversed in favor of splitting the agent into `@authmesh/agent`. Runtime-dependency argument (`Bun.spawn({ terminal })` is Bun-only) outweighed the install-confusion concern once prebuilt binaries landed.
- **ADR-011** (`docs/architecture-decisions.md`) — marked partially superseded. The "one package, one binary" design was reversed in favor of splitting the agent into `@authmesh/cli`. Runtime-dependency argument (`Bun.spawn({ terminal })` is Bun-only) outweighed the install-confusion concern once prebuilt binaries landed.

### Fixed

- **`/docs/remote-shell` showed phantom commands and install methods.** The page displayed `amesh agent start` (command doesn't exist — it's `amesh-agent agent start` from a separate package), referenced `brew install ameshdev/tap/amesh-agent` (no such formula), and linked to an `amesh-agent-linux-x64.tar.gz` download (never built). All corrected, plus a Runtime Requirement callout was added until binaries are verified in the first tagged release.
- **`/docs/remote-shell` showed phantom commands and install methods.** The page displayed `amesh agent start` (command doesn't exist — it's `amesh agent start` from a separate package), referenced `brew install ameshdev/tap/amesh-agent` (no such formula), and linked to an `amesh-agent-linux-x64.tar.gz` download (never built). All corrected, plus a Runtime Requirement callout was added until binaries are verified in the first tagged release.
- **`TableOfContents` magic-number margin** — replaced hardcoded `margin-left: 44rem` with a responsive `left: min(calc(50vw + 30rem), calc(100vw - 13.5rem))` calc, gated on the `2xl` breakpoint where there's actually room for a right-rail TOC. Between `lg` and `2xl`, the collapsible mobile-style TOC takes over instead of overlapping content.
- **Sitemap missing `/docs/key-storage`** — added, along with all new routes.
- **`docs/remote-shell-spec.md` and `docs/why-amesh.md`** updated to match the agent package split and the genericize-company-names policy.
- **`packages/cli/README.md`** — removed the stale `amesh agent start` command listing (that command lives in `@authmesh/agent`, not `@authmesh/cli`) and added a pointer to the separate agent package.
- **`packages/cli/README.md`** — removed the stale `amesh agent start` command listing (that command lives in `@authmesh/cli`, not `@authmesh/cli`) and added a pointer to the separate agent package.
- **`packages/agent/README.md`** — dropped the phantom Homebrew tap reference, documented the postinstall binary download, listed the four supported platforms and the armv7 exclusion.

## [0.3.3] - 2026-04-04
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ packages/
core/ — crypto primitives (sign, verify, HMAC, HKDF, ECDH)
keystore/ — key storage drivers (Secure Enclave, TPM, encrypted file)
cli/ — amesh CLI (oclif)
agent/ amesh-agent daemon + remote shell
cli/ — unified amesh CLI + agent daemon
sdk/ — signing fetch client + verification middleware
relay/ — WebSocket relay for device pairing
```
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,7 @@ app.use(amesh.verify());
| Package | Description |
|---------|-------------|
| [`@authmesh/sdk`](./packages/sdk) | Signing fetch client + Express verification middleware |
| [`@authmesh/cli`](./packages/cli) | CLI: `init`, `listen`, `invite`, `list`, `revoke`, `provision`, `grant`, `shell` |
| [`@authmesh/agent`](./packages/agent) | Agent daemon + full CLI: all CLI commands + `agent start` |
| [`@authmesh/cli`](./packages/cli) | CLI + agent: `init`, `listen`, `invite`, `list`, `revoke`, `provision`, `grant`, `shell`, `agent start/stop`, `reset` |
| [`@authmesh/core`](./packages/core) | Crypto primitives: sign, verify, canonical string, nonce, HMAC, HKDF, ECDH |
| [`@authmesh/keystore`](./packages/keystore) | Key storage drivers: Secure Enclave, macOS Keychain, TPM 2.0, encrypted file |
| [`@authmesh/relay`](./packages/relay) | WebSocket relay for device pairing handshakes |
Expand Down
35 changes: 5 additions & 30 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions docs/architecture-decisions.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,9 @@ The controller CLI displays this code; the target CLI prompts the operator to en

## ADR-011: Remote shell in the CLI with explicit shell permission

> **Status: Partially superseded (2026-04-05).** The single-package design was reversed: the agent daemon now ships in a separate `@authmesh/agent` package exposing an `amesh-agent` binary, while `@authmesh/cli` (`amesh`) keeps the controller-side commands (`init`, `list`, `invite`, `shell`, etc.) without the daemon.
> **Status: Partially superseded (2026-04-05).** The single-package design was reversed: the agent daemon now ships in a separate `@authmesh/cli` package exposing an `amesh` binary, while `@authmesh/cli` (`amesh`) keeps the controller-side commands (`init`, `list`, `invite`, `shell`, etc.) without the daemon.
>
> **Why the split:** the daemon uses `Bun.spawn({ terminal })` for PTY support, a Bun-only API. Bundling it with `@authmesh/cli` forced the entire controller install to depend on Bun even for users who only wanted `amesh init` + `amesh.fetch()`. Splitting lets `@authmesh/cli` ship a Node-compatible CLI and `@authmesh/agent` ship a Bun-dependent (or prebuilt-binary-only) daemon. The per-architecture prebuilt binaries are produced by the same release pipeline, so end users `brew install ameshdev/tap/amesh` to get both.
> **Why the split:** the daemon uses `Bun.spawn({ terminal })` for PTY support, a Bun-only API. Bundling it with `@authmesh/cli` forced the entire controller install to depend on Bun even for users who only wanted `amesh init` + `amesh.fetch()`. Splitting lets `@authmesh/cli` ship a Node-compatible CLI and `@authmesh/cli` ship a Bun-dependent (or prebuilt-binary-only) daemon. The per-architecture prebuilt binaries are produced by the same release pipeline, so end users `brew install ameshdev/tap/amesh` to get both.
>
> **The security argument below is unchanged:** `amesh grant --shell` is still the real boundary, not the package boundary. The split is purely a runtime-dependency concern.

Expand All @@ -181,7 +181,7 @@ The controller CLI displays this code; the target CLI prompts the operator to en

2. **Explicit consent:** Pairing for API authentication (`amesh invite`) does not grant shell access. A `permissions.shell` flag in the allow list defaults to `false`. The target admin must explicitly run `amesh grant <device-id> --shell`. This is the security boundary, not the package boundary.

3. **The daemon is opt-in by invocation:** `amesh-agent agent start` must be explicitly run. It doesn't auto-start, doesn't install as a service, and refuses to run as root without `--allow-root`.
3. **The daemon is opt-in by invocation:** `amesh agent start` must be explicitly run. It doesn't auto-start, doesn't install as a service, and refuses to run as root without `--allow-root`.

**Security design choices:**

Expand All @@ -194,7 +194,7 @@ The controller CLI displays this code; the target CLI prompts the operator to en
- **Per-controller session limits** — prevents DoS by authorized-but-misbehaving peers

**Rejected alternatives (at the time of the original decision):**
- ~~Separate `@authmesh/agent` package — adds install confusion without meaningful security benefit; the permission gate (`amesh grant --shell`) is the real security boundary, not the package boundary~~ *This was later reversed — see the Status note above. The runtime-dependency concern (Bun for PTY) outweighed the install-confusion concern once prebuilt binaries were shipped via the release pipeline.*
- ~~Separate `@authmesh/cli` package — adds install confusion without meaningful security benefit; the permission gate (`amesh grant --shell`) is the real security boundary, not the package boundary~~ *This was later reversed — see the Status note above. The runtime-dependency concern (Bun for PTY) outweighed the install-confusion concern once prebuilt binaries were shipped via the release pipeline.*
- Auto-granting shell on pairing — violates principle of least privilege
- Reusing pairing handshake's random-nonce encryption — birthday-bound risk over long sessions
- Session resumption — complexity and nonce-reuse risk outweigh the latency benefit
Expand Down
2 changes: 1 addition & 1 deletion docs/remote-shell-security-review.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ This is the same traffic analysis SSH faces over any network. It's not fixable w

**Not in spec.**

**Problem:** The agent logs `[amesh-agent] shell opened by am_3d9f — command: uptime`. If the command contains ANSI escape sequences, it could corrupt log files or exploit log viewers (terminal escape injection).
**Problem:** The agent logs `[amesh agent] shell opened by am_3d9f — command: uptime`. If the command contains ANSI escape sequences, it could corrupt log files or exploit log viewers (terminal escape injection).

**Fix:** Sanitize the logged command string (strip non-printable characters, truncate to 200 chars).

Expand Down
Loading
Loading