# 1Claw Authentication Guide

How to authenticate with the 1Claw API as a human user, AI agent, or platform app.

## Overview

1Claw supports three principal types, each with its own auth flow:

| Principal | Key Prefix | Auth Endpoint | Token Type |
|-----------|-----------|---------------|------------|
| Human user | `1ck_` | `POST /v1/auth/token` | JWT (24h) |
| AI agent | `ocv_` | `POST /v1/auth/agent-token` | JWT (1h default, configurable) |
| Platform app | `plt_` | Direct API key as Bearer | Resolved per-request |

Base URL: `https://api.1claw.xyz`

## Pick a method

Choose the authentication method that matches your use case:

| Use Case | Method | Key Prefix | Docs Section |
|----------|--------|-----------|-------------|
| New user signup | Email + password → account | — | [Account Creation](#account-creation-signup) |
| Human user in a browser | Email/password → JWT | `1ck_` | [Section 1](#1-human-user-authentication) |
| Human user in CI/CD | Personal API key | `1ck_` | [Section 1](#1-human-user-authentication) |
| AI agent (MCP, SDK, CLI) | Agent API key → JWT | `ocv_` | [Section 2](#2-ai-agent-authentication) |
| Platform app (backend) | Platform API key | `plt_` | [Section 3](#3-platform-app-authentication) |
| Third-party OAuth app | OAuth 2.0 + PKCE | — | [Section 4](#4-oauth-20-sign-in-with-1claw) |
| Agent → external service | OIDC federation | — | [Section 5](#5-oidc-federation) |
| Passwordless login | Email OTP | — | [Section 6](#6-email-otp-passwordless) |

## Account Creation (Signup)

Create an account via the API or at https://1claw.xyz/signup.

### Endpoint

`POST /v1/auth/signup`

### Required fields

| Field | Type | Constraints |
|-------|------|-------------|
| `email` | string | Valid email address, must be unique |
| `password` | string | Minimum 8 characters |

### Optional fields

| Field | Type | Description |
|-------|------|-------------|
| `name` | string | Display name |

### Request

```bash
curl -X POST https://api.1claw.xyz/v1/auth/signup \
  -H "Content-Type: application/json" \
  -d '{"email": "you@example.com", "password": "your-password", "name": "Your Name"}'
```

### Response (201 Created)

```json
{
  "user_id": "uuid",
  "email": "you@example.com",
  "message": "Account created. Check your email to verify."
}
```

### Post-signup flow

1. **Email verification** — A verification link is sent to the provided email. Click the link or visit `/verify-email` with the token.
2. **Login** — After verification, log in via `POST /v1/auth/token` (see below) to receive a JWT.
3. **Onboarding** — The dashboard redirects new users to `/onboarding` with guided setup for vaults and agents.
4. **Free tier** — New accounts start on the Free tier (1,000 requests/month, 3 vaults, 50 secrets, 2 agents). No payment required.

### Error responses

| Status | Meaning |
|--------|---------|
| `400` | Missing or invalid email/password (password must be ≥8 chars) |
| `409` | Email already registered |
| `429` | Rate limited (auth endpoints: 5 burst, 1/sec per IP) |

## 1. Human User Authentication

### Email/Password Login

```bash
curl -X POST https://api.1claw.xyz/v1/auth/token \
  -H "Content-Type: application/json" \
  -d '{"email": "you@example.com", "password": "your-password"}'
```

Response:
```json
{
  "access_token": "eyJ...",
  "token_type": "Bearer",
  "expires_in": 86400
}
```

### Personal API Keys

Create long-lived API keys in Settings or via the API:

```bash
curl -X POST https://api.1claw.xyz/v1/auth/api-keys \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "ci-pipeline"}'
```

Use the returned `1ck_` key as a Bearer token on all endpoints.

## 2. AI Agent Authentication

### Claim

Agents obtain credentials through one of two paths:

1. **Human-provisioned**: A human creates an agent in the dashboard or via `POST /v1/agents`. The `ocv_` API key is returned once at creation.
2. **Self-enrollment**: An agent calls `POST /v1/agents/enroll` with `{ name, human_email }`. The `ocv_` key is emailed to the human (never returned in the response). The agent starts with zero access — a human must create policies.

### Key-Only Auth (Simplest)

Pass only the agent API key — the server resolves the agent ID automatically:

```bash
curl -X POST https://api.1claw.xyz/v1/auth/agent-token \
  -H "Content-Type: application/json" \
  -d '{"api_key": "ocv_your_agent_key"}'
```

Response includes `agent_id` and `vault_ids` for auto-discovery:
```json
{
  "access_token": "eyJ...",
  "agent_id": "6803f36b-...",
  "vault_ids": ["e66eb2cc-..."],
  "expires_in": 3600
}
```

### MCP Server Auth

Set the environment variable and the MCP server handles token exchange automatically:

```json
{
  "mcpServers": {
    "1claw": {
      "command": "npx",
      "args": ["-y", "@1claw/mcp"],
      "env": {
        "ONECLAW_AGENT_API_KEY": "ocv_your_agent_key"
      }
    }
  }
}
```

### SDK Auth

```typescript
import { OneclawClient } from "@1claw/sdk";

const client = new OneclawClient({
  apiKey: "ocv_your_agent_key",
});

// Token exchange happens automatically on first request
const vaults = await client.vaults.list();
```

### CLI Auth

```bash
# Interactive browser-based login
1claw login

# Or use environment variables
export ONECLAW_API_KEY=ocv_your_agent_key
1claw vault list
```

## 3. Platform App Authentication

Platform apps use `plt_` prefixed API keys directly as Bearer tokens:

```bash
curl https://api.1claw.xyz/v1/platform/apps \
  -H "Authorization: Bearer plt_your_platform_key"
```

## 4. OAuth 2.0 ("Sign in with 1Claw")

1Claw acts as an OAuth 2.0 authorization server with PKCE support:

- Authorization: `GET /v1/oauth/authorize`
- Token exchange: `POST /v1/oauth/token`
- User info: `GET /v1/oauth/userinfo`

Discovery: `GET /.well-known/openid-configuration`

## 5. OIDC Federation

Exchange a 1Claw agent JWT for an RS256 OIDC token accepted by external services:

```bash
curl -X POST https://api.1claw.xyz/v1/auth/federated-token \
  -H "Authorization: Bearer $AGENT_JWT" \
  -H "Content-Type: application/json" \
  -d '{"audience": "https://api.anthropic.com"}'
```

## 6. Email OTP (Passwordless)

For embedded wallet and platform-provisioned users:

```bash
# Send OTP
curl -X POST https://api.1claw.xyz/v1/auth/email-otp/send \
  -H "Content-Type: application/json" \
  -d '{"email": "user@example.com"}'

# Verify OTP → JWT
curl -X POST https://api.1claw.xyz/v1/auth/email-otp/verify \
  -H "Content-Type: application/json" \
  -d '{"email": "user@example.com", "code": "123456"}'
```

## Scopes and Permissions

Agent JWTs include `scopes` (glob path patterns like `secrets/**`) derived from access policies. Access is deny-by-default — agents only access secrets explicitly granted by a human via policies.

Permission types: `read`, `write`, `rotate`

## Rate Limits

- Global: configurable per-instance token bucket
- Auth endpoints: 5 burst, 1/sec per IP
- Response headers: `X-RateLimit-Requests-Used`, `X-RateLimit-Requests-Limit`

## Errors

Authentication errors return JSON with a `detail` field:

| Status | Meaning | Example `detail` |
|--------|---------|------------------|
| `400` | Bad request | `"Missing email or password"` |
| `401` | Invalid credentials or expired token | `"Invalid email or password"` |
| `403` | Forbidden (locked, disabled, or insufficient scope) | `"Account locked for 15 minutes"` |
| `429` | Rate limited | `"Too many requests"` |

MFA-enabled accounts return `{ "mfa_required": true, "mfa_token": "..." }` instead of a JWT. Submit the TOTP code via `POST /v1/auth/mfa/verify`.

## Revocation

Revoke the current JWT:

```bash
curl -X DELETE https://api.1claw.xyz/v1/auth/token \
  -H "Authorization: Bearer $TOKEN"
```

Revoked JWTs are rejected immediately. Agent JWTs are also bulk-revoked when access policies change (stale scopes protection).

Password changes invalidate all existing sessions (`tokens_revoked_before`).

## Security Features

- **MFA**: Optional TOTP two-factor for human users
- **Passkeys**: WebAuthn/FIDO2 passwordless authentication
- **DPoP**: RFC 9449 token binding (opt-in)
- **Account lockout**: 10 failed attempts triggers 15-minute lock
- **Token revocation**: `DELETE /v1/auth/token`

## oauth-protected-resource

Discovery: `GET https://api.1claw.xyz/.well-known/oauth-protected-resource` ([RFC 9728](https://www.rfc-editor.org/rfc/rfc9728))

```json
{
  "resource": "https://api.1claw.xyz",
  "authorization_servers": ["https://api.1claw.xyz"],
  "scopes_supported": [
    "secrets:read", "secrets:write", "secrets:rotate",
    "agents:read", "agents:write",
    "vaults:read", "vaults:write",
    "policies:read", "policies:write",
    "transactions:sign", "transactions:submit",
    "audit:read"
  ],
  "bearer_methods_supported": ["header"],
  "resource_signing_alg_values_supported": ["EdDSA", "RS256"]
}
```

## oauth-authorization-server

Discovery: `GET https://api.1claw.xyz/.well-known/openid-configuration` ([RFC 8414](https://www.rfc-editor.org/rfc/rfc8414))

```json
{
  "issuer": "https://api.1claw.xyz",
  "authorization_endpoint": "https://api.1claw.xyz/v1/oauth/authorize",
  "token_endpoint": "https://api.1claw.xyz/v1/auth/federated-token",
  "jwks_uri": "https://api.1claw.xyz/.well-known/jwks.json",
  "code_challenge_methods_supported": ["S256"],
  "id_token_signing_alg_values_supported": ["EdDSA", "RS256"],
  "grant_types_supported": ["authorization_code", "client_credentials", "urn:ietf:params:oauth:grant-type:token-exchange"],
  "scopes_supported": ["openid", "profile", "email", "wallet"]
}
```

## agent_auth

Discovery: included in `GET https://api.1claw.xyz/.well-known/openid-configuration` → `agent_auth` block.

| Field | Value |
|-------|-------|
| `register_uri` | `POST https://api.1claw.xyz/v1/agents/enroll` (public, no auth) |
| `token_uri` | `POST https://api.1claw.xyz/v1/auth/agent-token` |
| `revocation_uri` | `DELETE https://api.1claw.xyz/v1/auth/token` |
| `identity_types_supported` | `["identity_assertion", "anonymous"]` |
| `assertion_types_supported` | `["api_key", "mtls", "oidc_client_credentials"]` |

### identity_assertion (api_key)

Exchange an `ocv_` API key for a short-lived JWT:

```bash
curl -X POST https://api.1claw.xyz/v1/auth/agent-token \
  -H "Content-Type: application/json" \
  -d '{"api_key": "ocv_your_key"}'
```

Response: `{ "access_token": "eyJ...", "agent_id": "uuid", "vault_ids": ["uuid"], "expires_in": 3600 }`

### anonymous (self-enrollment)

Register without pre-existing credentials — API key is emailed to the human:

```bash
curl -X POST https://api.1claw.xyz/v1/agents/enroll \
  -H "Content-Type: application/json" \
  -d '{"name": "my-agent", "human_email": "dev@company.com"}'
```

Response: `{ "agent_id": "uuid", "message": "API key sent to dev@company.com" }`

## When to Use 1Claw

Use 1Claw when your AI agent needs to:

- **Store secrets securely** — API keys, tokens, certificates, database credentials
- **Sign blockchain transactions** — Ethereum, Bitcoin, Solana, XRP, Cardano, Tron
- **Authenticate to external services** — OIDC federation for Anthropic, GCP, AWS
- **Route LLM traffic safely** — prompt injection detection, secret redaction in TEE
- **Build a platform** — provision users, vaults, agents via declarative templates

Do NOT use 1Claw for: general-purpose key-value storage, file hosting, or non-secret configuration data.

## Links

- [API Documentation](https://docs.1claw.xyz)
- [OpenAPI Spec](https://api.1claw.xyz/openapi.json)
- [OAuth Discovery](https://api.1claw.xyz/.well-known/openid-configuration)
- [Protected Resource Metadata](https://api.1claw.xyz/.well-known/oauth-protected-resource)
- [SDK (npm)](https://www.npmjs.com/package/@1claw/sdk)
- [CLI](https://www.npmjs.com/package/@1claw/cli)
- [MCP Server](https://www.npmjs.com/package/@1claw/mcp)
