@1claw/openapi-spec 0.19.1 → 0.20.2

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.
package/README.md CHANGED
@@ -40,21 +40,22 @@ openapi-generator generate \
40
40
  import spec from "@1claw/openapi-spec/openapi.json";
41
41
  ```
42
42
 
43
- ## What's in the spec (v0.19.x)
43
+ ## What's in the spec (v0.20.x — API `info.version` 2.10.x)
44
44
 
45
- - **Auth agent JWT** — `POST /v1/auth/agent-token` documents optional JWT claim **`shroud_config`** when the agent has Shroud enabled (mirrors DB; consumed by Shroud PolicyEngine on LLM requests). Re-exchange after changing agent Shroud settings.
45
+ - **OIDC Federation (1claw as IdP)** — `GET /.well-known/openid-configuration` (public discovery: issuer, jwks_uri, supported algs `["EdDSA","RS256"]`, supported grant types incl. token-exchange), `GET /.well-known/jwks.json` (public JWKS — every active EdDSA + RS256 key version, keyed by deterministic `kid`), `POST /v1/auth/federated-token` (RFC 8693 token exchange accepts JSON or `application/x-www-form-urlencoded`; subject token is an agent JWT or `ocv_` API key; returns RS256 JWT scoped to `audience`). Agent fields: `federation_enabled`, `federation_audiences[]`, `federated_token_ttl_seconds`. Designed for Anthropic Workload Identity Federation, GCP STS, AWS STS, etc.
46
+ - **Auth — agent JWT** — `POST /v1/auth/agent-token` documents optional JWT claim **`shroud_config`** when the agent has Shroud enabled (mirrors DB; consumed by Shroud PolicyEngine on LLM requests). Re-exchange after changing agent Shroud settings. Federation tokens use a separate KMS RSA-2048 key and are signed RS256.
46
47
  - **Auth — password reset** — `POST /v1/auth/forgot-password`, `POST /v1/auth/reset-password` (public; anti-enumeration on forgot)
47
48
  - **Billing — LLM token billing** — `GET /v1/billing/llm-token-billing` (`LlmTokenBillingStatus`: `enabled`, `subscription_status`, optional `credit_balance`, optional `billing_cycle_usage` with `metered_lines[]`), `POST .../subscribe`, `POST .../disable` (Stripe AI Gateway add-on; optional org feature)
48
49
  - **Treasury** — Safe multisig treasuries: `POST/GET /v1/treasury`, `GET/PATCH/DELETE /v1/treasury/{id}`, signers, agent access requests (`requests[]` on list)
49
50
  - **Vaults** — CRUD, CMEK enable/disable, key rotation with job tracking, MPC enable/disable (`POST /v1/vaults/{id}/mpc`, `DELETE /v1/vaults/{id}/mpc`)
50
51
  - **Secrets** — CRUD, versioning, CMEK-encrypted flag, `client_share` in responses (MPC vaults)
51
- - **Agents** — CRUD with `auth_method` (api_key, mtls, oidc_client_credentials), auto-generated SSH keypairs, `token_ttl_seconds`, `vault_ids`, Intents API, transaction guardrails (`tx_to_allowlist`, `tx_max_value_eth`, `tx_daily_limit_eth`, `tx_allowed_chains`); **`GET /v1/agents/{id}`** includes **`tx_spent_today_eth`** (rolling UTC-day spend from recorded txs) for clients such as **Shroud** that enforce the daily cap alongside per-tx limits
52
+ - **Agents** — CRUD with `auth_method` (api_key, mtls, oidc_client_credentials), auto-generated SSH keypairs, `token_ttl_seconds`, `vault_ids`, Intents API, transaction guardrails (`tx_to_allowlist`, `tx_max_value_eth`, `tx_daily_limit_eth`, `tx_allowed_chains`), **OIDC federation knobs** (`federation_enabled`, `federation_audiences`, `federated_token_ttl_seconds`); **`GET /v1/agents/{id}`** includes **`tx_spent_today_eth`** (rolling UTC-day spend from recorded txs) for clients such as **Shroud** that enforce the daily cap alongside per-tx limits
52
53
  - **Policies** — Glob-based access control
53
54
  - **Sharing** — Links, user/agent shares, accept/decline
54
55
  - **Billing** — Subscriptions, credits, x402, LLM token billing (see above)
55
56
  - **Audit** — Hash-chained event log
56
57
  - **Chains** — Supported blockchain registry
57
- - **Auth** — JWT, API keys, agent tokens, MFA, device flow, Google OAuth
58
+ - **Auth** — JWT, API keys, agent tokens, MFA, device flow, Google OAuth, **federated tokens (RFC 8693)**
58
59
  - **Org** — List members, invite, update/remove member; `GET /v1/org/agent-keys-vault` (users only, returns __agent-keys vault id or 404)
59
60
 
60
61
  ## Included files
package/openapi.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "openapi": "3.1.0",
3
3
  "info": {
4
4
  "title": "1Claw API",
5
- "version": "2.9.0",
5
+ "version": "2.10.1",
6
6
  "description": "Secure secret management for AI agents. Provides vaults, secrets,\npolicy-based access control, agent identity, Intents API,\nsharing, billing, and audit logging.\n\nAll endpoints require JWT Bearer authentication unless marked with\n`security: []`.\n",
7
7
  "contact": {
8
8
  "email": "ops@1claw.xyz"
@@ -267,7 +267,7 @@
267
267
  "Authentication"
268
268
  ],
269
269
  "summary": "Get JWT verification public key",
270
- "description": "Returns the Ed25519 public key used to sign JWTs.\nUse this to verify tokens independently (e.g. in a TEE proxy or\ngateway). No authentication required.\n",
270
+ "description": "Returns the Ed25519 public key used to sign JWTs.\nUse this to verify tokens independently (e.g. in a TEE proxy or\ngateway). No authentication required.\n\nFor OIDC-compliant relying parties (Anthropic Workload Identity\nFederation, etc.) prefer the JWKS endpoint at\n`/.well-known/jwks.json` together with the discovery document\nat `/.well-known/openid-configuration` — those advertise both\nEd25519 and RS256 keys keyed by `kid` and survive key rotation.\n",
271
271
  "operationId": "getJwtPublicKey",
272
272
  "security": [],
273
273
  "responses": {
@@ -298,6 +298,110 @@
298
298
  }
299
299
  }
300
300
  },
301
+ "/v1/auth/federated-token": {
302
+ "post": {
303
+ "tags": [
304
+ "Authentication"
305
+ ],
306
+ "summary": "Exchange a 1claw token for an OIDC federation token (RFC 8693)",
307
+ "description": "Mints a short-lived RS256-signed JWT targeted at an external\nrelying party (e.g. Anthropic Workload Identity Federation).\nThe relying party validates the token via this issuer's JWKS\nURL (`/.well-known/jwks.json`) and exchanges it for its own\nshort-lived service credentials.\n\nRequirements:\n- The agent that owns the `subject_token` must have\n `federation_enabled = true` and the requested `audience`\n must appear in `federation_audiences`.\n- The `subject_token` must be a valid 1claw agent JWT or\n `ocv_` API key.\n- Optional `scope` narrows the agent's existing scopes — it\n cannot escalate.\n\nReturns 503 when `ONECLAW_JWT_RS256_SIGNING_KEY_ID` is not\nconfigured on the server.\n",
308
+ "operationId": "exchangeFederatedToken",
309
+ "security": [],
310
+ "requestBody": {
311
+ "required": true,
312
+ "content": {
313
+ "application/json": {
314
+ "schema": {
315
+ "$ref": "#/components/schemas/TokenExchangeRequest"
316
+ }
317
+ },
318
+ "application/x-www-form-urlencoded": {
319
+ "schema": {
320
+ "$ref": "#/components/schemas/TokenExchangeRequest"
321
+ }
322
+ }
323
+ }
324
+ },
325
+ "responses": {
326
+ "200": {
327
+ "description": "Federation token issued",
328
+ "content": {
329
+ "application/json": {
330
+ "schema": {
331
+ "$ref": "#/components/schemas/TokenExchangeResponse"
332
+ }
333
+ }
334
+ }
335
+ },
336
+ "400": {
337
+ "$ref": "#/components/responses/BadRequest"
338
+ },
339
+ "401": {
340
+ "$ref": "#/components/responses/Unauthorized"
341
+ },
342
+ "403": {
343
+ "$ref": "#/components/responses/Forbidden"
344
+ },
345
+ "503": {
346
+ "description": "RS256 signing key not configured"
347
+ }
348
+ }
349
+ }
350
+ },
351
+ "/.well-known/openid-configuration": {
352
+ "get": {
353
+ "tags": [
354
+ "Authentication"
355
+ ],
356
+ "summary": "OIDC discovery document",
357
+ "description": "Standard OpenID Connect discovery document advertising the\nissuer URL, JWKS URL, supported algorithms (`EdDSA`, `RS256`),\nand the RFC 8693 token-exchange endpoint. External IdPs\n(Anthropic WIF, Okta, Auth0, etc.) read this URL to learn\nwhere 1claw publishes its JWKS.\n",
358
+ "operationId": "openidConfiguration",
359
+ "security": [],
360
+ "responses": {
361
+ "200": {
362
+ "description": "Discovery document",
363
+ "content": {
364
+ "application/json": {
365
+ "schema": {
366
+ "type": "object"
367
+ }
368
+ }
369
+ }
370
+ }
371
+ }
372
+ }
373
+ },
374
+ "/.well-known/jwks.json": {
375
+ "get": {
376
+ "tags": [
377
+ "Authentication"
378
+ ],
379
+ "summary": "JSON Web Key Set",
380
+ "description": "Public keys for every active version of every JWT signing\nkey (Ed25519 + RSA-2048). Each entry includes a `kid` so\nconsumers can validate tokens issued before the most recent\nkey rotation. Cached for 5 minutes via `Cache-Control` and\nCORS-permissive for browser-based IdP consoles.\n",
381
+ "operationId": "jwks",
382
+ "security": [],
383
+ "responses": {
384
+ "200": {
385
+ "description": "JWK Set",
386
+ "content": {
387
+ "application/jwk-set+json": {
388
+ "schema": {
389
+ "type": "object",
390
+ "properties": {
391
+ "keys": {
392
+ "type": "array",
393
+ "items": {
394
+ "type": "object"
395
+ }
396
+ }
397
+ }
398
+ }
399
+ }
400
+ }
401
+ }
402
+ }
403
+ }
404
+ },
301
405
  "/v1/auth/signup": {
302
406
  "post": {
303
407
  "tags": [
@@ -952,6 +1056,205 @@
952
1056
  }
953
1057
  }
954
1058
  },
1059
+ "/v1/auth/export-data": {
1060
+ "post": {
1061
+ "tags": [
1062
+ "Authentication"
1063
+ ],
1064
+ "summary": "Export user data (GDPR)",
1065
+ "description": "Returns a full export of the authenticated user's data including\nprofile, vaults, agents, secrets metadata, and policies. Intended\nfor GDPR data-portability requests. Only available to human users\n(not agents).\n",
1066
+ "operationId": "exportUserData",
1067
+ "responses": {
1068
+ "200": {
1069
+ "description": "User data export",
1070
+ "content": {
1071
+ "application/json": {
1072
+ "schema": {
1073
+ "type": "object",
1074
+ "required": [
1075
+ "export_version",
1076
+ "exported_at",
1077
+ "user",
1078
+ "vaults",
1079
+ "agents",
1080
+ "secrets_metadata",
1081
+ "policies"
1082
+ ],
1083
+ "properties": {
1084
+ "export_version": {
1085
+ "type": "string",
1086
+ "example": "1.0"
1087
+ },
1088
+ "exported_at": {
1089
+ "type": "string",
1090
+ "format": "date-time"
1091
+ },
1092
+ "user": {
1093
+ "type": "object",
1094
+ "required": [
1095
+ "id",
1096
+ "email",
1097
+ "display_name",
1098
+ "auth_method",
1099
+ "created_at"
1100
+ ],
1101
+ "properties": {
1102
+ "id": {
1103
+ "type": "string",
1104
+ "format": "uuid"
1105
+ },
1106
+ "email": {
1107
+ "type": "string",
1108
+ "format": "email"
1109
+ },
1110
+ "display_name": {
1111
+ "type": "string"
1112
+ },
1113
+ "auth_method": {
1114
+ "type": "string"
1115
+ },
1116
+ "created_at": {
1117
+ "type": "string",
1118
+ "format": "date-time"
1119
+ }
1120
+ }
1121
+ },
1122
+ "vaults": {
1123
+ "type": "array",
1124
+ "items": {
1125
+ "type": "object",
1126
+ "required": [
1127
+ "id",
1128
+ "name",
1129
+ "created_at"
1130
+ ],
1131
+ "properties": {
1132
+ "id": {
1133
+ "type": "string",
1134
+ "format": "uuid"
1135
+ },
1136
+ "name": {
1137
+ "type": "string"
1138
+ },
1139
+ "created_at": {
1140
+ "type": "string",
1141
+ "format": "date-time"
1142
+ }
1143
+ }
1144
+ }
1145
+ },
1146
+ "agents": {
1147
+ "type": "array",
1148
+ "items": {
1149
+ "type": "object",
1150
+ "required": [
1151
+ "id",
1152
+ "name",
1153
+ "created_at"
1154
+ ],
1155
+ "properties": {
1156
+ "id": {
1157
+ "type": "string",
1158
+ "format": "uuid"
1159
+ },
1160
+ "name": {
1161
+ "type": "string"
1162
+ },
1163
+ "created_at": {
1164
+ "type": "string",
1165
+ "format": "date-time"
1166
+ }
1167
+ }
1168
+ }
1169
+ },
1170
+ "secrets_metadata": {
1171
+ "type": "array",
1172
+ "items": {
1173
+ "type": "object",
1174
+ "required": [
1175
+ "vault_id",
1176
+ "path",
1177
+ "type",
1178
+ "version",
1179
+ "created_at"
1180
+ ],
1181
+ "properties": {
1182
+ "vault_id": {
1183
+ "type": "string",
1184
+ "format": "uuid"
1185
+ },
1186
+ "path": {
1187
+ "type": "string"
1188
+ },
1189
+ "type": {
1190
+ "type": "string"
1191
+ },
1192
+ "version": {
1193
+ "type": "integer"
1194
+ },
1195
+ "created_at": {
1196
+ "type": "string",
1197
+ "format": "date-time"
1198
+ }
1199
+ }
1200
+ }
1201
+ },
1202
+ "policies": {
1203
+ "type": "array",
1204
+ "items": {
1205
+ "type": "object",
1206
+ "required": [
1207
+ "id",
1208
+ "vault_id",
1209
+ "principal_type",
1210
+ "principal_id",
1211
+ "secret_path_pattern",
1212
+ "permissions",
1213
+ "created_at"
1214
+ ],
1215
+ "properties": {
1216
+ "id": {
1217
+ "type": "string",
1218
+ "format": "uuid"
1219
+ },
1220
+ "vault_id": {
1221
+ "type": "string",
1222
+ "format": "uuid"
1223
+ },
1224
+ "principal_type": {
1225
+ "type": "string"
1226
+ },
1227
+ "principal_id": {
1228
+ "type": "string",
1229
+ "format": "uuid"
1230
+ },
1231
+ "secret_path_pattern": {
1232
+ "type": "string"
1233
+ },
1234
+ "permissions": {
1235
+ "type": "array",
1236
+ "items": {
1237
+ "type": "string"
1238
+ }
1239
+ },
1240
+ "created_at": {
1241
+ "type": "string",
1242
+ "format": "date-time"
1243
+ }
1244
+ }
1245
+ }
1246
+ }
1247
+ }
1248
+ }
1249
+ }
1250
+ }
1251
+ },
1252
+ "403": {
1253
+ "$ref": "#/components/responses/Forbidden"
1254
+ }
1255
+ }
1256
+ }
1257
+ },
955
1258
  "/v1/vaults": {
956
1259
  "post": {
957
1260
  "tags": [
@@ -1509,7 +1812,7 @@
1509
1812
  }
1510
1813
  }
1511
1814
  },
1512
- "/v1/vaults/{vault_id}/secret-version/{path}/{version}/disable": {
1815
+ "/v1/vaults/{vault_id}/secret-version-disable/{path}/{version}": {
1513
1816
  "post": {
1514
1817
  "tags": [
1515
1818
  "Secrets"
@@ -1723,7 +2026,7 @@
1723
2026
  ],
1724
2027
  "summary": "Self-enroll an agent",
1725
2028
  "operationId": "enrollAgent",
1726
- "description": "Public endpoint (no auth required). Creates an agent under the human's org\nand emails the credentials to the specified human email. The API key is NOT\nreturned in the response. Anti-spam: IP rate limiting + per-email cooldown.\n",
2029
+ "description": "Public endpoint (no auth required).\n\n**With `human_email`:** Creates a pending enrollment for that account's org,\nemails Allow/Deny links, and returns `approval_url` in the JSON body (use if email\nis delayed). The API key is NOT returned until the human approves.\n\n**Name only (omit `human_email`):** Creates a link-only pending enrollment.\nThe response includes `approval_url`; the human opens it while signed in to\napprove the agent into their org.\n\nAnti-spam: IP rate limiting, per-email cooldown, caps on pending rows.\n",
1727
2030
  "requestBody": {
1728
2031
  "required": true,
1729
2032
  "content": {
@@ -4669,6 +4972,76 @@
4669
4972
  }
4670
4973
  }
4671
4974
  },
4975
+ "TokenExchangeRequest": {
4976
+ "type": "object",
4977
+ "required": [
4978
+ "grant_type",
4979
+ "subject_token",
4980
+ "subject_token_type",
4981
+ "audience"
4982
+ ],
4983
+ "description": "RFC 8693 token-exchange request body. `subject_token_type`\naccepts the standard JWT URI or 1claw's API-key URI:\n - `urn:ietf:params:oauth:token-type:jwt`\n - `urn:1claw:params:oauth:token-type:api-key`\n",
4984
+ "properties": {
4985
+ "grant_type": {
4986
+ "type": "string",
4987
+ "enum": [
4988
+ "urn:ietf:params:oauth:grant-type:token-exchange"
4989
+ ]
4990
+ },
4991
+ "subject_token": {
4992
+ "type": "string",
4993
+ "description": "1claw JWT or `ocv_` API key authorising the exchange."
4994
+ },
4995
+ "subject_token_type": {
4996
+ "type": "string",
4997
+ "enum": [
4998
+ "urn:ietf:params:oauth:token-type:jwt",
4999
+ "urn:1claw:params:oauth:token-type:api-key"
5000
+ ]
5001
+ },
5002
+ "audience": {
5003
+ "type": "string",
5004
+ "format": "uri",
5005
+ "description": "Required `aud` claim for the issued federation token (must be in agent's allowlist).",
5006
+ "example": "https://api.anthropic.com"
5007
+ },
5008
+ "scope": {
5009
+ "type": "string",
5010
+ "description": "Optional space-separated subset of the agent's existing scopes."
5011
+ },
5012
+ "requested_token_type": {
5013
+ "type": "string",
5014
+ "description": "Optional. Defaults to `urn:ietf:params:oauth:token-type:jwt`."
5015
+ }
5016
+ }
5017
+ },
5018
+ "TokenExchangeResponse": {
5019
+ "type": "object",
5020
+ "required": [
5021
+ "access_token",
5022
+ "issued_token_type",
5023
+ "token_type",
5024
+ "expires_in"
5025
+ ],
5026
+ "properties": {
5027
+ "access_token": {
5028
+ "type": "string",
5029
+ "description": "RS256-signed federation JWT."
5030
+ },
5031
+ "issued_token_type": {
5032
+ "type": "string"
5033
+ },
5034
+ "token_type": {
5035
+ "type": "string"
5036
+ },
5037
+ "expires_in": {
5038
+ "type": "integer"
5039
+ },
5040
+ "scope": {
5041
+ "type": "string"
5042
+ }
5043
+ }
5044
+ },
4672
5045
  "SignupRequest": {
4673
5046
  "type": "object",
4674
5047
  "required": [
@@ -5567,8 +5940,7 @@
5567
5940
  "EnrollAgentRequest": {
5568
5941
  "type": "object",
5569
5942
  "required": [
5570
- "name",
5571
- "human_email"
5943
+ "name"
5572
5944
  ],
5573
5945
  "properties": {
5574
5946
  "name": {
@@ -5578,7 +5950,7 @@
5578
5950
  "human_email": {
5579
5951
  "type": "string",
5580
5952
  "format": "email",
5581
- "description": "Email of the human who will receive the agent credentials"
5953
+ "description": "Optional. If set, pending enrollment is bound to that 1Claw account email\nand Allow/Deny links are emailed. If omitted, only `approval_url` is used\n(link-only enrollment; human must open the URL while signed in).\n"
5582
5954
  },
5583
5955
  "description": {
5584
5956
  "type": "string",
@@ -5592,11 +5964,16 @@
5592
5964
  "agent_id": {
5593
5965
  "type": "string",
5594
5966
  "format": "uuid",
5595
- "description": "UUID of the created agent (nil UUID when email not found — uniform response)"
5967
+ "description": "UUID of the created agent (nil UUID until approved — uniform response)"
5596
5968
  },
5597
5969
  "message": {
5598
5970
  "type": "string",
5599
- "description": "Status message (always generic to prevent email enumeration)"
5971
+ "description": "Status message (worded to limit email enumeration where applicable)"
5972
+ },
5973
+ "approval_url": {
5974
+ "type": "string",
5975
+ "format": "uri",
5976
+ "description": "Present when a pending enrollment was created and the client should show\nthis link (email flow includes it as a fallback; name-only flow requires it).\n"
5600
5977
  }
5601
5978
  }
5602
5979
  },
@@ -5746,6 +6123,25 @@
5746
6123
  },
5747
6124
  "shroud_config": {
5748
6125
  "$ref": "#/components/schemas/ShroudConfig"
6126
+ },
6127
+ "federation_enabled": {
6128
+ "type": "boolean",
6129
+ "description": "Enable OIDC federation (RFC 8693 token-exchange) for this agent.\nWhen true, the agent may call POST /v1/auth/federated-token to mint\nfederation tokens for the audiences listed in `federation_audiences`.\n"
6130
+ },
6131
+ "federation_audiences": {
6132
+ "type": "array",
6133
+ "items": {
6134
+ "type": "string",
6135
+ "format": "uri"
6136
+ },
6137
+ "description": "Allowlist of `aud` values the federation token-exchange may issue\ntokens for (e.g. `[\"https://api.anthropic.com\"]`). Empty array\nblocks all federation requests (zero-trust default).\n"
6138
+ },
6139
+ "federated_token_ttl_seconds": {
6140
+ "type": "integer",
6141
+ "minimum": 60,
6142
+ "maximum": 3600,
6143
+ "nullable": true,
6144
+ "description": "Per-agent TTL override for federation tokens (seconds). NULL falls\nback to the global default (`ONECLAW_JWT_FEDERATED_TOKEN_EXPIRY_SECS`).\nHard-capped at 3600 seconds.\n"
5749
6145
  }
