Skip to content

ameshdev/amesh

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

123 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

amesh

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.

CI License: MIT


Before and After

// 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.


Install

npm install @authmesh/sdk          # signing client + verification middleware
npm install -g @authmesh/cli       # CLI for device management

Quickstart

1. Create a device identity

amesh init --name "prod-api"
# Identity created.
#   Device ID     : am_cOixWcOdI8-pLh4P
#   Backend       : Secure Enclave
#   Friendly Name : prod-api

2. Pair two machines

On 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 provision to generate a bootstrap token instead. See the Integration Guide.

3. Sign requests (2 lines)

import { amesh } from '@authmesh/sdk';

const res = await amesh.fetch('https://api.example.com/data', {
  method: 'POST',
  body: JSON.stringify({ amount: 100 })
});

4. Verify requests (2 lines)

import { amesh } from '@authmesh/sdk';

app.use(amesh.verify());
// req.authMesh.deviceId, req.authMesh.friendlyName available

How It Works

  • 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.

Packages

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

Architecture

[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.


Self-Hosted

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.


Documentation

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

Language Support

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.

Using amesh with AI Assistants

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.


Development

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

License

MIT

About

Device-bound M2M authentication. Replace API keys with cryptographic device identity.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors