# @lifeaitools/clauth

Hardware-bound credential vault for the LIFEAI stack. Your machine is the second factor. Keys live in Supabase Vault (AES-256). Nothing sensitive ever touches a config file.

---

## Install

```bash
npm install -g @lifeaitools/clauth
```

Then provision your Supabase project:

```bash
clauth install
```

That's it. `clauth install` handles everything:
- Creates all database tables
- Deploys the `auth-vault` Edge Function
- Generates HMAC salt + bootstrap token
- Tests the connection end-to-end
- Installs the Claude skill

At the end it prints a **bootstrap token** — save it for the next step.

---

## After Install — Register Your Machine

```bash
clauth setup
```

Prompts for: machine label, password, bootstrap token (from `clauth install`).

Then verify:
```bash
clauth test      # → PASS
clauth status    # → 12 services, all NO KEY
```

### Add A New Computer

On an old computer where clauth is already registered:

```bash
clauth enroll --label "Dave-New-Laptop"
```

This creates a one-time enrollment code tied to the same `install_id` and writes
a one-time PowerShell setup script. Move that script to the new computer and run
it. The script installs clauth, enrolls the computer, installs startup, then
deletes itself. Setup defaults the machine label to the computer name and only
asks you to set the new computer's local clauth password.

The enrollment code does not copy repo credentials into the script. It lets the
new hardware-bound `machine_hash` join the shared Supabase Vault once. After the
code is redeemed, it cannot be used again.

---

## What clauth install asks for

Two things from Supabase:

**1. Project ref** — the last segment of your Supabase project URL:
`https://supabase.com/dashboard/project/` **`your-ref-here`**

**2. Personal Access Token (PAT)**:
`https://supabase.com/dashboard/account/tokens` → Generate new token

> This is **not** your anon key or service_role key — it is your account-level token.

---

## Writing Your First Key

```bash
clauth write key github     # prompts for value
clauth enable github
clauth get github
```

---

## Command Reference

```
clauth install              Provision Supabase + install Claude skill
clauth setup                Register this machine with the vault
clauth enroll               Create one-time code to add another computer
clauth status               All services + state
clauth search <query>       Find services by name, project, description, or type
clauth search <query> --addresses
                            Also search redacted address hints (may read multiple secrets)
clauth test                 Verify connection

clauth write key <service>  Store a credential
clauth write pw             Change password
clauth enable <svc|all>     Activate service
clauth disable <svc|all>    Suspend service
clauth get <service>        Retrieve a key
clauth npm whoami           Verify npm token without PowerShell secret plumbing
clauth npm sync-github-secret LIFEAI/rdc-skills
                            Update GitHub NPM_TOKEN from clauth

clauth add service <n>      Register new service
clauth remove service <n>   Remove service
clauth revoke <svc|all>     Delete key (destructive)
```

## Built-in Services

`github` `supabase-anon` `supabase-service` `supabase-db`
`vercel` `namecheap` `neo4j` `anthropic`
`r2` `r2-bucket` `cloudflare` `rocketreach`

---

## How It Works

```
Machine fingerprint (BIOS UUID + OS install ID)
  + Your clauth password
  → HMAC-SHA256 token + 5-min timestamp window
  → Supabase Edge Function validates
  → Returns AES-256 encrypted key from Vault
```

Nothing stored locally. Password never persisted. Machine hash is one-way only.

---

## Daemon Mode (`clauth serve`)

clauth runs as an HTTP daemon on `http://127.0.0.1:52437`. The daemon provides:

- **Web UI** — unlock vault, manage services, configure mounts
- **REST API** — `GET /knowledge`, `GET /status`, `GET /v/<service>`, `GET /ping`, `POST /restart`, `GET /shutdown`
- **MCP server** — Model Context Protocol for Claude Code and claude.ai
- **Cloudflare Tunnel** — exposes MCP endpoints publicly for claude.ai connectors

Start: `clauth serve start` (starts locked, auto-opens browser for unlock).

Full daemon operations reference: see `regen-root/.claude/rules/clauth.md`.

### Safe Metadata Cache

Agents and scripts must discover services through metadata endpoints, not by
walking every secret endpoint. The daemon caches service metadata for 30 seconds:

```bash
curl -s http://127.0.0.1:52437/knowledge      # sanitized, agent-safe metadata
curl -s http://127.0.0.1:52437/list-services  # names only
curl -s http://127.0.0.1:52437/status         # full daemon metadata, cached
```

`/knowledge` returns service names, labels, key types, enabled state, project,
description, timestamps, and `has_key`. It never returns raw secrets or Vault
secret names. Use `GET /v/<service>` only for the one exact secret needed by the
next command. Do not bulk-fetch every service.

---

## MCP Server — 5 Namespaces, 63 Tools

clauth is the single MCP interface for all local tools. One process, namespaced paths:

| Path | Namespace | Tools | Description |
|------|-----------|-------|-------------|
| `/clauth` | `clauth_*` + runtime helpers | 23 | Credential vault operations, safe metadata cache, and agent runtime helpers |
| `/gws` | `gws_*` | 6 | Google Workspace (Gmail, Calendar, Drive) |
| `/fs` | `fs_*` | 20 | Filesystem plus guarded git/local-branch tools |
| `/chitchat` | `chitchat_*` | 7 | Collaboration relay sessions |
| `/codevelop` | `codevelop_*` | 7 | Peer development sessions |
| `/mcp` | all | 63 | All namespaces combined (Claude Code) |