5750
6146
  }
5751
6147
  },
@@ -5851,6 +6247,23 @@
5851
6247
  "shroud_config": {
5852
6248
  "$ref": "#/components/schemas/ShroudConfig"
5853
6249
  },
6250
+ "federation_enabled": {
6251
+ "type": "boolean",
6252
+ "description": "Whether this agent may mint OIDC federation tokens via\nPOST /v1/auth/federated-token. False by default.\n"
6253
+ },
6254
+ "federation_audiences": {
6255
+ "type": "array",
6256
+ "items": {
6257
+ "type": "string",
6258
+ "format": "uri"
6259
+ },
6260
+ "description": "Allowlist of audience URIs the agent may federate to."
6261
+ },
6262
+ "federated_token_ttl_seconds": {
6263
+ "type": "integer",
6264
+ "nullable": true,
6265
+ "description": "Per-agent TTL override for federation tokens (60..=3600)."
6266
+ },
5854
6267
  "created_at": {
5855
6268
  "type": "string",
5856
6269
  "format": "date-time"
@@ -8247,6 +8660,36 @@
8247
8660
  "type": "string"
8248
8661
  }
8249
8662
  },
8663
+ "response_injection_score": {
8664
+ "type": "number",
8665
+ "description": "Response-side prompt-injection score (0.0–1.0)."
8666
+ },
8667
+ "response_context_injection_score": {
8668
+ "type": "number",
8669
+ "description": "Response-side context-injection score (0.0–1.0)."
8670
+ },
8671
+ "response_injection_categories": {
8672
+ "type": "array",
8673
+ "items": {
8674
+ "type": "string"
8675
+ },
8676
+ "description": "Category tags emitted by the response-side filters (e.g. `markdown_image_exfil`, `data_uri_blob`, `echoed_instruction`)."
8677
+ },
8678
+ "external_urls_flagged": {
8679
+ "type": "array",
8680
+ "items": {
8681
+ "type": "string"
8682
+ },
8683
+ "description": "URLs emitted by the model that were flagged as potential exfil / callback targets."
8684
+ },
8685
+ "unexpected_code_blocks": {
8686
+ "type": "integer",
8687
+ "description": "Number of code fences in the response that were not expected for the agent's allowed task set."
8688
+ },
8689
+ "content_filtered": {
8690
+ "type": "boolean",
8691
+ "description": "True when Shroud rewrote or blocked response content before returning it to the agent."
8692
+ },
8250
8693
  "metadata": {
8251
8694
  "type": "object"
8252
8695
  },
