---
title: "Tunnel Enroll"
method: POST
path: "/tunnel/enroll"
---

# Tunnel Enroll

`POST /tunnel/enroll`

## Request

- Base URL: `https://api.local-mcp.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.local-mcp.com/tunnel/enroll`
- Auth: none declared

Bind a device public key to a machine_id (ADR-0009). The private key never leaves the
device (Secure Enclave on Mac); this only ever receives the PUBLIC key + a proof of the
right to enroll it. Additive alongside the bearer token during the migration window.

proof.kind:
  - "tofu"   : first enroll for a machine (no live key yet). First-wins; a second tofu is
               refused. TOFU is safe because enrollment happens at install, before the
               machine_id is exposed to any AI.
  - "bearer" : migration — the machine's existing bearer token proves ownership; binds the
               key and supersedes the token as the auth path.
  - "sig"    : rotation — signed by the CURRENT live key over enroll_message(mid, new_pub);
               only the old key's holder can swap it, and the old key dies.

## Request body

- TunnelEnrollRequest
  - `machine_id` string
  - `public_key` string
  - `alg` string
  - `proof` object

## Response `200`

Successful Response

- unknown

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/local-mcp/apis/lmcp-api.md) · [All operations](https://skmtc.dev/local-mcp/apis/lmcp-api/llms.txt) · [OpenAPI document](https://skmtc.dev/local-mcp/apis/lmcp-api/revisions/f1f1c502623a?raw)
