Device-bound M2M authentication. Replace API keys with cryptographic device identity.
No .env files. No secrets in CI. No tokens in Slack. The private key stays on your device --- there is nothing to leak.
// Before: static secret that can leak
fetch("/api/orders", {
headers: { Authorization: `Bearer ${process.env.API_KEY}` }
});// After: device-bound signature, nothing to leak
import { amesh } from '@authmesh/sdk';
amesh.fetch("/api/orders", {
method: "POST",
body: JSON.stringify({ amount: 100 })
});No .env. No secret. The request is signed with a P-256 ECDSA key that never leaves your machine.
npm install @authmesh/sdk # signing client + verification middleware
npm install -g @authmesh/cli # CLI for device managementamesh init --name "prod-api"
# Identity created.
# Device ID : am_cOixWcOdI8-pLh4P
# Backend : Secure Enclave
# Friendly Name : prod-apiOn the target (server):
amesh listen
# Pairing code: 482916
# Enter the 6-digit code shown on the Controller.
# Verification code: 847291
# ✔ "my-laptop" added as controller.On the controller (your laptop):
amesh invite 482916
# Verification code: 847291
# Enter this code on the Target device.
# ✔ "prod-api" added as target.Trust is one-way: the controller can authenticate to the target, but not the reverse.
Remote device? If you can't run interactive commands on the target, use
amesh provisionto generate a bootstrap token instead. See the Integration Guide.
import { amesh } from '@authmesh/sdk';
const res = await amesh.fetch('https://api.example.com/data', {
method: 'POST',
body: JSON.stringify({ amount: 100 })
});import { amesh } from '@authmesh/sdk';
app.use(amesh.verify());
// req.authMesh.deviceId, req.authMesh.friendlyName available- Device identity --- each machine gets a unique P-256 ECDSA keypair. The private key is protected by the OS keychain (macOS), TPM 2.0 (Linux), or an encrypted file (cloud VMs) and never leaves the device.
- One-way trust --- controllers authenticate to targets, never the reverse. A compromised server cannot call back to your laptop.
- Signed requests --- every HTTP request is signed with the device's private key. The signature covers method, path, timestamp, nonce, and body.
- Replay protection --- each request has a unique nonce and a 30-second timestamp window. Nonces are tracked server-side.
- No static secrets --- there is no string to leak, rotate, or share. Revoke a compromised device instantly with
amesh revoke.
| Package | Description |
|---|---|
@authmesh/sdk |
Signing fetch client + Express verification middleware |
@authmesh/cli |
CLI: init, listen, invite, list, revoke, provision |
@authmesh/core |
Crypto primitives: sign, verify, canonical string, nonce, HMAC, HKDF, ECDH |
@authmesh/keystore |
Key storage drivers: Secure Enclave, macOS Keychain, TPM 2.0, encrypted file |
@authmesh/relay |
WebSocket relay for device pairing handshakes |
[Pairing — one time]
Target (server) <--WebSocket--> Relay <--WebSocket--> Controller (laptop)
(P-256 ECDH + ChaCha20-Poly1305 + SAS verification)
[Runtime — every request]
Controller ----HTTP + AuthMesh header----> Target
(one-way trust, no relay, stateless)
The relay is only needed for the initial pairing handshake. After devices exchange public keys, all authentication is stateless HTTP headers. Trust is one-way: controllers authenticate to targets, but targets cannot authenticate back. The relay can be shut down and all existing pairings continue working.
amesh is fully self-contained. No SaaS, no telemetry, no phone-home.
- Install packages from npm (MIT licensed)
- Run your own relay: Docker, Cloud Run, Fly.io, Kubernetes, or plain Bun
- All data stays on your machines (
~/.amesh/)
See the Self-Hosting Guide for deployment options.
| Doc | Description |
|---|---|
| Integration Guide | Recipes for Express, microservices, webhooks, remote pairing |
| Self-Hosting Guide | Deploy the relay: Docker, Cloud Run, Fly.io, Kubernetes |
| Usage Guide | CLI commands, SDK usage, crypto primitives |
| Protocol Spec | Full protocol specification (v2.0.0) |
| Architecture Decisions | ADRs for every design choice |
| Why amesh | The problem amesh solves |
amesh currently provides a TypeScript/Node.js SDK. The protocol is language-agnostic (standard HTTP headers + ECDSA-P256 signatures), so verification can be implemented in any language. SDKs for Python and Go are planned.
amesh is designed to be easy to integrate with AI coding assistants like Claude, Copilot, and Cursor. The packages have full TypeScript types, and the API surface is minimal.
Example prompts:
- "Help me protect my Express API with amesh instead of API keys"
- "Set up
amesh.fetch()in my Node.js service to call an authenticated endpoint" - "Configure amesh with Redis nonce store for a multi-instance production deployment"
- "Add amesh device authentication to my microservices"
The SDK has two main functions: amesh.fetch() (client) and amesh.verify() (server middleware). That's it.
bun install # install all deps
bun run build # turbo build (tsc -b per package)
bun run test # tests across all packages
bun run lint # eslint + prettier