@@ -8306,6 +8749,34 @@
8306
8749
  },
8307
8750
  "metadata": {
8308
8751
  "type": "object"
8752
+ },
8753
+ "response_injection_score": {
8754
+ "type": "number",
8755
+ "default": 0
8756
+ },
8757
+ "response_context_injection_score": {
8758
+ "type": "number",
8759
+ "default": 0
8760
+ },
8761
+ "response_injection_categories": {
8762
+ "type": "array",
8763
+ "items": {
8764
+ "type": "string"
8765
+ }
8766
+ },
8767
+ "external_urls_flagged": {
8768
+ "type": "array",
8769
+ "items": {
8770
+ "type": "string"
8771
+ }
8772
+ },
8773
+ "unexpected_code_blocks": {
8774
+ "type": "integer",
8775
+ "default": 0
8776
+ },
8777
+ "content_filtered": {
8778
+ "type": "boolean",
8779
+ "default": false
8309
8780
  }
8310
8781
  }
8311
8782
  },
package/openapi.yaml CHANGED
@@ -2,7 +2,7 @@ openapi: 3.1.0
2
2
 
3
3
  info:
4
4
  title: 1Claw API
5
- version: 2.9.0
5
+ version: 2.10.1
6
6
  description: |
7
7
  Secure secret management for AI agents. Provides vaults, secrets,
