@1claw/openapi-spec 0.61.45 → 0.61.47
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/openapi.json +445 -1
- package/openapi.yaml +305 -1
- package/package.json +1 -1
package/openapi.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"openapi": "3.1.0",
|
|
3
3
|
"info": {
|
|
4
4
|
"title": "1Claw API",
|
|
5
|
-
"version": "0.61.
|
|
5
|
+
"version": "0.61.47",
|
|
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. Automations (workflow_spec,\nwebhook tokens, event triggers, Assist), cloud runtimes with\ninteractive shell sessions, agent memory, and discovery.\n\n## Domains\n\n`api.1claw.co` is canonical: it is the OIDC issuer, the `aud` the API\nmints, and the first entry in `servers` — a generated client takes its\nbase URL from there, and the previous ordering pointed every SDK at the\ndomain the issuer had already left. `api.1claw.xyz` still answers and is\nstill accepted on token validation, because tokens minted before the\nmove carry it; it is never minted now.\n\nOne deliberate exception: the Shroud attestation identity token is\nrequested from GCP with `audience: https://api.1claw.xyz`, so\n`/v1/shroud/attestation` reports that as its `expected_audience`. That\nis accurate rather than stale — the audience is a verification contract\nwith anyone already checking the token, and moving it is a breaking\nchange for them, not a rename.\n\nAll endpoints require JWT Bearer authentication unless marked with\n`security: []`.\n",
|
|
7
7
|
"contact": {
|
|
8
8
|
"email": "ops@1claw.co"
|
|
@@ -28291,6 +28291,346 @@
|
|
|
28291
28291
|
}
|
|
28292
28292
|
}
|
|
28293
28293
|
},
|
|
28294
|
+
"/v1/connectors/suggest": {
|
|
28295
|
+
"get": {
|
|
28296
|
+
"tags": [
|
|
28297
|
+
"Connectors"
|
|
28298
|
+
],
|
|
28299
|
+
"summary": "Is there a connector for this credential?",
|
|
28300
|
+
"description": "Asked before a secret is written, so the caller can offer to connect the service properly instead of filing a key that cannot do the job. A user stored an X bearer token, a consumer key and a consumer secret and asked their agent to post daily; none of the three can post, because X needs a user-context OAuth grant. Nothing said so until the agent failed.\n\nMatches on both a provider name and a credential word, so `api-keys/x-bearer-token` suggests the X connector and `notes/slack-migration-plan` suggests nothing — a hint that fires on every path is one people learn to scroll past.\n",
|
|
28301
|
+
"operationId": "suggest_connector",
|
|
28302
|
+
"parameters": [
|
|
28303
|
+
{
|
|
28304
|
+
"name": "path",
|
|
28305
|
+
"in": "query",
|
|
28306
|
+
"required": true,
|
|
28307
|
+
"schema": {
|
|
28308
|
+
"type": "string"
|
|
28309
|
+
},
|
|
28310
|
+
"description": "The secret path about to be written."
|
|
28311
|
+
}
|
|
28312
|
+
],
|
|
28313
|
+
"responses": {
|
|
28314
|
+
"200": {
|
|
28315
|
+
"description": "The matching connector, or null.",
|
|
28316
|
+
"content": {
|
|
28317
|
+
"application/json": {
|
|
28318
|
+
"schema": {
|
|
28319
|
+
"type": "object",
|
|
28320
|
+
"required": [
|
|
28321
|
+
"preset"
|
|
28322
|
+
],
|
|
28323
|
+
"properties": {
|
|
28324
|
+
"preset": {
|
|
28325
|
+
"nullable": true,
|
|
28326
|
+
"allOf": [
|
|
28327
|
+
{
|
|
28328
|
+
"$ref": "#/components/schemas/ConnectorPreset"
|
|
28329
|
+
}
|
|
28330
|
+
]
|
|
28331
|
+
}
|
|
28332
|
+
}
|
|
28333
|
+
}
|
|
28334
|
+
}
|
|
28335
|
+
}
|
|
28336
|
+
},
|
|
28337
|
+
"401": {
|
|
28338
|
+
"description": "Unauthenticated"
|
|
28339
|
+
}
|
|
28340
|
+
}
|
|
28341
|
+
}
|
|
28342
|
+
},
|
|
28343
|
+
"/v1/secret-requests": {
|
|
28344
|
+
"post": {
|
|
28345
|
+
"tags": [
|
|
28346
|
+
"Secrets"
|
|
28347
|
+
],
|
|
28348
|
+
"summary": "Ask a human for a credential",
|
|
28349
|
+
"description": "Agent-authenticated. The agent says what it needs and why; the human sees a secure field in the dashboard, stores the value straight into the vault over their own session, and the agent is later told **where** it went — never what it is.\n\nThis exists because the alternative is worse than it looks. Typing a credential into runtime chat persists it to the conversation, writes it into the agent's memory, and replays it to the model on every later turn: one paste, four copies, no way back.\n\nOne open request per agent per label: asking again with the same label refreshes the existing one rather than queueing a duplicate. Unanswered requests expire after 24 hours.\n",
|
|
28350
|
+
"operationId": "create_secret_request",
|
|
28351
|
+
"requestBody": {
|
|
28352
|
+
"required": true,
|
|
28353
|
+
"content": {
|
|
28354
|
+
"application/json": {
|
|
28355
|
+
"schema": {
|
|
28356
|
+
"type": "object",
|
|
28357
|
+
"required": [
|
|
28358
|
+
"label",
|
|
28359
|
+
"purpose"
|
|
28360
|
+
],
|
|
28361
|
+
"properties": {
|
|
28362
|
+
"label": {
|
|
28363
|
+
"type": "string",
|
|
28364
|
+
"maxLength": 120,
|
|
28365
|
+
"example": "X API access token"
|
|
28366
|
+
},
|
|
28367
|
+
"purpose": {
|
|
28368
|
+
"type": "string",
|
|
28369
|
+
"maxLength": 500,
|
|
28370
|
+
"description": "Shown to the person being asked. They are handing over a secret and need to know what for.\n",
|
|
28371
|
+
"example": "To post the daily update to X on your behalf."
|
|
28372
|
+
},
|
|
28373
|
+
"suggested_path": {
|
|
28374
|
+
"type": "string",
|
|
28375
|
+
"nullable": true,
|
|
28376
|
+
"description": "A suggestion only — the human picks the vault and may change the path.\n",
|
|
28377
|
+
"example": "api-keys/x-access-token"
|
|
28378
|
+
}
|
|
28379
|
+
}
|
|
28380
|
+
}
|
|
28381
|
+
}
|
|
28382
|
+
}
|
|
28383
|
+
},
|
|
28384
|
+
"responses": {
|
|
28385
|
+
"202": {
|
|
28386
|
+
"description": "Asked. Poll the status route; do not ask in conversation.",
|
|
28387
|
+
"content": {
|
|
28388
|
+
"application/json": {
|
|
28389
|
+
"schema": {
|
|
28390
|
+
"type": "object",
|
|
28391
|
+
"required": [
|
|
28392
|
+
"id",
|
|
28393
|
+
"status",
|
|
28394
|
+
"expires_at",
|
|
28395
|
+
"next"
|
|
28396
|
+
],
|
|
28397
|
+
"properties": {
|
|
28398
|
+
"id": {
|
|
28399
|
+
"type": "string",
|
|
28400
|
+
"format": "uuid"
|
|
28401
|
+
},
|
|
28402
|
+
"status": {
|
|
28403
|
+
"type": "string",
|
|
28404
|
+
"example": "pending"
|
|
28405
|
+
},
|
|
28406
|
+
"expires_at": {
|
|
28407
|
+
"type": "string",
|
|
28408
|
+
"format": "date-time"
|
|
28409
|
+
},
|
|
28410
|
+
"next": {
|
|
28411
|
+
"type": "string"
|
|
28412
|
+
}
|
|
28413
|
+
}
|
|
28414
|
+
}
|
|
28415
|
+
}
|
|
28416
|
+
}
|
|
28417
|
+
},
|
|
28418
|
+
"400": {
|
|
28419
|
+
"description": "Missing label or purpose, or an invalid suggested path"
|
|
28420
|
+
},
|
|
28421
|
+
"403": {
|
|
28422
|
+
"description": "Not an agent. A person storing a credential uses the vault directly.\n"
|
|
28423
|
+
}
|
|
28424
|
+
}
|
|
28425
|
+
},
|
|
28426
|
+
"get": {
|
|
28427
|
+
"tags": [
|
|
28428
|
+
"Secrets"
|
|
28429
|
+
],
|
|
28430
|
+
"summary": "What your agents have asked you for",
|
|
28431
|
+
"description": "User-authenticated. Open requests for the caller's org, newest first, excluding expired ones. Agents cannot call this — they read their own request by id, so one agent can never enumerate which credentials an org holds.\n",
|
|
28432
|
+
"operationId": "list_secret_requests",
|
|
28433
|
+
"responses": {
|
|
28434
|
+
"200": {
|
|
28435
|
+
"description": "Open requests",
|
|
28436
|
+
"content": {
|
|
28437
|
+
"application/json": {
|
|
28438
|
+
"schema": {
|
|
28439
|
+
"type": "object",
|
|
28440
|
+
"required": [
|
|
28441
|
+
"requests"
|
|
28442
|
+
],
|
|
28443
|
+
"properties": {
|
|
28444
|
+
"requests": {
|
|
28445
|
+
"type": "array",
|
|
28446
|
+
"items": {
|
|
28447
|
+
"$ref": "#/components/schemas/SecretRequest"
|
|
28448
|
+
}
|
|
28449
|
+
}
|
|
28450
|
+
}
|
|
28451
|
+
}
|
|
28452
|
+
}
|
|
28453
|
+
}
|
|
28454
|
+
},
|
|
28455
|
+
"403": {
|
|
28456
|
+
"description": "Called by an agent"
|
|
28457
|
+
}
|
|
28458
|
+
}
|
|
28459
|
+
}
|
|
28460
|
+
},
|
|
28461
|
+
"/v1/secret-requests/{id}": {
|
|
28462
|
+
"get": {
|
|
28463
|
+
"tags": [
|
|
28464
|
+
"Secrets"
|
|
28465
|
+
],
|
|
28466
|
+
"summary": "Has my human answered yet?",
|
|
28467
|
+
"description": "The asking agent's own view, and only its own — another agent's request reads as 404 rather than 403, so its existence is not disclosed. A fulfilled request returns a vault id and a path; the value is read separately with `get_secret`.\n\nExpiry is computed on read, so a lapsed request cannot appear live because no sweeper has run.\n",
|
|
28468
|
+
"operationId": "get_secret_request",
|
|
28469
|
+
"parameters": [
|
|
28470
|
+
{
|
|
28471
|
+
"name": "id",
|
|
28472
|
+
"in": "path",
|
|
28473
|
+
"required": true,
|
|
28474
|
+
"schema": {
|
|
28475
|
+
"type": "string",
|
|
28476
|
+
"format": "uuid"
|
|
28477
|
+
}
|
|
28478
|
+
}
|
|
28479
|
+
],
|
|
28480
|
+
"responses": {
|
|
28481
|
+
"200": {
|
|
28482
|
+
"description": "Status and, once fulfilled, where to look",
|
|
28483
|
+
"content": {
|
|
28484
|
+
"application/json": {
|
|
28485
|
+
"schema": {
|
|
28486
|
+
"$ref": "#/components/schemas/SecretRequestAgentView"
|
|
28487
|
+
}
|
|
28488
|
+
}
|
|
28489
|
+
}
|
|
28490
|
+
},
|
|
28491
|
+
"404": {
|
|
28492
|
+
"description": "No such request, or it belongs to another agent"
|
|
28493
|
+
}
|
|
28494
|
+
}
|
|
28495
|
+
}
|
|
28496
|
+
},
|
|
28497
|
+
"/v1/secret-requests/{id}/fulfil": {
|
|
28498
|
+
"post": {
|
|
28499
|
+
"tags": [
|
|
28500
|
+
"Secrets"
|
|
28501
|
+
],
|
|
28502
|
+
"summary": "Tell the agent where you put it",
|
|
28503
|
+
"description": "User-authenticated. Takes a **location, never a value** — by the time this is called the secret is already in the vault, written by the browser with `PUT /v1/vaults/{vault_id}/secrets/{path}` over the user's own session. There is no field here that could carry a plaintext credential, and there should never be one.\n\nFulfilment also grants the asking agent read on exactly that path, and binds the vault to it if the agent has an explicit vault list. Without both, the user hands over a credential and the agent still gets a 403 — the failure this whole flow exists to remove.\n",
|
|
28504
|
+
"operationId": "fulfil_secret_request",
|
|
28505
|
+
"parameters": [
|
|
28506
|
+
{
|
|
28507
|
+
"name": "id",
|
|
28508
|
+
"in": "path",
|
|
28509
|
+
"required": true,
|
|
28510
|
+
"schema": {
|
|
28511
|
+
"type": "string",
|
|
28512
|
+
"format": "uuid"
|
|
28513
|
+
}
|
|
28514
|
+
}
|
|
28515
|
+
],
|
|
28516
|
+
"requestBody": {
|
|
28517
|
+
"required": true,
|
|
28518
|
+
"content": {
|
|
28519
|
+
"application/json": {
|
|
28520
|
+
"schema": {
|
|
28521
|
+
"type": "object",
|
|
28522
|
+
"required": [
|
|
28523
|
+
"vault_id",
|
|
28524
|
+
"path"
|
|
28525
|
+
],
|
|
28526
|
+
"properties": {
|
|
28527
|
+
"vault_id": {
|
|
28528
|
+
"type": "string",
|
|
28529
|
+
"format": "uuid"
|
|
28530
|
+
},
|
|
28531
|
+
"path": {
|
|
28532
|
+
"type": "string",
|
|
28533
|
+
"example": "api-keys/x-access-token"
|
|
28534
|
+
}
|
|
28535
|
+
}
|
|
28536
|
+
}
|
|
28537
|
+
}
|
|
28538
|
+
}
|
|
28539
|
+
},
|
|
28540
|
+
"responses": {
|
|
28541
|
+
"200": {
|
|
28542
|
+
"description": "Fulfilled",
|
|
28543
|
+
"content": {
|
|
28544
|
+
"application/json": {
|
|
28545
|
+
"schema": {
|
|
28546
|
+
"type": "object",
|
|
28547
|
+
"required": [
|
|
28548
|
+
"status",
|
|
28549
|
+
"path",
|
|
28550
|
+
"vault_id",
|
|
28551
|
+
"granted_read"
|
|
28552
|
+
],
|
|
28553
|
+
"properties": {
|
|
28554
|
+
"status": {
|
|
28555
|
+
"type": "string",
|
|
28556
|
+
"example": "fulfilled"
|
|
28557
|
+
},
|
|
28558
|
+
"path": {
|
|
28559
|
+
"type": "string"
|
|
28560
|
+
},
|
|
28561
|
+
"vault_id": {
|
|
28562
|
+
"type": "string",
|
|
28563
|
+
"format": "uuid"
|
|
28564
|
+
},
|
|
28565
|
+
"granted_read": {
|
|
28566
|
+
"type": "boolean",
|
|
28567
|
+
"description": "False when the secret was stored but the read grant could not be written — the agent will need access granted by hand.\n"
|
|
28568
|
+
}
|
|
28569
|
+
}
|
|
28570
|
+
}
|
|
28571
|
+
}
|
|
28572
|
+
}
|
|
28573
|
+
},
|
|
28574
|
+
"400": {
|
|
28575
|
+
"description": "Already answered, expired, or an invalid path"
|
|
28576
|
+
},
|
|
28577
|
+
"403": {
|
|
28578
|
+
"description": "Called by an agent"
|
|
28579
|
+
},
|
|
28580
|
+
"404": {
|
|
28581
|
+
"description": "No such request, or no such vault in this org"
|
|
28582
|
+
}
|
|
28583
|
+
}
|
|
28584
|
+
}
|
|
28585
|
+
},
|
|
28586
|
+
"/v1/secret-requests/{id}/decline": {
|
|
28587
|
+
"post": {
|
|
28588
|
+
"tags": [
|
|
28589
|
+
"Secrets"
|
|
28590
|
+
],
|
|
28591
|
+
"summary": "No, and stop asking",
|
|
28592
|
+
"description": "User-authenticated. The agent's next poll returns `declined` with an instruction not to ask again for the same thing and to say plainly what it cannot do.\n",
|
|
28593
|
+
"operationId": "decline_secret_request",
|
|
28594
|
+
"parameters": [
|
|
28595
|
+
{
|
|
28596
|
+
"name": "id",
|
|
28597
|
+
"in": "path",
|
|
28598
|
+
"required": true,
|
|
28599
|
+
"schema": {
|
|
28600
|
+
"type": "string",
|
|
28601
|
+
"format": "uuid"
|
|
28602
|
+
}
|
|
28603
|
+
}
|
|
28604
|
+
],
|
|
28605
|
+
"responses": {
|
|
28606
|
+
"200": {
|
|
28607
|
+
"description": "Declined",
|
|
28608
|
+
"content": {
|
|
28609
|
+
"application/json": {
|
|
28610
|
+
"schema": {
|
|
28611
|
+
"type": "object",
|
|
28612
|
+
"required": [
|
|
28613
|
+
"status"
|
|
28614
|
+
],
|
|
28615
|
+
"properties": {
|
|
28616
|
+
"status": {
|
|
28617
|
+
"type": "string",
|
|
28618
|
+
"example": "declined"
|
|
28619
|
+
}
|
|
28620
|
+
}
|
|
28621
|
+
}
|
|
28622
|
+
}
|
|
28623
|
+
}
|
|
28624
|
+
},
|
|
28625
|
+
"400": {
|
|
28626
|
+
"description": "Already answered"
|
|
28627
|
+
},
|
|
28628
|
+
"403": {
|
|
28629
|
+
"description": "Called by an agent"
|
|
28630
|
+
}
|
|
28631
|
+
}
|
|
28632
|
+
}
|
|
28633
|
+
},
|
|
28294
28634
|
"/v1/billing/promo/preview": {
|
|
28295
28635
|
"get": {
|
|
28296
28636
|
"tags": [
|
|
@@ -42068,6 +42408,110 @@
|
|
|
42068
42408
|
}
|
|
42069
42409
|
}
|
|
42070
42410
|
},
|
|
42411
|
+
"SecretRequest": {
|
|
42412
|
+
"type": "object",
|
|
42413
|
+
"description": "An agent's open ask, as the human sees it. Carries the request and, once fulfilled, a reference — never a value.\n",
|
|
42414
|
+
"required": [
|
|
42415
|
+
"id",
|
|
42416
|
+
"label",
|
|
42417
|
+
"purpose",
|
|
42418
|
+
"status",
|
|
42419
|
+
"expires_at",
|
|
42420
|
+
"created_at"
|
|
42421
|
+
],
|
|
42422
|
+
"properties": {
|
|
42423
|
+
"id": {
|
|
42424
|
+
"type": "string",
|
|
42425
|
+
"format": "uuid"
|
|
42426
|
+
},
|
|
42427
|
+
"agent_id": {
|
|
42428
|
+
"type": "string",
|
|
42429
|
+
"format": "uuid",
|
|
42430
|
+
"nullable": true
|
|
42431
|
+
},
|
|
42432
|
+
"agent_name": {
|
|
42433
|
+
"type": "string",
|
|
42434
|
+
"nullable": true
|
|
42435
|
+
},
|
|
42436
|
+
"label": {
|
|
42437
|
+
"type": "string",
|
|
42438
|
+
"description": "Written by the agent. Untrusted text — render it as text, never as markup.\n"
|
|
42439
|
+
},
|
|
42440
|
+
"purpose": {
|
|
42441
|
+
"type": "string"
|
|
42442
|
+
},
|
|
42443
|
+
"suggested_path": {
|
|
42444
|
+
"type": "string",
|
|
42445
|
+
"nullable": true
|
|
42446
|
+
},
|
|
42447
|
+
"status": {
|
|
42448
|
+
"type": "string",
|
|
42449
|
+
"enum": [
|
|
42450
|
+
"pending",
|
|
42451
|
+
"fulfilled",
|
|
42452
|
+
"declined",
|
|
42453
|
+
"expired"
|
|
42454
|
+
]
|
|
42455
|
+
},
|
|
42456
|
+
"stored_path": {
|
|
42457
|
+
"type": "string",
|
|
42458
|
+
"nullable": true,
|
|
42459
|
+
"description": "Set on fulfilment. Where the secret went, not what it is."
|
|
42460
|
+
},
|
|
42461
|
+
"vault_id": {
|
|
42462
|
+
"type": "string",
|
|
42463
|
+
"format": "uuid",
|
|
42464
|
+
"nullable": true
|
|
42465
|
+
},
|
|
42466
|
+
"expires_at": {
|
|
42467
|
+
"type": "string",
|
|
42468
|
+
"format": "date-time"
|
|
42469
|
+
},
|
|
42470
|
+
"created_at": {
|
|
42471
|
+
"type": "string",
|
|
42472
|
+
"format": "date-time"
|
|
42473
|
+
}
|
|
42474
|
+
}
|
|
42475
|
+
},
|
|
42476
|
+
"SecretRequestAgentView": {
|
|
42477
|
+
"type": "object",
|
|
42478
|
+
"description": "The same request as the *agent* is allowed to see it: status, and once fulfilled where to look. Deliberately narrower than `SecretRequest` — no `fulfilled_by`, no timestamps, and no field anywhere that could hold a credential.\n",
|
|
42479
|
+
"required": [
|
|
42480
|
+
"id",
|
|
42481
|
+
"status",
|
|
42482
|
+
"next"
|
|
42483
|
+
],
|
|
42484
|
+
"properties": {
|
|
42485
|
+
"id": {
|
|
42486
|
+
"type": "string",
|
|
42487
|
+
"format": "uuid"
|
|
42488
|
+
},
|
|
42489
|
+
"status": {
|
|
42490
|
+
"type": "string",
|
|
42491
|
+
"enum": [
|
|
42492
|
+
"pending",
|
|
42493
|
+
"fulfilled",
|
|
42494
|
+
"declined",
|
|
42495
|
+
"expired"
|
|
42496
|
+
]
|
|
42497
|
+
},
|
|
42498
|
+
"vault_id": {
|
|
42499
|
+
"type": "string",
|
|
42500
|
+
"format": "uuid",
|
|
42501
|
+
"nullable": true,
|
|
42502
|
+
"description": "Present only once fulfilled."
|
|
42503
|
+
},
|
|
42504
|
+
"path": {
|
|
42505
|
+
"type": "string",
|
|
42506
|
+
"nullable": true,
|
|
42507
|
+
"description": "Present only once fulfilled. Read the credential from here with `get_secret`.\n"
|
|
42508
|
+
},
|
|
42509
|
+
"next": {
|
|
42510
|
+
"type": "string",
|
|
42511
|
+
"description": "What to do about this status, in the agent's terms."
|
|
42512
|
+
}
|
|
42513
|
+
}
|
|
42514
|
+
},
|
|
42071
42515
|
"ConnectorPreset": {
|
|
42072
42516
|
"type": "object",
|
|
42073
42517
|
"required": [
|
package/openapi.yaml
CHANGED
|
@@ -2,7 +2,7 @@ openapi: 3.1.0
|
|
|
2
2
|
|
|
3
3
|
info:
|
|
4
4
|
title: 1Claw API
|
|
5
|
-
version: "0.61.
|
|
5
|
+
version: "0.61.47"
|
|
6
6
|
description: |
|
|
7
7
|
Secure secret management for AI agents. Provides vaults, secrets,
|
|
8
8
|
policy-based access control, agent identity, Intents API,
|
|
@@ -18065,6 +18065,254 @@ paths:
|
|
|
18065
18065
|
answered GET would look like a working unsubscribe to a
|
|
18066
18066
|
person and a broken one to the providers scoring the domain.
|
|
18067
18067
|
operationId: marketing_unsubscribe_post
|
|
18068
|
+
/v1/connectors/suggest:
|
|
18069
|
+
get:
|
|
18070
|
+
tags: [Connectors]
|
|
18071
|
+
summary: "Is there a connector for this credential?"
|
|
18072
|
+
description: >
|
|
18073
|
+
Asked before a secret is written, so the caller can offer to
|
|
18074
|
+
connect the service properly instead of filing a key that
|
|
18075
|
+
cannot do the job. A user stored an X bearer token, a consumer
|
|
18076
|
+
key and a consumer secret and asked their agent to post daily;
|
|
18077
|
+
none of the three can post, because X needs a user-context
|
|
18078
|
+
OAuth grant. Nothing said so until the agent failed.
|
|
18079
|
+
|
|
18080
|
+
|
|
18081
|
+
Matches on both a provider name and a credential word, so
|
|
18082
|
+
`api-keys/x-bearer-token` suggests the X connector and
|
|
18083
|
+
`notes/slack-migration-plan` suggests nothing — a hint that
|
|
18084
|
+
fires on every path is one people learn to scroll past.
|
|
18085
|
+
operationId: suggest_connector
|
|
18086
|
+
parameters:
|
|
18087
|
+
- name: path
|
|
18088
|
+
in: query
|
|
18089
|
+
required: true
|
|
18090
|
+
schema: { type: string }
|
|
18091
|
+
description: The secret path about to be written.
|
|
18092
|
+
responses:
|
|
18093
|
+
'200':
|
|
18094
|
+
description: The matching connector, or null.
|
|
18095
|
+
content:
|
|
18096
|
+
application/json:
|
|
18097
|
+
schema:
|
|
18098
|
+
type: object
|
|
18099
|
+
required: [preset]
|
|
18100
|
+
properties:
|
|
18101
|
+
preset:
|
|
18102
|
+
nullable: true
|
|
18103
|
+
allOf:
|
|
18104
|
+
- $ref: '#/components/schemas/ConnectorPreset'
|
|
18105
|
+
'401':
|
|
18106
|
+
description: Unauthenticated
|
|
18107
|
+
/v1/secret-requests:
|
|
18108
|
+
post:
|
|
18109
|
+
tags: [Secrets]
|
|
18110
|
+
summary: "Ask a human for a credential"
|
|
18111
|
+
description: >
|
|
18112
|
+
Agent-authenticated. The agent says what it needs and why; the
|
|
18113
|
+
human sees a secure field in the dashboard, stores the value
|
|
18114
|
+
straight into the vault over their own session, and the agent
|
|
18115
|
+
is later told **where** it went — never what it is.
|
|
18116
|
+
|
|
18117
|
+
|
|
18118
|
+
This exists because the alternative is worse than it looks.
|
|
18119
|
+
Typing a credential into runtime chat persists it to the
|
|
18120
|
+
conversation, writes it into the agent's memory, and replays it
|
|
18121
|
+
to the model on every later turn: one paste, four copies, no
|
|
18122
|
+
way back.
|
|
18123
|
+
|
|
18124
|
+
|
|
18125
|
+
One open request per agent per label: asking again with the
|
|
18126
|
+
same label refreshes the existing one rather than queueing a
|
|
18127
|
+
duplicate. Unanswered requests expire after 24 hours.
|
|
18128
|
+
operationId: create_secret_request
|
|
18129
|
+
requestBody:
|
|
18130
|
+
required: true
|
|
18131
|
+
content:
|
|
18132
|
+
application/json:
|
|
18133
|
+
schema:
|
|
18134
|
+
type: object
|
|
18135
|
+
required: [label, purpose]
|
|
18136
|
+
properties:
|
|
18137
|
+
label:
|
|
18138
|
+
type: string
|
|
18139
|
+
maxLength: 120
|
|
18140
|
+
example: X API access token
|
|
18141
|
+
purpose:
|
|
18142
|
+
type: string
|
|
18143
|
+
maxLength: 500
|
|
18144
|
+
description: >
|
|
18145
|
+
Shown to the person being asked. They are
|
|
18146
|
+
handing over a secret and need to know
|
|
18147
|
+
what for.
|
|
18148
|
+
example: To post the daily update to X on your behalf.
|
|
18149
|
+
suggested_path:
|
|
18150
|
+
type: string
|
|
18151
|
+
nullable: true
|
|
18152
|
+
description: >
|
|
18153
|
+
A suggestion only — the human picks the
|
|
18154
|
+
vault and may change the path.
|
|
18155
|
+
example: api-keys/x-access-token
|
|
18156
|
+
responses:
|
|
18157
|
+
'202':
|
|
18158
|
+
description: Asked. Poll the status route; do not ask in conversation.
|
|
18159
|
+
content:
|
|
18160
|
+
application/json:
|
|
18161
|
+
schema:
|
|
18162
|
+
type: object
|
|
18163
|
+
required: [id, status, expires_at, next]
|
|
18164
|
+
properties:
|
|
18165
|
+
id: { type: string, format: uuid }
|
|
18166
|
+
status: { type: string, example: pending }
|
|
18167
|
+
expires_at: { type: string, format: date-time }
|
|
18168
|
+
next: { type: string }
|
|
18169
|
+
'400':
|
|
18170
|
+
description: Missing label or purpose, or an invalid suggested path
|
|
18171
|
+
'403':
|
|
18172
|
+
description: >
|
|
18173
|
+
Not an agent. A person storing a credential uses the
|
|
18174
|
+
vault directly.
|
|
18175
|
+
get:
|
|
18176
|
+
tags: [Secrets]
|
|
18177
|
+
summary: "What your agents have asked you for"
|
|
18178
|
+
description: >
|
|
18179
|
+
User-authenticated. Open requests for the caller's org, newest
|
|
18180
|
+
first, excluding expired ones. Agents cannot call this — they
|
|
18181
|
+
read their own request by id, so one agent can never enumerate
|
|
18182
|
+
which credentials an org holds.
|
|
18183
|
+
operationId: list_secret_requests
|
|
18184
|
+
responses:
|
|
18185
|
+
'200':
|
|
18186
|
+
description: Open requests
|
|
18187
|
+
content:
|
|
18188
|
+
application/json:
|
|
18189
|
+
schema:
|
|
18190
|
+
type: object
|
|
18191
|
+
required: [requests]
|
|
18192
|
+
properties:
|
|
18193
|
+
requests:
|
|
18194
|
+
type: array
|
|
18195
|
+
items:
|
|
18196
|
+
$ref: '#/components/schemas/SecretRequest'
|
|
18197
|
+
'403':
|
|
18198
|
+
description: Called by an agent
|
|
18199
|
+
/v1/secret-requests/{id}:
|
|
18200
|
+
get:
|
|
18201
|
+
tags: [Secrets]
|
|
18202
|
+
summary: "Has my human answered yet?"
|
|
18203
|
+
description: >
|
|
18204
|
+
The asking agent's own view, and only its own — another agent's
|
|
18205
|
+
request reads as 404 rather than 403, so its existence is not
|
|
18206
|
+
disclosed. A fulfilled request returns a vault id and a path;
|
|
18207
|
+
the value is read separately with `get_secret`.
|
|
18208
|
+
|
|
18209
|
+
|
|
18210
|
+
Expiry is computed on read, so a lapsed request cannot appear
|
|
18211
|
+
live because no sweeper has run.
|
|
18212
|
+
operationId: get_secret_request
|
|
18213
|
+
parameters:
|
|
18214
|
+
- name: id
|
|
18215
|
+
in: path
|
|
18216
|
+
required: true
|
|
18217
|
+
schema: { type: string, format: uuid }
|
|
18218
|
+
responses:
|
|
18219
|
+
'200':
|
|
18220
|
+
description: Status and, once fulfilled, where to look
|
|
18221
|
+
content:
|
|
18222
|
+
application/json:
|
|
18223
|
+
schema:
|
|
18224
|
+
$ref: '#/components/schemas/SecretRequestAgentView'
|
|
18225
|
+
'404':
|
|
18226
|
+
description: No such request, or it belongs to another agent
|
|
18227
|
+
/v1/secret-requests/{id}/fulfil:
|
|
18228
|
+
post:
|
|
18229
|
+
tags: [Secrets]
|
|
18230
|
+
summary: "Tell the agent where you put it"
|
|
18231
|
+
description: >
|
|
18232
|
+
User-authenticated. Takes a **location, never a value** — by
|
|
18233
|
+
the time this is called the secret is already in the vault,
|
|
18234
|
+
written by the browser with
|
|
18235
|
+
`PUT /v1/vaults/{vault_id}/secrets/{path}` over the user's own
|
|
18236
|
+
session. There is no field here that could carry a plaintext
|
|
18237
|
+
credential, and there should never be one.
|
|
18238
|
+
|
|
18239
|
+
|
|
18240
|
+
Fulfilment also grants the asking agent read on exactly that
|
|
18241
|
+
path, and binds the vault to it if the agent has an explicit
|
|
18242
|
+
vault list. Without both, the user hands over a credential and
|
|
18243
|
+
the agent still gets a 403 — the failure this whole flow
|
|
18244
|
+
exists to remove.
|
|
18245
|
+
operationId: fulfil_secret_request
|
|
18246
|
+
parameters:
|
|
18247
|
+
- name: id
|
|
18248
|
+
in: path
|
|
18249
|
+
required: true
|
|
18250
|
+
schema: { type: string, format: uuid }
|
|
18251
|
+
requestBody:
|
|
18252
|
+
required: true
|
|
18253
|
+
content:
|
|
18254
|
+
application/json:
|
|
18255
|
+
schema:
|
|
18256
|
+
type: object
|
|
18257
|
+
required: [vault_id, path]
|
|
18258
|
+
properties:
|
|
18259
|
+
vault_id: { type: string, format: uuid }
|
|
18260
|
+
path:
|
|
18261
|
+
type: string
|
|
18262
|
+
example: api-keys/x-access-token
|
|
18263
|
+
responses:
|
|
18264
|
+
'200':
|
|
18265
|
+
description: Fulfilled
|
|
18266
|
+
content:
|
|
18267
|
+
application/json:
|
|
18268
|
+
schema:
|
|
18269
|
+
type: object
|
|
18270
|
+
required: [status, path, vault_id, granted_read]
|
|
18271
|
+
properties:
|
|
18272
|
+
status: { type: string, example: fulfilled }
|
|
18273
|
+
path: { type: string }
|
|
18274
|
+
vault_id: { type: string, format: uuid }
|
|
18275
|
+
granted_read:
|
|
18276
|
+
type: boolean
|
|
18277
|
+
description: >
|
|
18278
|
+
False when the secret was stored but
|
|
18279
|
+
the read grant could not be written —
|
|
18280
|
+
the agent will need access granted
|
|
18281
|
+
by hand.
|
|
18282
|
+
'400':
|
|
18283
|
+
description: Already answered, expired, or an invalid path
|
|
18284
|
+
'403':
|
|
18285
|
+
description: Called by an agent
|
|
18286
|
+
'404':
|
|
18287
|
+
description: No such request, or no such vault in this org
|
|
18288
|
+
/v1/secret-requests/{id}/decline:
|
|
18289
|
+
post:
|
|
18290
|
+
tags: [Secrets]
|
|
18291
|
+
summary: "No, and stop asking"
|
|
18292
|
+
description: >
|
|
18293
|
+
User-authenticated. The agent's next poll returns `declined`
|
|
18294
|
+
with an instruction not to ask again for the same thing and to
|
|
18295
|
+
say plainly what it cannot do.
|
|
18296
|
+
operationId: decline_secret_request
|
|
18297
|
+
parameters:
|
|
18298
|
+
- name: id
|
|
18299
|
+
in: path
|
|
18300
|
+
required: true
|
|
18301
|
+
schema: { type: string, format: uuid }
|
|
18302
|
+
responses:
|
|
18303
|
+
'200':
|
|
18304
|
+
description: Declined
|
|
18305
|
+
content:
|
|
18306
|
+
application/json:
|
|
18307
|
+
schema:
|
|
18308
|
+
type: object
|
|
18309
|
+
required: [status]
|
|
18310
|
+
properties:
|
|
18311
|
+
status: { type: string, example: declined }
|
|
18312
|
+
'400':
|
|
18313
|
+
description: Already answered
|
|
18314
|
+
'403':
|
|
18315
|
+
description: Called by an agent
|
|
18068
18316
|
/v1/billing/promo/preview:
|
|
18069
18317
|
get:
|
|
18070
18318
|
tags: [Billing]
|
|
@@ -27050,6 +27298,62 @@ components:
|
|
|
27050
27298
|
an approval by reply.
|
|
27051
27299
|
created_at: { type: string, format: date-time }
|
|
27052
27300
|
|
|
27301
|
+
SecretRequest:
|
|
27302
|
+
type: object
|
|
27303
|
+
description: >
|
|
27304
|
+
An agent's open ask, as the human sees it. Carries the request
|
|
27305
|
+
and, once fulfilled, a reference — never a value.
|
|
27306
|
+
required: [id, label, purpose, status, expires_at, created_at]
|
|
27307
|
+
properties:
|
|
27308
|
+
id: { type: string, format: uuid }
|
|
27309
|
+
agent_id: { type: string, format: uuid, nullable: true }
|
|
27310
|
+
agent_name: { type: string, nullable: true }
|
|
27311
|
+
label:
|
|
27312
|
+
type: string
|
|
27313
|
+
description: >
|
|
27314
|
+
Written by the agent. Untrusted text — render it as
|
|
27315
|
+
text, never as markup.
|
|
27316
|
+
purpose: { type: string }
|
|
27317
|
+
suggested_path: { type: string, nullable: true }
|
|
27318
|
+
status:
|
|
27319
|
+
type: string
|
|
27320
|
+
enum: [pending, fulfilled, declined, expired]
|
|
27321
|
+
stored_path:
|
|
27322
|
+
type: string
|
|
27323
|
+
nullable: true
|
|
27324
|
+
description: Set on fulfilment. Where the secret went, not what it is.
|
|
27325
|
+
vault_id: { type: string, format: uuid, nullable: true }
|
|
27326
|
+
expires_at: { type: string, format: date-time }
|
|
27327
|
+
created_at: { type: string, format: date-time }
|
|
27328
|
+
|
|
27329
|
+
SecretRequestAgentView:
|
|
27330
|
+
type: object
|
|
27331
|
+
description: >
|
|
27332
|
+
The same request as the *agent* is allowed to see it: status,
|
|
27333
|
+
and once fulfilled where to look. Deliberately narrower than
|
|
27334
|
+
`SecretRequest` — no `fulfilled_by`, no timestamps, and no
|
|
27335
|
+
field anywhere that could hold a credential.
|
|
27336
|
+
required: [id, status, next]
|
|
27337
|
+
properties:
|
|
27338
|
+
id: { type: string, format: uuid }
|
|
27339
|
+
status:
|
|
27340
|
+
type: string
|
|
27341
|
+
enum: [pending, fulfilled, declined, expired]
|
|
27342
|
+
vault_id:
|
|
27343
|
+
type: string
|
|
27344
|
+
format: uuid
|
|
27345
|
+
nullable: true
|
|
27346
|
+
description: Present only once fulfilled.
|
|
27347
|
+
path:
|
|
27348
|
+
type: string
|
|
27349
|
+
nullable: true
|
|
27350
|
+
description: >
|
|
27351
|
+
Present only once fulfilled. Read the credential from
|
|
27352
|
+
here with `get_secret`.
|
|
27353
|
+
next:
|
|
27354
|
+
type: string
|
|
27355
|
+
description: What to do about this status, in the agent's terms.
|
|
27356
|
+
|
|
27053
27357
|
ConnectorPreset:
|
|
27054
27358
|
type: object
|
|
27055
27359
|
required: [slug, display_name, description, category, binding_type, base_url, requires_oauth]
|