@1claw/openclaw-plugin 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,846 @@
1
+ ---
2
+ name: 1claw
3
+ version: 1.1.0
4
+ description: HSM-backed secret management for AI agents — store, retrieve, rotate, and share secrets via the 1Claw vault without exposing them in context.
5
+ homepage: https://1claw.xyz
6
+ repository: https://github.com/1clawAI/1claw
7
+ metadata:
8
+ {
9
+ "openclaw":
10
+ {
11
+ "requires":
12
+ {
13
+ "env":
14
+ [
15
+ "ONECLAW_AGENT_ID",
16
+ "ONECLAW_AGENT_API_KEY",
17
+ "ONECLAW_VAULT_ID",
18
+ ],
19
+ "bins": [],
20
+ },
21
+ "primaryEnv": "ONECLAW_AGENT_ID",
22
+ "install":
23
+ [
24
+ {
25
+ "id": "npm",
26
+ "kind": "node",
27
+ "package": "@1claw/mcp",
28
+ "bins": ["1claw-mcp"],
29
+ "label": "1Claw MCP Server",
30
+ },
31
+ ],
32
+ "credentials": ["ONECLAW_AGENT_API_KEY"],
33
+ "optional_credentials":
34
+ ["ONECLAW_AGENT_ID", "ONECLAW_VAULT_ID"],
35
+ "permissions":
36
+ [
37
+ "vault:read",
38
+ "vault:write",
39
+ "vault:delete",
40
+ "secret:read",
41
+ "secret:write",
42
+ "secret:delete",
43
+ "policy:create",
44
+ "share:create",
45
+ "tx:sign",
46
+ "tx:simulate",
47
+ ],
48
+ },
49
+ }
50
+ ---
51
+
52
+ # 1Claw — HSM-Backed Secret Management for AI Agents
53
+
54
+ 1Claw is a cloud HSM-backed secrets manager. Agents access API keys, passwords, and credentials at runtime without them ever entering the conversation context. Secrets are encrypted with keys that never leave the HSM.
55
+
56
+ **API base URL:** `https://api.1claw.xyz`
57
+ **Shroud (TEE proxy):** `https://shroud.1claw.xyz`
58
+ **MCP endpoint:** `https://mcp.1claw.xyz/mcp`
59
+ **Dashboard:** `https://1claw.xyz`
60
+ **Docs:** `https://docs.1claw.xyz`
61
+
62
+ ## When to use this skill
63
+
64
+ - You need an API key, password, or credential to complete a task
65
+ - You want to store a newly generated credential securely
66
+ - You need to share a secret with a user or another agent
67
+ - You need to rotate a credential after regenerating it
68
+ - You want to check what secrets are available before using one
69
+ - You need to sign or simulate an EVM transaction without exposing private keys
70
+ - You want TEE-grade key isolation for transaction signing (use Shroud at `shroud.1claw.xyz`)
71
+
72
+ ---
73
+
74
+ ## Setup
75
+
76
+ ### Option 0: Self-enrollment (new agents)
77
+
78
+ If you don't have credentials yet, self-enroll — this sends them to your human:
79
+
80
+ ```bash
81
+ # curl
82
+ curl -s -X POST https://api.1claw.xyz/v1/agents/enroll \
83
+ -H "Content-Type: application/json" \
84
+ -d '{"name":"my-agent","human_email":"human@example.com"}'
85
+
86
+ # TypeScript SDK (static method, no auth needed)
87
+ import { AgentsResource } from "@1claw/sdk";
88
+ await AgentsResource.enroll("https://api.1claw.xyz", {
89
+ name: "my-agent",
90
+ human_email: "human@example.com",
91
+ });
92
+
93
+ # CLI (no auth needed)
94
+ npx @1claw/cli agent enroll my-agent --email human@example.com
95
+ ```
96
+
97
+ The human receives the Agent ID + API key by email. They then configure policies for your access.
98
+
99
+ ### Option 1: MCP server (recommended for AI agents)
100
+
101
+ Add to your MCP client configuration. Only the API key is required — agent ID and vault are auto-discovered.
102
+
103
+ ```json
104
+ {
105
+ "mcpServers": {
106
+ "1claw": {
107
+ "command": "npx",
108
+ "args": ["-y", "@1claw/mcp"],
109
+ "env": {
110
+ "ONECLAW_AGENT_API_KEY": "<agent-api-key>"
111
+ }
112
+ }
113
+ }
114
+ }
115
+ ```
116
+
117
+ Optional overrides: `ONECLAW_AGENT_ID` (explicit agent), `ONECLAW_VAULT_ID` (explicit vault).
118
+
119
+ Hosted HTTP streaming mode:
120
+
121
+ ```
122
+ URL: https://mcp.1claw.xyz/mcp
123
+ Headers:
124
+ Authorization: Bearer <agent-jwt>
125
+ X-Vault-ID: <vault-uuid>
126
+ ```
127
+
128
+ ### Option 2: TypeScript SDK
129
+
130
+ ```bash
131
+ npm install @1claw/sdk
132
+ ```
133
+
134
+ ```ts
135
+ import { createClient } from "@1claw/sdk";
136
+
137
+ const client = createClient({
138
+ baseUrl: "https://api.1claw.xyz",
139
+ apiKey: process.env.ONECLAW_AGENT_API_KEY,
140
+ });
141
+ ```
142
+
143
+ ### Option 3: Direct REST API
144
+
145
+ Authenticate, then pass the Bearer token on every request.
146
+
147
+ ```bash
148
+ # Exchange agent API key for a JWT (key-only — agent_id is auto-resolved)
149
+ RESP=$(curl -s -X POST https://api.1claw.xyz/v1/auth/agent-token \
150
+ -H "Content-Type: application/json" \
151
+ -d '{"api_key":"<key>"}')
152
+ TOKEN=$(echo "$RESP" | jq -r .access_token)
153
+ AGENT_ID=$(echo "$RESP" | jq -r .agent_id)
154
+
155
+ # Use the JWT
156
+ curl -H "Authorization: Bearer $TOKEN" https://api.1claw.xyz/v1/vaults
157
+ ```
158
+
159
+ **Alternative:** `1ck_` API keys (personal or agent) can be used directly as Bearer tokens — no JWT exchange needed.
160
+
161
+ ---
162
+
163
+ ## Authentication
164
+
165
+ ### Agent auth flow
166
+
167
+ 1. Human registers an agent in the dashboard or via `POST /v1/agents` with an `auth_method` (`api_key` default, `mtls`, or `oidc_client_credentials`). For `api_key` agents → receives `agent_id` + `api_key` (prefix `ocv_`). For mTLS/OIDC agents → receives `agent_id` only (no API key).
168
+ 2. All agents auto-receive an Ed25519 SSH keypair (public key on agent record, private key in `__agent-keys` vault).
169
+ 3. API key agents exchange credentials: `POST /v1/auth/agent-token` with `{ "api_key": "<key>" }` (or `{ "agent_id": "<uuid>", "api_key": "<key>" }`) → returns `{ "access_token": "<jwt>", "expires_in": 3600, "agent_id": "<uuid>", "vault_ids": ["..."] }`. Agent ID is optional — the server resolves it from the key prefix.
170
+ 4. Agent uses `Authorization: Bearer <jwt>` on all subsequent requests.
171
+ 5. JWT scopes derive from the agent's access policies (path patterns). If no policies exist, scopes are empty (zero access). The agent's `vault_ids` are also included in the JWT — requests to unlisted vaults are rejected.
172
+ 6. Token TTL defaults to ~1 hour but can be set per-agent via `token_ttl_seconds`. The MCP server auto-refreshes 60s before expiry.
173
+
174
+ ### API key auth
175
+
176
+ Tokens starting with `1ck_` (human personal API keys) or `ocv_` (agent API keys) can be used as Bearer tokens directly on any authenticated endpoint.
177
+
178
+ ---
179
+
180
+ ## MCP Tools Reference
181
+
182
+ ### list_secrets
183
+
184
+ List all secrets in the vault. Returns paths, types, and versions — never values.
185
+
186
+ | Parameter | Type | Required | Description |
187
+ | --------- | ------ | -------- | ---------------------------------------- |
188
+ | `prefix` | string | no | Path prefix to filter (e.g. `api-keys/`) |
189
+
190
+ ### get_secret
191
+
192
+ Fetch the decrypted value of a secret. Use immediately before the API call that needs it. Never store the value or include it in summaries.
193
+
194
+ | Parameter | Type | Required | Description |
195
+ | --------- | ------ | -------- | ------------------------------------ |
196
+ | `path` | string | yes | Secret path (e.g. `api-keys/stripe`) |
197
+
198
+ ### put_secret
199
+
200
+ Store a new secret or update an existing one. Each call creates a new version.
201
+
202
+ | Parameter | Type | Required | Default | Description |
203
+ | ------------------ | ------ | -------- | --------- | ---------------------------------------------------------------------------------------------------- |
204
+ | `path` | string | yes | | Secret path |
205
+ | `value` | string | yes | | The secret value |
206
+ | `type` | string | no | `api_key` | One of: `api_key`, `password`, `private_key`, `certificate`, `file`, `note`, `ssh_key`, `env_bundle` |
207
+ | `metadata` | object | no | | Arbitrary JSON metadata |
208
+ | `expires_at` | string | no | | ISO 8601 expiry datetime |
209
+ | `max_access_count` | number | no | | Max reads before auto-expiry (0 = unlimited) |
210
+
211
+ ### delete_secret
212
+
213
+ Soft-delete a secret. Reversible by an admin.
214
+
215
+ | Parameter | Type | Required | Description |
216
+ | --------- | ------ | -------- | --------------------- |
217
+ | `path` | string | yes | Secret path to delete |
218
+
219
+ ### describe_secret
220
+
221
+ Get metadata (type, version, expiry) without fetching the value. Use to check existence.
222
+
223
+ | Parameter | Type | Required | Description |
224
+ | --------- | ------ | -------- | ----------- |
225
+ | `path` | string | yes | Secret path |
226
+
227
+ ### rotate_and_store
228
+
229
+ Store a new value for an existing secret, creating a new version. Use after regenerating a key.
230
+
231
+ | Parameter | Type | Required | Description |
232
+ | --------- | ------ | -------- | ---------------- |
233
+ | `path` | string | yes | Secret path |
234
+ | `value` | string | yes | New secret value |
235
+
236
+ ### get_env_bundle
237
+
238
+ Fetch an `env_bundle` secret and parse its `KEY=VALUE` lines as JSON.
239
+
240
+ | Parameter | Type | Required | Description |
241
+ | --------- | ------ | -------- | ------------------------------ |
242
+ | `path` | string | yes | Path to an `env_bundle` secret |
243
+
244
+ ### create_vault
245
+
246
+ Create a new vault for organizing secrets.
247
+
248
+ | Parameter | Type | Required | Description |
249
+ | ------------- | ------ | -------- | ------------------------ |
250
+ | `name` | string | yes | Vault name (1–255 chars) |
251
+ | `description` | string | no | Short description |
252
+
253
+ ### list_vaults
254
+
255
+ List all vaults accessible to you. No parameters.
256
+
257
+ ### grant_access
258
+
259
+ Grant a user or agent access to a vault path pattern.
260
+
261
+ | Parameter | Type | Required | Default | Description |
262
+ | --------------------- | ----------------- | -------- | ---------- | ---------------------------------------------- |
263
+ | `vault_id` | string (UUID) | yes | | Vault ID |
264
+ | `principal_type` | `user` \| `agent` | yes | | Who to grant access to |
265
+ | `principal_id` | string (UUID) | yes | | The user or agent UUID |
266
+ | `permissions` | string[] | no | `["read"]` | `["read"]`, `["write"]`, or `["read","write"]` |
267
+ | `secret_path_pattern` | string | no | `**` | Glob pattern for secret paths |
268
+
269
+ ### share_secret
270
+
271
+ Share a secret via link, with your creator, or with a specific user/agent.
272
+
273
+ | Parameter | Type | Required | Description |
274
+ | ------------------ | ---------------------------------------------------- | -------------- | ------------------------------------------------------------------------ |
275
+ | `secret_id` | string (UUID) | yes | The secret's UUID |
276
+ | `recipient_type` | `user` \| `agent` \| `anyone_with_link` \| `creator` | yes | `creator` shares with the human who registered this agent — no ID needed |
277
+ | `recipient_id` | string (UUID) | conditional | Required for `user` and `agent` types |
278
+ | `expires_at` | string | yes | ISO 8601 expiry |
279
+ | `max_access_count` | number | no (default 5) | Max reads (0 = unlimited) |
280
+
281
+ Targeted shares (creator/user/agent) require the recipient to explicitly accept before access.
282
+
283
+ ### simulate_transaction
284
+
285
+ Simulate an EVM transaction via Tenderly without signing. Returns balance changes, gas estimates, success/revert status.
286
+
287
+ | Parameter | Type | Required | Default | Description |
288
+ | ------------------ | ------ | -------- | --------------------- | --------------------------------------------- |
289
+ | `to` | string | yes | | Destination address (0x-prefixed) |
290
+ | `value` | string | yes | | Value in ETH (e.g. `"0.01"`) |
291
+ | `chain` | string | yes | | Chain name or chain ID (see Supported Chains) |
292
+ | `data` | string | no | | Hex-encoded calldata |
293
+ | `signing_key_path` | string | no | `keys/{chain}-signer` | Vault path to signing key |
294
+ | `gas_limit` | number | no | 21000 | Gas limit |
295
+
296
+ ### submit_transaction
297
+
298
+ Submit an EVM transaction for signing and optional broadcast. Requires `intents_api_enabled`.
299
+
300
+ | Parameter | Type | Required | Default | Description |
301
+ | -------------------------- | ------- | -------- | --------------------- | ----------------------------------------- |
302
+ | `to` | string | yes | | Destination address |
303
+ | `value` | string | yes | | Value in ETH |
304
+ | `chain` | string | yes | | Chain name or chain ID |
305
+ | `data` | string | no | | Hex-encoded calldata |
306
+ | `signing_key_path` | string | no | `keys/{chain}-signer` | Vault path to signing key |
307
+ | `nonce` | number | no | auto-resolved | Transaction nonce |
308
+ | `gas_price` | string | no | | Gas price in wei (legacy mode) |
309
+ | `gas_limit` | number | no | 21000 | Gas limit |
310
+ | `max_fee_per_gas` | string | no | | EIP-1559 max fee in wei (triggers Type 2) |
311
+ | `max_priority_fee_per_gas` | string | no | | EIP-1559 priority fee in wei |
312
+ | `simulate_first` | boolean | no | true | Run Tenderly simulation before signing |
313
+
314
+ ---
315
+
316
+ ## REST API Quick Reference
317
+
318
+ Base URL: `https://api.1claw.xyz`. All authenticated endpoints require `Authorization: Bearer <token>`.
319
+
320
+ ### Auth (public — no token required)
321
+
322
+ | Method | Path | Description |
323
+ | ------ | ----------------------- | ----------------------------------------------------- |
324
+ | `POST` | `/v1/auth/token` | Login (email + password) → `{ access_token }` |
325
+ | `POST` | `/v1/auth/agent-token` | Agent login (agent_id + api_key) → `{ access_token }` |
326
+ | `POST` | `/v1/auth/google` | Google OAuth |
327
+ | `POST` | `/v1/auth/signup` | Create account → sends verification email |
328
+ | `POST` | `/v1/auth/verify-email` | Verify email token → creates user |
329
+ | `POST` | `/v1/auth/mfa/verify` | Verify MFA code during login |
330
+
331
+ ### Auth (authenticated)
332
+
333
+ | Method | Path | Description |
334
+ | -------- | -------------------------- | ---------------------------------------------------------------- |
335
+ | `GET` | `/v1/auth/me` | Get current user profile |
336
+ | `PATCH` | `/v1/auth/me` | Update profile (`display_name`, `marketing_emails`) |
337
+ | `DELETE` | `/v1/auth/me` | Delete account (body: `{ "confirmation": "DELETE MY ACCOUNT" }`) |
338
+ | `DELETE` | `/v1/auth/token` | Revoke current token |
339
+ | `POST` | `/v1/auth/change-password` | Change password |
340
+
341
+ ### Vaults
342
+
343
+ | Method | Path | Description |
344
+ | -------- | -------------------------------------- | --------------------------------------------------------------------- |
345
+ | `POST` | `/v1/vaults` | Create vault (`{ name, description? }`) → `201` |
346
+ | `GET` | `/v1/vaults` | List vaults → `{ vaults: [...] }` |
347
+ | `GET` | `/v1/vaults/{id}` | Get vault details |
348
+ | `DELETE` | `/v1/vaults/{id}` | Delete vault → `204` |
349
+ | `POST` | `/v1/vaults/{id}/cmek` | Enable CMEK (`{ fingerprint }`) |
350
+ | `DELETE` | `/v1/vaults/{id}/cmek` | Disable CMEK |
351
+ | `POST` | `/v1/vaults/{id}/cmek-rotate` | Start CMEK key rotation (headers: `X-CMEK-Old-Key`, `X-CMEK-New-Key`) |
352
+ | `GET` | `/v1/vaults/{id}/cmek-rotate/{job_id}` | Get rotation job status |
353
+
354
+ ### Secrets
355
+
356
+ | Method | Path | Description |
357
+ | -------- | ------------------------------------ | ------------------------------------------------------------------------------------------ |
358
+ | `PUT` | `/v1/vaults/{id}/secrets/{path}` | Store/update secret (`{ type, value, metadata?, expires_at?, max_access_count? }`) → `201` |
359
+ | `GET` | `/v1/vaults/{id}/secrets/{path}` | Read secret → `{ path, type, value, version, metadata }` |
360
+ | `DELETE` | `/v1/vaults/{id}/secrets/{path}` | Delete secret → `204` |
361
+ | `GET` | `/v1/vaults/{id}/secrets?prefix=...` | List secrets (metadata only, no values) |
362
+
363
+ ### Agents
364
+
365
+ | Method | Path | Description |
366
+ | -------- | -------------------------------------- | -------------------------------------------------------------------------- |
367
+ | `POST` | `/v1/agents` | Create agent → `{ agent: {...}, api_key: "ocv_..." }` |
368
+ | `GET` | `/v1/agents` | List agents → `{ agents: [...] }` |
369
+ | `GET` | `/v1/agents/{id}` | Get agent |
370
+ | `GET` | `/v1/agents/me` | Get current agent (self) |
371
+ | `PATCH` | `/v1/agents/{id}` | Update agent (is_active, scopes, intents_api_enabled, guardrails) |
372
+ | `DELETE` | `/v1/agents/{id}` | Delete agent → `204` |
373
+ | `POST` | `/v1/agents/{id}/rotate-key` | Rotate agent API key → `{ api_key: "ocv_..." }` |
374
+ | `POST` | `/v1/agents/{id}/rotate-identity-keys` | Rotate agent SSH + ECDH keypairs (user-only; keys in `__agent-keys` vault) |
375
+
376
+ ### Policies (Access Control)
377
+
378
+ | Method | Path | Description |
379
+ | -------- | -------------------------------- | -------------------------------------------------------------------------------------------------------------- |
380
+ | `POST` | `/v1/vaults/{id}/policies` | Create policy (`{ principal_type, principal_id, secret_path_pattern, permissions, conditions?, expires_at? }`) |
381
+ | `GET` | `/v1/vaults/{id}/policies` | List policies for vault |
382
+ | `PUT` | `/v1/vaults/{id}/policies/{pid}` | Update policy (permissions, conditions, expires_at only) |
383
+ | `DELETE` | `/v1/vaults/{id}/policies/{pid}` | Delete policy → `204` |
384
+
385
+ ### Sharing
386
+
387
+ | Method | Path | Description |
388
+ | -------- | ------------------------- | ----------------------------------------------- |
389
+ | `POST` | `/v1/secrets/{id}/share` | Create share link |
390
+ | `GET` | `/v1/shares/outbound` | List shares you created |
391
+ | `GET` | `/v1/shares/inbound` | List shares sent to you |
392
+ | `POST` | `/v1/shares/{id}/accept` | Accept an inbound share |
393
+ | `POST` | `/v1/shares/{id}/decline` | Decline an inbound share |
394
+ | `DELETE` | `/v1/share/{id}` | Revoke a share |
395
+ | `GET` | `/v1/share/{id}` | Access a share (public, may require passphrase) |
396
+
397
+ ### Intents API (requires `intents_api_enabled`)
398
+
399
+ | Method | Path | Description |
400
+ | ------ | ---------------------------------------------- | ------------------------------------------------------------------------------------------------- |
401
+ | `POST` | `/v1/agents/{id}/transactions` | Submit transaction for signing. Optional `Idempotency-Key` header for replay protection (24h TTL) |
402
+ | `GET` | `/v1/agents/{id}/transactions` | List agent's transactions. `signed_tx` redacted unless `?include_signed_tx=true` |
403
+ | `GET` | `/v1/agents/{id}/transactions/{txid}` | Get transaction details. `signed_tx` redacted unless `?include_signed_tx=true` |
404
+ | `POST` | `/v1/agents/{id}/transactions/simulate` | Simulate single transaction |
405
+ | `POST` | `/v1/agents/{id}/transactions/simulate-bundle` | Simulate transaction bundle |
406
+
407
+ ### Audit
408
+
409
+ | Method | Path | Description |
410
+ | ------ | ----------------------------------------------------- | ------------------ |
411
+ | `GET` | `/v1/audit/events?limit=N&action=...&from=...&to=...` | Query audit events |
412
+
413
+ ### Billing
414
+
415
+ | Method | Path | Description |
416
+ | ------- | ---------------------------------- | ------------------------------------------ |
417
+ | `GET` | `/v1/billing/subscription` | Subscription status, usage, credit balance |
418
+ | `GET` | `/v1/billing/credits/balance` | Credit balance + expiring credits |
419
+ | `GET` | `/v1/billing/credits/transactions` | Credit transaction ledger |
420
+ | `PATCH` | `/v1/billing/overage-method` | Set overage method (`credits` or `x402`) |
421
+ | `GET` | `/v1/billing/usage` | Usage summary (current month) |
422
+ | `GET` | `/v1/billing/history` | Usage event history |
423
+
424
+ ### Chains
425
+
426
+ | Method | Path | Description |
427
+ | ------ | ------------------------- | --------------------- |
428
+ | `GET` | `/v1/chains` | List supported chains |
429
+ | `GET` | `/v1/chains/{name_or_id}` | Get chain details |
430
+
431
+ ### Other
432
+
433
+ | Method | Path | Description |
434
+ | ------------------ | ------------------------------ | -------------------------------------------------- |
435
+ | `GET` | `/v1/health` | Health check → `{ status, service, version }` |
436
+ | `GET` | `/v1/health/hsm` | HSM health → `{ status, hsm_provider, connected }` |
437
+ | `POST/GET/DELETE` | `/v1/auth/api-keys[/{id}]` | Manage personal API keys |
438
+ | `GET/POST/DELETE` | `/v1/security/ip-rules[/{id}]` | Manage IP allowlist/blocklist |
439
+ | `GET/PATCH/DELETE` | `/v1/org/members[/{id}]` | Manage org members |
440
+
441
+ ---
442
+
443
+ ## SDK Method Reference
444
+
445
+ All methods return `Promise<OneclawResponse<T>>`. Access via `client.<resource>.<method>(...)`.
446
+
447
+ | Resource | Method | Description |
448
+ | --------- | ------------------------------------------------------------------------------------------------------------ | -------------------------------------- |
449
+ | `vaults` | `create({ name, description? })` | Create vault |
450
+ | `vaults` | `get(vaultId)` | Get vault |
451
+ | `vaults` | `list()` | List vaults |
452
+ | `vaults` | `delete(vaultId)` | Delete vault |
453
+ | `secrets` | `set(vaultId, key, value, { type?, metadata?, expires_at?, max_access_count? })` | Store/update secret |
454
+ | `secrets` | `get(vaultId, key)` | Read secret (decrypted) |
455
+ | `secrets` | `list(vaultId, prefix?)` | List secret metadata |
456
+ | `secrets` | `delete(vaultId, key)` | Delete secret |
457
+ | `secrets` | `rotate(vaultId, key, newValue)` | Rotate secret to new version |
458
+ | `agents` | `create({ name, description?, scopes?, expires_at?, intents_api_enabled?, token_ttl_seconds?, vault_ids? })` | Create agent → returns agent + api_key |
459
+ | `agents` | `get(agentId)` | Get agent |
460
+ | `agents` | `list()` | List agents |
461
+ | `agents` | `update(agentId, { is_active?, scopes?, intents_api_enabled?, tx_*? })` | Update agent |
462
+ | `agents` | `delete(agentId)` | Delete agent |
463
+ | `agents` | `rotateKey(agentId)` | Rotate agent API key |
464
+ | `agents` | `submitTransaction(agentId, { to, value, chain, ... })` | Submit EVM transaction |
465
+ | `agents` | `simulateTransaction(agentId, { to, value, chain, ... })` | Simulate transaction |
466
+ | `agents` | `simulateBundle(agentId, bundle)` | Simulate transaction bundle |
467
+ | `agents` | `getTransaction(agentId, txId)` | Get transaction |
468
+ | `agents` | `listTransactions(agentId)` | List agent transactions |
469
+ | `access` | `grantAgent(vaultId, agentId, permissions, { path?, conditions?, expires_at? })` | Grant agent access |
470
+ | `access` | `grantHuman(vaultId, userId, permissions, { path?, conditions?, expires_at? })` | Grant user access |
471
+ | `access` | `listGrants(vaultId)` | List policies |
472
+ | `access` | `update(vaultId, policyId, { permissions?, conditions?, expires_at? })` | Update policy |
473
+ | `access` | `revoke(vaultId, policyId)` | Revoke policy |
474
+ | `sharing` | `create(secretId, { recipient_type, recipient_id?, expires_at, max_access_count? })` | Create share |
475
+ | `sharing` | `access(shareId)` | Access shared secret |
476
+ | `sharing` | `listOutbound()` | Shares you created |
477
+ | `sharing` | `listInbound()` | Shares sent to you |
478
+ | `sharing` | `accept(shareId)` | Accept inbound share |
479
+ | `sharing` | `decline(shareId)` | Decline inbound share |
480
+ | `sharing` | `revoke(shareId)` | Revoke outbound share |
481
+ | `audit` | `query({ action?, actor_id?, from?, to?, limit?, offset? })` | Query audit events |
482
+ | `billing` | `usage()` | Current month usage |
483
+ | `billing` | `history(limit?)` | Usage event history |
484
+ | `auth` | `login({ email, password })` | Human login |
485
+ | `auth` | `agentToken({ agent_id, api_key })` | Agent JWT exchange |
486
+ | `auth` | `logout()` | Revoke token |
487
+ | `apiKeys` | `create({ name, scopes?, expires_at? })` | Create personal API key |
488
+ | `apiKeys` | `list()` | List API keys |
489
+ | `apiKeys` | `revoke(keyId)` | Revoke key |
490
+ | `chains` | `list()` | List supported chains |
491
+ | `chains` | `get(identifier)` | Get chain by name or ID |
492
+ | `org` | `listMembers()` | List org members |
493
+ | `org` | `updateMemberRole(userId, role)` | Update member role |
494
+ | `org` | `removeMember(userId)` | Remove member |
495
+
496
+ ### OpenAPI spec for custom SDKs
497
+
498
+ The API spec is published as an npm package for generating clients in any language:
499
+
500
+ ```bash
501
+ npm install @1claw/openapi-spec
502
+ ```
503
+
504
+ Ships `openapi.yaml` and `openapi.json`. Use with any OpenAPI 3.1 codegen tool:
505
+
506
+ ```bash
507
+ # TypeScript
508
+ npx openapi-typescript node_modules/@1claw/openapi-spec/openapi.yaml -o ./types.ts
509
+
510
+ # Python
511
+ openapi-generator generate -i node_modules/@1claw/openapi-spec/openapi.yaml -g python -o ./oneclaw-py
512
+
513
+ # Go
514
+ oapi-codegen -package oneclaw node_modules/@1claw/openapi-spec/openapi.yaml > oneclaw.go
515
+ ```
516
+
517
+ SDK also re-exports generated types: `import type { ApiSchemas } from "@1claw/sdk"`.
518
+
519
+ ---
520
+
521
+ ## Supported Chains
522
+
523
+ Default chain registry (query `GET /v1/chains` for live list):
524
+
525
+ | Name | Chain ID | Testnet |
526
+ | ------------ | -------- | ------- |
527
+ | ethereum | 1 | no |
528
+ | base | 8453 | no |
529
+ | optimism | 10 | no |
530
+ | arbitrum-one | 42161 | no |
531
+ | polygon | 137 | no |
532
+ | sepolia | 11155111 | yes |
533
+ | base-sepolia | 84532 | yes |
534
+
535
+ Use chain names (e.g. `"base"`, `"sepolia"`) or numeric chain IDs in transaction requests.
536
+
537
+ ---
538
+
539
+ ## Access Control Model
540
+
541
+ Agents do **not** get blanket access. A human must create a policy to grant an agent access to specific secret paths.
542
+
543
+ - **Path patterns**: Glob syntax — `api-keys/*`, `db/**`, `**` (all)
544
+ - **Permissions**: `read`, `write` (delete requires `write`)
545
+ - **Conditions**: IP allowlist, time windows (JSON)
546
+ - **Expiry**: Optional ISO 8601 date
547
+
548
+ If no policy matches → **403 Forbidden**. Vault creators always have full access (owner bypass).
549
+
550
+ ### Vault binding and token scoping
551
+
552
+ Agents can be restricted beyond policies:
553
+
554
+ - **`vault_ids`**: Restrict the agent to specific vaults. If non-empty, any request to a vault not in the list returns 403.
555
+ - **`token_ttl_seconds`**: Custom JWT expiry per agent (e.g., 300 for 5-minute tokens).
556
+ - **Scopes from policies**: JWT scopes are derived from the agent's access policies. If an agent has no policies and no explicit scopes, it has zero access.
557
+
558
+ Set via dashboard, CLI (`--token-ttl`, `--vault-ids`), SDK, or API.
559
+
560
+ ### Customer-Managed Encryption Keys (CMEK)
561
+
562
+ Enterprise opt-in feature (Business tier and above). A human generates a 256-bit AES key in the dashboard — the key never leaves their device. Only its SHA-256 fingerprint is stored on the server.
563
+
564
+ - Enable: `POST /v1/vaults/{id}/cmek` with `{ fingerprint }`
565
+ - Disable: `DELETE /v1/vaults/{id}/cmek`
566
+ - Rotate: `POST /v1/vaults/{id}/cmek-rotate` (server-assisted, batched in 100s)
567
+ - Secrets stored in a CMEK vault have `cmek_encrypted: true` in responses
568
+
569
+ Agents reading from a CMEK vault receive the encrypted blob. The CMEK key is required to decrypt client-side. This is designed for organizations with compliance requirements — the default HSM encryption is already strong.
570
+
571
+ ### Intents API
572
+
573
+ When `intents_api_enabled = true` (set by a human):
574
+
575
+ 1. Agent **gains** transaction signing via the Intents API (keys stay in HSM)
576
+ 2. Agent is **blocked** from reading `private_key` and `ssh_key` secrets directly (403)
577
+
578
+ Default signing key path: `keys/{chain}-signer`. Override with `signing_key_path`.
579
+
580
+ #### Replay protection (Idempotency-Key)
581
+
582
+ Include an `Idempotency-Key: <unique-string>` header on `POST /v1/agents/{id}/transactions`. The server SHA-256 hashes the key and caches the result for 24 hours. Duplicate submissions with the same key return the cached response instead of re-signing and re-broadcasting. If two concurrent requests share a key, one returns 409 (retry after a moment).
583
+
584
+ #### Server-side nonce serialization
585
+
586
+ When `nonce` is omitted from a transaction request, the server resolves it automatically via `eth_getTransactionCount` (pending) and serializes concurrent callers with `SELECT FOR UPDATE`. This prevents two in-flight submissions from the same agent+chain+address from receiving the same nonce. You can still pass an explicit `nonce` to override.
587
+
588
+ #### signed_tx field gating
589
+
590
+ GET endpoints (`/v1/agents/{id}/transactions` and `/v1/agents/{id}/transactions/{txid}`) **redact** the `signed_tx` field by default to reduce exfiltration risk. To include it, pass `?include_signed_tx=true`. The initial POST response always includes `signed_tx` for the originating caller.
591
+
592
+ ### Transaction guardrails
593
+
594
+ Human-configured, server-enforced limits on what the Intents API allows:
595
+
596
+ | Guardrail | Field | Effect |
597
+ | -------------------- | -------------------- | ----------------------------------------------------- |
598
+ | Allowed destinations | `tx_to_allowlist` | Only listed addresses permitted. Empty = unrestricted |
599
+ | Max value per tx | `tx_max_value_eth` | Single-tx cap in ETH. NULL = unlimited |
600
+ | Daily spend limit | `tx_daily_limit_eth` | Rolling 24h cumulative cap. NULL = unlimited |
601
+ | Allowed chains | `tx_allowed_chains` | Chain names. Empty = all chains |
602
+
603
+ Agents **cannot** modify their own guardrails. Violations return 403 with a descriptive error.
604
+
605
+ ### Shroud per-agent LLM proxy
606
+
607
+ When `shroud_enabled = true` (set by a human), the agent's LLM traffic is routed through Shroud (`shroud.1claw.xyz`) for secret redaction, PII scrubbing, prompt injection defense, threat detection, and policy enforcement inside a TEE.
608
+
609
+ `shroud_config` is an optional JSON object that lets humans fine-tune the proxy behavior per agent:
610
+
611
+ #### Basic settings
612
+
613
+ | Field | Type | Description |
614
+ | ----------------------------- | ------------------------------------------------ | --------------------------------------------- |
615
+ | `pii_policy` | `"block"` \| `"redact"` \| `"warn"` \| `"allow"` | How PII in LLM traffic is handled |
616
+ | `injection_threshold` | number (0.0–1.0) | Prompt injection detection sensitivity |
617
+ | `context_injection_threshold` | number (0.0–1.0) | Context injection detection sensitivity |
618
+ | `allowed_providers` | string[] | LLM providers the agent may use (empty = all) |
619
+ | `allowed_models` | string[] | Models the agent may use (empty = all) |
620
+ | `denied_models` | string[] | Models explicitly blocked |
621
+ | `max_tokens_per_request` | number | Token cap per LLM request |
622
+ | `max_requests_per_minute` | number | Per-minute rate limit |
623
+ | `max_requests_per_day` | number | Per-day rate limit |
624
+ | `daily_budget_usd` | number | Daily LLM spend cap in USD |
625
+ | `enable_secret_redaction` | boolean | Redact vault secrets from LLM context |
626
+ | `enable_response_filtering` | boolean | Filter sensitive data from LLM responses |
627
+
628
+ #### Threat detection settings
629
+
630
+ Multi-layered detection for prompt injection, command injection, social engineering, and data exfiltration attempts:
631
+
632
+ | Field | Type | Description |
633
+ | ------------------------------ | ------ | ------------------------------------------------------------------- |
634
+ | `unicode_normalization` | object | Homoglyph/zero-width character normalization (see below) |
635
+ | `command_injection_detection` | object | Detect shell commands, path traversal, reverse shells |
636
+ | `social_engineering_detection` | object | Detect urgency, authority claims, secrecy requests, bypass attempts |
637
+ | `encoding_detection` | object | Detect base64, hex, Unicode escapes that may hide payloads |
638
+ | `network_detection` | object | Detect blocked domains, IP URLs, data exfiltration patterns |
639
+ | `filesystem_detection` | object | Detect sensitive paths (/etc/passwd, .ssh/, .env, etc.) |
640
+ | `sanitization_mode` | string | `"block"` (reject threats), `"sanitize"` (strip), `"warn"` (log) |
641
+ | `threat_logging` | boolean| Log detected threats for audit (default: true) |
642
+
643
+ **`unicode_normalization` object:**
644
+
645
+ | Field | Type | Default | Description |
646
+ | -------------------- | ------- | ------- | ---------------------------------------------- |
647
+ | `enabled` | boolean | true | Enable Unicode normalization |
648
+ | `strip_zero_width` | boolean | true | Remove zero-width characters (U+200B, U+200C) |
649
+ | `normalize_homoglyphs` | boolean | true | Convert look-alike characters (Cyrillic а → a) |
650
+ | `normalization_form` | string | `"NFKC"` | Unicode form: `"NFC"`, `"NFKC"`, `"NFD"`, `"NFKD"` |
651
+
652
+ **`command_injection_detection` object:**
653
+
654
+ | Field | Type | Default | Description |
655
+ | ----------- | ------ | --------- | ---------------------------------------------- |
656
+ | `action` | string | `"block"` | `"block"`, `"sanitize"`, or `"warn"` |
657
+ | `strictness`| string | `"default"` | `"strict"` (more patterns), `"default"`, `"relaxed"` |
658
+
659
+ **`social_engineering_detection` object:**
660
+
661
+ | Field | Type | Default | Description |
662
+ | ----------- | ------ | -------- | ---------------------------------------- |
663
+ | `action` | string | `"warn"` | `"block"` or `"warn"` |
664
+ | `sensitivity` | string | `"medium"` | `"low"` (more triggers), `"medium"`, `"high"` |
665
+
666
+ **`encoding_detection` object:**
667
+
668
+ | Field | Type | Default | Description |
669
+ | -------------- | ------- | ------- | ------------------------------------- |
670
+ | `action` | string | `"warn"` | `"block"`, `"decode"`, or `"warn"` |
671
+ | `detect_base64`| boolean | true | Detect base64 encoded content |
672
+ | `detect_hex` | boolean | true | Detect \xNN hex escapes |
673
+ | `detect_unicode` | boolean | true | Detect \uNNNN Unicode escapes |
674
+
675
+ **`network_detection` object:**
676
+
677
+ | Field | Type | Default | Description |
678
+ | ----------------- | -------- | ------------------------ | ---------------------------------- |
679
+ | `action` | string | `"warn"` | `"block"` or `"warn"` |
680
+ | `blocked_domains` | string[] | pastebin, ngrok, etc. | Domains to block (subdomains auto) |
681
+ | `allowed_domains` | string[] | [] | Allowlist (empty = blocklist mode) |
682
+
683
+ **`filesystem_detection` object:**
684
+
685
+ | Field | Type | Default | Description |
686
+ | -------------- | -------- | -------------------- | --------------------------------- |
687
+ | `action` | string | `"log"` | `"block"`, `"sanitize"`, or `"log"` |
688
+ | `blocked_paths`| string[] | /etc/passwd, .ssh/, .env, etc. | Paths to detect |
689
+
690
+ **SDK:**
691
+
692
+ ```typescript
693
+ await client.agents.create({
694
+ name: "my-agent",
695
+ shroud_enabled: true,
696
+ shroud_config: {
697
+ pii_policy: "redact",
698
+ injection_threshold: 0.8,
699
+ allowed_providers: ["openai", "anthropic"],
700
+ max_requests_per_day: 1000,
701
+ daily_budget_usd: 10.0,
702
+ enable_secret_redaction: true,
703
+ // Threat detection
704
+ unicode_normalization: { enabled: true, normalize_homoglyphs: true },
705
+ command_injection_detection: { action: "block", strictness: "default" },
706
+ social_engineering_detection: { action: "warn", sensitivity: "medium" },
707
+ encoding_detection: { action: "warn", detect_base64: true },
708
+ network_detection: { action: "warn", blocked_domains: ["pastebin.com"] },
709
+ filesystem_detection: { action: "log" },
710
+ sanitization_mode: "block",
711
+ threat_logging: true,
712
+ },
713
+ });
714
+
715
+ await client.agents.update(agentId, {
716
+ shroud_enabled: true,
717
+ shroud_config: { pii_policy: "block", injection_threshold: 0.9 },
718
+ });
719
+ ```
720
+
721
+ **CLI:**
722
+
723
+ ```bash
724
+ 1claw agent create my-agent --shroud
725
+ 1claw agent update <agent-id> --shroud true
726
+ 1claw agent update <agent-id> --shroud false
727
+ ```
728
+
729
+ **MCP:** When `shroud_enabled` is true, the agent can send LLM requests through `shroud.1claw.xyz`. The Shroud proxy enforces the agent's `shroud_config` policy automatically — no client-side changes needed.
730
+
731
+ ---
732
+
733
+ ## Share with Your Human
734
+
735
+ Agents can share secrets back with the human who created or enrolled them. Use `recipient_type: "creator"` — no email or user ID needed.
736
+
737
+ **Via MCP:**
738
+
739
+ ```
740
+ share_secret(secret_id: "...", recipient_type: "creator", expires_at: "2026-12-31T00:00:00Z")
741
+ ```
742
+
743
+ **Via SDK:**
744
+
745
+ ```typescript
746
+ await client.sharing.create(secretId, {
747
+ recipient_type: "creator",
748
+ expires_at: "2026-12-31T00:00:00Z",
749
+ max_access_count: 5,
750
+ });
751
+ ```
752
+
753
+ The human sees the share in their Inbound shares and accepts it. This is the primary pattern for agents that discover or generate credentials and need to report them to their human.
754
+
755
+ ---
756
+
757
+ ## Fleet Patterns
758
+
759
+ When many agents operate in the same organization:
760
+
761
+ - **Vault organization:** Use a shared vault with path-scoped policies (e.g. `agents/{name}/**`) or per-agent vaults for strict isolation.
762
+ - **Bulk provisioning:** Use the authenticated `POST /v1/agents` endpoint with a human API key to create many agents, or stagger self-enrollment calls to respect the 10-min per-email cooldown.
763
+ - **Vault binding:** Set `vault_ids` on each agent to restrict JWT scope beyond what policies allow.
764
+ - **Token TTL:** Shorten to 5 min for ephemeral tasks (`token_ttl_seconds: 300`), keep default 1h for long-running agents.
765
+ - **Transaction guardrails:** Apply `tx_max_value_eth`, `tx_daily_limit_eth`, and `tx_allowed_chains` to all Intents API agents.
766
+ - **Monitoring:** Filter the audit log by agent ID to track per-agent activity. Use `billing usage` to monitor org-wide consumption.
767
+
768
+ ---
769
+
770
+ ## Security Model
771
+
772
+ - **Credentials are configured by the human**, not the agent. The MCP server reads them from env vars.
773
+ - **The agent never sees its own credentials.** The MCP server authenticates on the agent's behalf.
774
+ - **Access is deny-by-default.** Even with valid credentials, only policy-allowed secrets are accessible.
775
+ - **Secret values are fetched just-in-time** and must never be stored, echoed, or included in summaries.
776
+ - **Agents cannot create email-based shares** (prevents unsolicited email sharing).
777
+ - **Intents API is opt-in.** When enabled, raw key reads are blocked.
778
+ - **Transaction guardrails are human-controlled and server-enforced.**
779
+ - **Token revocation:** `DELETE /v1/auth/token` (or SDK `auth.logout()`) revokes the current Bearer token; revoked tokens return 401.
780
+ - **Request body limit:** 5MB max; larger requests return 413.
781
+
782
+ ---
783
+
784
+ ## Error Handling
785
+
786
+ | Code | Meaning | Action |
787
+ | ---- | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
788
+ | 400 | Bad request | Check request body format |
789
+ | 401 | Not authenticated | Token expired — re-authenticate |
790
+ | 402 | Quota exhausted / payment required | Body may include `required_usd`, `message`. Intents submit over quota: 0.25% of tx value; top up credits or send X-PAYMENT for required amount. Otherwise upgrade at `1claw.xyz/settings/billing` |
791
+ | 403 | No permission | Ask user to grant access via a policy. Or: guardrail violation (check error detail) |
792
+ | 403 | Resource limit reached (`type: "resource_limit_exceeded"`) | Tier limit on vaults/secrets/agents hit — ask user to upgrade at `1claw.xyz/settings/billing` |
793
+ | 404 | Not found | Check path with `list_secrets` |
794
+ | 405 | Method not allowed | Wrong HTTP verb for this endpoint |
795
+ | 409 | Conflict | Resource already exists (e.g. duplicate vault name) |
796
+ | 410 | Gone | Secret expired or max access count reached — ask user to store a new version |
797
+ | 422 | Validation error or simulation reverted | Check input. For `simulate_first`: transaction would revert |
798
+ | 413 | Payload too large | Request body over 5MB — reduce payload size |
799
+ | 429 | Rate limited | Wait and retry. Auth routes: 5 req burst, 1/sec. Share creation: 10/min/org |
800
+
801
+ All error responses include a `detail` field with a human-readable message.
802
+
803
+ ---
804
+
805
+ ## Best Practices
806
+
807
+ 1. **Fetch secrets just-in-time.** Call `get_secret` immediately before the API call that needs the credential.
808
+ 2. **Never echo secret values.** Say "I retrieved the API key and used it" — never include raw values in responses.
809
+ 3. **Use `describe_secret` first** to check existence or validity before fetching the full value.
810
+ 4. **Use `list_secrets` to discover** available credentials before guessing paths.
811
+ 5. **Rotate after regeneration.** If you regenerate an API key at a provider, immediately `rotate_and_store` the new value.
812
+ 6. **Use `grant_access` for vault-level sharing** — creates a fine-grained policy with path patterns.
813
+ 7. **Use `share_secret` for one-off sharing** — creates a time-limited, access-counted share link.
814
+ 8. **Simulate before signing.** Always use `simulate_first: true` (default) or call `simulate_transaction` before `submit_transaction`.
815
+ 9. **Check `list_vaults` before creating.** Avoid creating duplicate vaults.
816
+ 10. **Handle 402 gracefully.** Billing/quota errors should be surfaced to the user, not retried.
817
+
818
+ ---
819
+
820
+ ## Billing Tiers
821
+
822
+ | Tier | Requests/mo | Vaults | Secrets | Agents | Price |
823
+ | ---------- | ----------- | --------- | --------- | --------- | --------------------------------- |
824
+ | Free | 1,000 | 3 | 50 | 2 | $0 |
825
+ | Pro | 25,000 | 25 | 500 | 10 | $29/mo |
826
+ | Business | 100,000 | 100 | 5,000 | 50 | $149/mo (+ CMEK) |
827
+ | Enterprise | Custom | Unlimited | Unlimited | Unlimited | Contact (+ CMEK + KMS delegation) |
828
+
829
+ Overage methods: **prepaid credits** (top up via Stripe, deducted per request) or **x402 micropayments** (per-query on-chain payments on Base).
830
+
831
+ Audit, org, security, chain, billing, and auth endpoints are **free and never consume quota**.
832
+
833
+ ---
834
+
835
+ ## Links
836
+
837
+ - Dashboard: [1claw.xyz](https://1claw.xyz)
838
+ - Docs: [docs.1claw.xyz](https://docs.1claw.xyz)
839
+ - Status: [1claw.xyz/status](https://1claw.xyz/status)
840
+ - API: `https://api.1claw.xyz`
841
+ - SDK: [@1claw/sdk on npm](https://www.npmjs.com/package/@1claw/sdk)
842
+ - OpenAPI Spec: [@1claw/openapi-spec on npm](https://www.npmjs.com/package/@1claw/openapi-spec)
843
+ - MCP Server: [@1claw/mcp on npm](https://www.npmjs.com/package/@1claw/mcp)
844
+ - CLI: [@1claw/cli on npm](https://www.npmjs.com/package/@1claw/cli)
845
+ - GitHub: [github.com/1clawAI](https://github.com/1clawAI)
846
+ - Support: [ops@1claw.xyz](mailto:ops@1claw.xyz)