8
8
  policy-based access control, agent identity, Intents API,
@@ -192,6 +192,12 @@ paths:
192
192
  Returns the Ed25519 public key used to sign JWTs.
193
193
  Use this to verify tokens independently (e.g. in a TEE proxy or
194
194
  gateway). No authentication required.
195
+
196
+ For OIDC-compliant relying parties (Anthropic Workload Identity
197
+ Federation, etc.) prefer the JWKS endpoint at
198
+ `/.well-known/jwks.json` together with the discovery document
199
+ at `/.well-known/openid-configuration` — those advertise both
200
+ Ed25519 and RS256 keys keyed by `kid` and survive key rotation.
195
201
  operationId: getJwtPublicKey
196
202
  security: []
197
203
  responses:
@@ -210,6 +216,100 @@ paths:
210
216
  type: string
211
217
  description: Base64-encoded Ed25519 public key
212
218
 
219
+ /v1/auth/federated-token:
220
+ post:
221
+ tags: [Authentication]
222
+ summary: Exchange a 1claw token for an OIDC federation token (RFC 8693)
223
+ description: |
224
+ Mints a short-lived RS256-signed JWT targeted at an external
225
+ relying party (e.g. Anthropic Workload Identity Federation).
226
+ The relying party validates the token via this issuer's JWKS
227
+ URL (`/.well-known/jwks.json`) and exchanges it for its own
228
+ short-lived service credentials.
229
+
230
+ Requirements:
231
+ - The agent that owns the `subject_token` must have
232
+ `federation_enabled = true` and the requested `audience`
233
+ must appear in `federation_audiences`.
234
+ - The `subject_token` must be a valid 1claw agent JWT or
235
+ `ocv_` API key.
236
+ - Optional `scope` narrows the agent's existing scopes — it
237
+ cannot escalate.
238
+
239
+ Returns 503 when `ONECLAW_JWT_RS256_SIGNING_KEY_ID` is not
240
+ configured on the server.
241
+ operationId: exchangeFederatedToken
242
+ security: []
243
+ requestBody:
244
+ required: true
245
+ content:
246
+ application/json:
247
+ schema:
248
+ $ref: "#/components/schemas/TokenExchangeRequest"
249
+ application/x-www-form-urlencoded:
250
+ schema:
251
+ $ref: "#/components/schemas/TokenExchangeRequest"
252
+ responses:
253
+ "200":
254
+ description: Federation token issued
255
+ content:
256
+ application/json:
257
+ schema:
258
+ $ref: "#/components/schemas/TokenExchangeResponse"
259
+ "400":
260
+ $ref: "#/components/responses/BadRequest"
261
+ "401":
262
+ $ref: "#/components/responses/Unauthorized"
263
+ "403":
264
+ $ref: "#/components/responses/Forbidden"
265
+ "503":
266
+ description: RS256 signing key not configured
267
+
268
+ /.well-known/openid-configuration:
269
+ get:
270
+ tags: [Authentication]
271
+ summary: OIDC discovery document
272
+ description: |
273
+ Standard OpenID Connect discovery document advertising the
274
+ issuer URL, JWKS URL, supported algorithms (`EdDSA`, `RS256`),
275
+ and the RFC 8693 token-exchange endpoint. External IdPs
276
+ (Anthropic WIF, Okta, Auth0, etc.) read this URL to learn
277
+ where 1claw publishes its JWKS.
278
+ operationId: openidConfiguration
279
+ security: []
280
+ responses:
281
+ "200":
282
+ description: Discovery document
283
+ content:
284
+ application/json:
285
+ schema:
286
+ type: object
287
+
288
+ /.well-known/jwks.json:
289
+ get:
290
+ tags: [Authentication]
291
+ summary: JSON Web Key Set
292
+ description: |
293
+ Public keys for every active version of every JWT signing
294
+ key (Ed25519 + RSA-2048). Each entry includes a `kid` so
295
+ consumers can validate tokens issued before the most recent
296
+ key rotation. Cached for 5 minutes via `Cache-Control` and
297
+ CORS-permissive for browser-based IdP consoles.
298
+ operationId: jwks
299
+ security: []
300
+ responses:
301
+ "200":
302
+ description: JWK Set
303
+ content:
304
+ application/jwk-set+json:
305
+ schema:
306
+ type: object
307
+ properties:
308
+ keys:
309
+ type: array
310
+ items:
311
+ type: object
312
+
213
313
  /v1/auth/signup:
214
314
  post:
215
315
  tags: [Authentication]
@@ -626,6 +726,147 @@ paths:
626
726
  "404":
627
727
  $ref: "#/components/responses/NotFound"
628
728
 
729
+ /v1/auth/export-data:
730
+ post:
731
+ tags: [Authentication]
732
+ summary: Export user data (GDPR)
733
+ description: |
734
+ Returns a full export of the authenticated user's data including
735
+ profile, vaults, agents, secrets metadata, and policies. Intended
736
+ for GDPR data-portability requests. Only available to human users
737
+ (not agents).
738
+ operationId: exportUserData
739
+ responses:
740
+ "200":
741
+ description: User data export
742
+ content:
743
+ application/json:
744
+ schema:
745
+ type: object
746
+ required:
747
+ - export_version
748
+ - exported_at
749
+ - user
750
+ - vaults
751
+ - agents
752
+ - secrets_metadata
753
+ - policies
754
+ properties:
755
+ export_version:
756
+ type: string
757
+ example: "1.0"
758
+ exported_at:
759
+ type: string
760
+ format: date-time
761
+ user:
762
+ type: object
763
+ required:
764
+ - id
765
+ - email
766
+ - display_name
767
+ - auth_method
768
+ - created_at
769
+ properties:
770
+ id:
771
+ type: string
772
+ format: uuid
773
+ email:
774
+ type: string
775
+ format: email
776
+ display_name:
777
+ type: string
778
+ auth_method:
779
+ type: string
780
+ created_at:
781
+ type: string
782
+ format: date-time
783
+ vaults:
784
+ type: array
785
+ items:
786
+ type: object
787
+ required: [id, name, created_at]
788
+ properties:
789
+ id:
790
+ type: string
791
+ format: uuid
792
+ name:
793
+ type: string
794
+ created_at:
795
+ type: string
796
+ format: date-time
797
+ agents:
798
+ type: array
799
+ items:
800
+ type: object
801
+ required: [id, name, created_at]
802
+ properties:
803
+ id:
804
+ type: string
805
+ format: uuid
806
+ name:
807
+ type: string
808
+ created_at:
809
+ type: string
810
+ format: date-time
811
+ secrets_metadata:
812
+ type: array
813
+ items:
814
+ type: object
815
+ required:
816
+ - vault_id
817
+ - path
818
+ - type
819
+ - version
820
+ - created_at
821
+ properties:
822
+ vault_id:
823
+ type: string
824
+ format: uuid
825
+ path:
826
+ type: string
827
+ type:
828
+ type: string
829
+ version:
830
+ type: integer
831
+ created_at:
832
+ type: string
833
+ format: date-time
834
+ policies:
835
+ type: array
836
+ items:
837
+ type: object
838
+ required:
839
+ - id
840
+ - vault_id
841
+ - principal_type
842
+ - principal_id
843
+ - secret_path_pattern
844
+ - permissions
845
+ - created_at
846
+ properties:
847
+ id:
848
+ type: string
849
+ format: uuid
850
+ vault_id:
851
+ type: string
852
+ format: uuid
853
+ principal_type:
854
+ type: string
855
+ principal_id:
856
+ type: string
857
+ format: uuid
858
+ secret_path_pattern:
859
+ type: string
860
+ permissions:
861
+ type: array
862
+ items:
863
+ type: string
864
+ created_at:
865
+ type: string
866
+ format: date-time
867
+ "403":
868
+ $ref: "#/components/responses/Forbidden"
869
+
629
870
  # ---------------------------------------------------------------------------