The default live `/clauth` surface includes 13 credential tools plus
`call_agent`, `monkey_dispatch`, `handoff_start`, `terminal_*`, and `channel_*`
runtime helpers. Admin write tools such as enable/disable/project/token actions
are gated by write-mode.

### clauth MCP Usage

Use `clauth_knowledge` or `clauth_status` for discovery. They use cached
metadata and never retrieve raw secrets. `clauth_search` is metadata-only by
default; pass `addresses: true` only when you intentionally need redacted address
hints from connstrings/fileserver/oauth secrets. `clauth_get` is for one exact
secret. `clauth_inject` refuses more than five services unless `allow_many: true`
is explicitly supplied, to prevent accidental rate-limit lockouts from bulk
secret sweeps.

### FS Tools

20 filesystem tools with path-jail security:
- `fs_read`, `fs_write`, `fs_stat`, `fs_append`, `fs_write_chunk`, `fs_ingest_url`, `fs_import_git_files`, `fs_list`, `fs_grep`, `fs_glob`, `fs_delete`, `fs_mkdir`, `fs_edit`, `fs_move`, `fs_copy`, `fs_mounts`, `fs_repo_status`, `fs_use_branch`, `fs_commit`, `fs_diff`
- Uses `node:fs/promises` (async), `@vscode/ripgrep` (shipped binary), `fast-glob`
- Permission flags per mount: `r` (read), `w` (write), `d` (delete)
- Mount config stored as "fileserver" service type in vault — only configurable through web UI
- Large writes should use `fs_write_chunk`; cloud-to-local transfer should use `fs_ingest_url`; guarded appends should pass `expected_sha256` from `fs_stat`
- Durable new files authored by Claude.ai in GitHub should use `fs_import_git_files` so the local dirty monorepo fetches and restores only named paths without `git pull`

### Collaboration Tools

Chitchat tools: `chitchat_start`, `chitchat_list`, `chitchat_send`, `chitchat_recv`, `chitchat_reply`, `chitchat_poll`, `chitchat_stop`

Codevelop tools: `codevelop_start`, `codevelop_join`, `codevelop_send`, `codevelop_poll`, `codevelop_status`, `codevelop_stream`, `codevelop_stop`

### GWS Tools

6 Google Workspace tools: `gws_run`, `gws_gmail_list`, `gws_gmail_read`, `gws_gmail_send`, `gws_calendar_list`, `gws_drive_list`
- Calls `gws` CLI via `execSync` with `shell: 'bash'` (fixes Windows cmd.exe JSON quoting)

---

## claude.ai Integration

### Noauth Mode (v1.5.38)

claude.ai's OAuth proxy has a confirmed bug ([anthropics/claude-code#46140](https://github.com/anthropics/claude-code/issues/46140), [anthropics/claude-ai-mcp#136](https://github.com/anthropics/claude-ai-mcp/issues/136)): it completes the token exchange but never sends the authenticated request.

**Workaround:** Noauth hosts — fresh domains where OAuth endpoints return 404. claude.ai connects directly (tunnel URL is the shared secret).

### OAuth 2.1 (v1.5.36-37)

Full OAuth 2.1 protocol implementation is present for future use when Anthropic fixes the bug:
- 401 gate with `WWW-Authenticate` header
- Dynamic client registration (public client, no secret)
- Mandatory PKCE S256
- `Cache-Control: no-store`

### Connector URLs

| Connector | URL |
|-----------|-----|
| clauth | `https://clauth.regendevcorp.com/clauth` |
| gws | `https://clauth.regendevcorp.com/gws` |
| chitchat | `https://clauth.regendevcorp.com/chitchat` |
| codevelop | `https://clauth.regendevcorp.com/codevelop` |
| fs | `https://fs.regendevcorp.com/fs` |

---

## Dependencies (notable)

- `@vscode/ripgrep` — shipped ripgrep binary for `fs_grep`
- `fast-glob` — pattern matching for `fs_glob`

---

## Testing

```bash
node test-tools.mjs    # MCP tool execution smoke tests
```

Tests actual MCP tool calls (not just OAuth + listing).

---

## Releasing a New Version (maintainers)

Publishing is **manual** — there is no auto-publish. The GitHub Actions
`publish.yml` workflow was removed on 2026-04-27 (commit `08b7751`); trusted
publishing via OIDC was tried first (`b2bf08b`→`41d2d92`) and dropped. clauth is
a **private** repo and GitHub Actions bill for minutes on private repos, so we
don't run them here (reserve Actions for *public* repos, where they're free).

```bash
# 1. Bump version in package.json
# 2. Commit + tag + push
git add -A && git commit -m "feat(...): description (vX.Y.Z)"
git tag vX.Y.Z
git push && git push --tags

# 3. Publish manually with the vault npm token
clauth npm set-local          # writes ~/.npmrc auth from the vault 'npm' service
npm publish --access public

# 4. Verify on the registry (direct check — bypasses npm's local cache)
curl -s https://registry.npmjs.org/@lifeaitools/clauth \
  | python -c "import sys,json;print(json.load(sys.stdin)['dist-tags'])"

# 5. Update the running daemon
curl -s -X POST http://127.0.0.1:52437/restart   # picks up new code, stays unlocked
```

**The tag push does NOT publish anything** — you must run step 3. A version bump
that is committed+tagged but never `npm publish`ed leaves the registry stale
(symptom: `npm view` still shows the old version after a push).

---

> Life before Profits. — LIFEAI / PRT
>
> ☕ [Support this project](https://github.com/sponsors/DaveLadouceur)