630
871
  # Vaults
631
872
  # ---------------------------------------------------------------------------
@@ -980,7 +1221,7 @@ paths:
980
1221
  "410":
981
1222
  description: Version has been disabled or expired
982
1223
 
983
- /v1/vaults/{vault_id}/secret-version/{path}/{version}/disable:
1224
+ /v1/vaults/{vault_id}/secret-version-disable/{path}/{version}:
984
1225
  post:
985
1226
  tags: [Secrets]
986
1227
  summary: Disable a specific secret version
@@ -1117,9 +1358,17 @@ paths:
1117
1358
  summary: Self-enroll an agent
1118
1359
  operationId: enrollAgent
1119
1360
  description: |
1120
- Public endpoint (no auth required). Creates an agent under the human's org
1121
- and emails the credentials to the specified human email. The API key is NOT
1122
- returned in the response. Anti-spam: IP rate limiting + per-email cooldown.
1361
+ Public endpoint (no auth required).
1362
+
1363
+ **With `human_email`:** Creates a pending enrollment for that account's org,
1364
+ emails Allow/Deny links, and returns `approval_url` in the JSON body (use if email
1365
+ is delayed). The API key is NOT returned until the human approves.
1366
+
1367
+ **Name only (omit `human_email`):** Creates a link-only pending enrollment.
1368
+ The response includes `approval_url`; the human opens it while signed in to
1369
+ approve the agent into their org.
1370
+
1371
+ Anti-spam: IP rate limiting, per-email cooldown, caps on pending rows.
1123
1372
  requestBody:
1124
1373
  required: true
1125
1374
  content:
@@ -3027,6 +3276,55 @@ components:
3027
3276
  api_key:
3028
3277
  type: string
3029
3278
 
3279
+ TokenExchangeRequest:
3280
+ type: object
3281
+ required: [grant_type, subject_token, subject_token_type, audience]
3282
+ description: |
3283
+ RFC 8693 token-exchange request body. `subject_token_type`
3284
+ accepts the standard JWT URI or 1claw's API-key URI:
3285
+ - `urn:ietf:params:oauth:token-type:jwt`
3286
+ - `urn:1claw:params:oauth:token-type:api-key`
3287
+ properties:
3288
+ grant_type:
3289
+ type: string
3290
+ enum:
3291
+ - "urn:ietf:params:oauth:grant-type:token-exchange"
3292
+ subject_token:
3293
+ type: string
3294
+ description: 1claw JWT or `ocv_` API key authorising the exchange.
3295
+ subject_token_type:
3296
+ type: string
3297
+ enum:
3298
+ - "urn:ietf:params:oauth:token-type:jwt"
3299
+ - "urn:1claw:params:oauth:token-type:api-key"
3300
+ audience:
3301
+ type: string
3302
+ format: uri
3303
+ description: Required `aud` claim for the issued federation token (must be in agent's allowlist).
3304
+ example: "https://api.anthropic.com"
3305
+ scope:
3306
+ type: string
3307
+ description: Optional space-separated subset of the agent's existing scopes.
3308
+ requested_token_type:
3309
+ type: string
3310
+ description: Optional. Defaults to `urn:ietf:params:oauth:token-type:jwt`.
3311
+
3312
+ TokenExchangeResponse:
3313
+ type: object
3314
+ required: [access_token, issued_token_type, token_type, expires_in]
3315
+ properties:
3316
+ access_token:
3317
+ type: string
3318
+ description: RS256-signed federation JWT.
3319
+ issued_token_type:
3320
+ type: string
3321
+ token_type:
3322
+ type: string
3323
+ expires_in:
3324
+ type: integer
3325
+ scope:
3326
+ type: string
3327
+
3030
3328
  SignupRequest:
3031
3329
  type: object
3032
3330
  required: [email, password]
@@ -3651,7 +3949,7 @@ components:
3651
3949
 
3652
3950
  EnrollAgentRequest:
3653
3951
  type: object
3654
- required: [name, human_email]
3952
+ required: [name]
3655
3953
  properties:
3656
3954
  name:
3657
3955
  type: string
@@ -3659,7 +3957,10 @@ components:
3659
3957
  human_email:
3660
3958
  type: string
3661
3959
  format: email
3662
- description: Email of the human who will receive the agent credentials
3960
+ description: |
3961
+ Optional. If set, pending enrollment is bound to that 1Claw account email
3962
+ and Allow/Deny links are emailed. If omitted, only `approval_url` is used
3963
+ (link-only enrollment; human must open the URL while signed in).
3663
3964
  description:
3664
3965
  type: string
3665
3966
  description: Optional agent description
@@ -3670,10 +3971,16 @@ components:
3670
3971
  agent_id:
3671
3972
  type: string
3672
3973
  format: uuid
3673
- description: UUID of the created agent (nil UUID when email not found — uniform response)
3974
+ description: UUID of the created agent (nil UUID until approved — uniform response)
3674
3975
  message:
3675
3976
  type: string
3676
- description: Status message (always generic to prevent email enumeration)
3977
+ description: Status message (worded to limit email enumeration where applicable)
3978
+ approval_url:
3979
+ type: string
3980
+ format: uri
3981
+ description: |
3982
+ Present when a pending enrollment was created and the client should show
3983
+ this link (email flow includes it as a fallback; name-only flow requires it).
3677
3984
 
3678
3985
  # --- Agents ---
3679
3986
 
@@ -3779,6 +4086,30 @@ components:
3779
4086
  description: Enable/disable Shroud LLM Proxy
3780
4087
  shroud_config:
3781
4088
  $ref: "#/components/schemas/ShroudConfig"
4089
+ federation_enabled:
4090
+ type: boolean
4091
+ description: |
4092
+ Enable OIDC federation (RFC 8693 token-exchange) for this agent.
4093
+ When true, the agent may call POST /v1/auth/federated-token to mint
4094
+ federation tokens for the audiences listed in `federation_audiences`.
4095
+ federation_audiences:
4096
+ type: array
4097
+ items:
4098
+ type: string
4099
+ format: uri
4100
+ description: |
4101
+ Allowlist of `aud` values the federation token-exchange may issue
4102
+ tokens for (e.g. `["https://api.anthropic.com"]`). Empty array
4103
+ blocks all federation requests (zero-trust default).
4104
+ federated_token_ttl_seconds:
4105
+ type: integer
4106
+ minimum: 60
4107
+ maximum: 3600
4108
+ nullable: true
4109
+ description: |
4110
+ Per-agent TTL override for federation tokens (seconds). NULL falls
4111
+ back to the global default (`ONECLAW_JWT_FEDERATED_TOKEN_EXPIRY_SECS`).
4112
+ Hard-capped at 3600 seconds.
3782
4113
 
3783
4114
  AgentResponse:
3784
4115
  type: object
@@ -3854,6 +4185,21 @@ components:
3854
4185
  description: Whether this agent routes LLM traffic through the Shroud TEE proxy
3855
4186
  shroud_config:
3856
4187
  $ref: "#/components/schemas/ShroudConfig"
4188
+ federation_enabled:
4189
+ type: boolean
4190
+ description: |
4191
+ Whether this agent may mint OIDC federation tokens via
4192
+ POST /v1/auth/federated-token. False by default.
4193
+ federation_audiences:
4194
+ type: array
4195
+ items:
4196
+ type: string
4197
+ format: uri
4198
+ description: Allowlist of audience URIs the agent may federate to.
4199
+ federated_token_ttl_seconds:
4200
+ type: integer
4201
+ nullable: true
4202
+ description: Per-agent TTL override for federation tokens (60..=3600).
3857
4203
  created_at:
3858
4204
  type: string
3859
4205
  format: date-time
@@ -5502,6 +5848,31 @@ components:
5502
5848
  type: array
5503
5849
  items:
5504
5850
  type: string
5851
+ # Response-side inspection signals (Shroud v0.5.0+,
5852
+ # H-RESP-INSPECT). Optional — pre-v0.5.0 events have them
5853
+ # unset; treat as zero / empty.
5854
+ response_injection_score:
5855
+ type: number
5856
+ description: Response-side prompt-injection score (0.0–1.0).
5857
+ response_context_injection_score:
5858
+ type: number
5859
+ description: Response-side context-injection score (0.0–1.0).
5860
+ response_injection_categories:
5861
+ type: array
5862
+ items:
5863
+ type: string
5864
+ description: Category tags emitted by the response-side filters (e.g. `markdown_image_exfil`, `data_uri_blob`, `echoed_instruction`).
5865
+ external_urls_flagged:
5866
+ type: array
5867
+ items:
5868
+ type: string
5869
+ description: URLs emitted by the model that were flagged as potential exfil / callback targets.
5870
+ unexpected_code_blocks:
5871
+ type: integer
5872
+ description: Number of code fences in the response that were not expected for the agent's allowed task set.
5873
+ content_filtered:
5874
+ type: boolean
5875
+ description: True when Shroud rewrote or blocked response content before returning it to the agent.
5505
5876
  metadata:
5506
5877
  type: object
5507
5878
  timestamp:
@@ -5543,6 +5914,28 @@ components:
5543
5914
  type: string
5544
5915
  metadata:
5545
5916
  type: object
5917
+ # Response-side inspection signals (Shroud v0.5.0+,
5918
+ # H-RESP-INSPECT). Optional for backward compatibility.
5919
+ response_injection_score:
5920
+ type: number
5921
+ default: 0
5922
+ response_context_injection_score:
5923
+ type: number
5924
+ default: 0
5925
+ response_injection_categories:
5926
+ type: array
5927
+ items:
5928
+ type: string
5929
+ external_urls_flagged:
5930
+ type: array
5931
+ items:
5932
+ type: string
5933
+ unexpected_code_blocks:
5934
+ type: integer
5935
+ default: 0
5936
+ content_filtered:
5937
+ type: boolean
5938
+ default: false
5546
5939
 
5547
5940
  ShroudThreatSummary:
5548
5941
  type: object
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@1claw/openapi-spec",
3
- "version": "0.19.1",
3
+ "version": "0.20.2",
4
4
  "description": "OpenAPI 3.1.0 specification for the 1Claw Vault API — generate clients in any language",
5
5
  "license": "MIT",
6
6
  "repository": {