Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
341 changes: 341 additions & 0 deletions apps/api/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -6515,6 +6515,23 @@
"title": "DemoteDatasetRequest",
"type": "object"
},
"DenyRatificationRequest": {
"description": "Body for `POST /ratifications/{ratification_id}/deny`.\n\n`reason` is operator-supplied free text (audit-log breadcrumb) explaining\nthe refusal. MUST NOT contain PII.",
"properties": {
"reason": {
"description": "Operator-supplied reason for the denial (audit-log breadcrumb; no PII).",
"maxLength": 500,
"minLength": 1,
"title": "Reason",
"type": "string"
}
},
"required": [
"reason"
],
"title": "DenyRatificationRequest",
"type": "object"
},
"DeprecateAgentRequest": {
"description": "Body for `POST /agents/{agent_id}/deprecate`.",
"properties": {
Expand Down Expand Up @@ -13206,6 +13223,58 @@
"title": "RemoveRunFromCampaignRequest",
"type": "object"
},
"RequestRatificationRequest": {
"description": "Body for `POST /ratifications`.",
"properties": {
"command_name": {
"description": "Canonical name of the gated command.",
"title": "Command Name",
"type": "string"
},
"consequence_class": {
"description": "Declared class that triggered the requirement (bare-str label).",
"maxLength": 100,
"minLength": 1,
"title": "Consequence Class",
"type": "string"
},
"ratification_id": {
"description": "Caller-supplied UUID. A subscriber may mint a deterministic uuid5 for replay-safe ingest; operator-direct may use uuid4.",
"format": "uuid",
"title": "Ratification Id",
"type": "string"
},
"target_action_id": {
"description": "Opaque id of the action being gated (e.g. the run id whose consequential command is held). Not existence-checked at the decider.",
"format": "uuid",
"title": "Target Action Id",
"type": "string"
}
},
"required": [
"ratification_id",
"target_action_id",
"command_name",
"consequence_class"
],
"title": "RequestRatificationRequest",
"type": "object"
},
"RequestRatificationResponse": {
"description": "Response body for `POST /ratifications`.",
"properties": {
"ratification_id": {
"format": "uuid",
"title": "Ratification Id",
"type": "string"
}
},
"required": [
"ratification_id"
],
"title": "RequestRatificationResponse",
"type": "object"
},
"RestoreAssetRequest": {
"description": "Body for `POST /assets/{asset_id}/restore`.\n\n`reason` is operator-supplied free text (audit-log breadcrumb)\nexplaining the repair. Examples: \"replaced flat cable\", \"cleaned\nsample stage and recalibrated\", \"vacuum pump rebuild complete\".",
"properties": {
Expand Down Expand Up @@ -39378,6 +39447,278 @@
]
}
},
"/ratifications": {
"post": {
"operationId": "post_ratifications_ratifications_post",
"parameters": [
{
"description": "Legacy principal-id header (trust-the-proxy shape). When IDENTITY_PROVIDERS is configured (bearer-auth mode), this header is IGNORED and the verified bearer token from `BearerAuthMiddleware` (Authorization: Bearer) sets the principal. When no IdPs are configured (legacy mode), the application TRUSTS this header (no cryptographic verification) -- production deployments in legacy mode MUST front the API with an auth proxy that strips any client-supplied X-Principal-Id and sets it to the verified principal UUID. Behavior when absent: see Settings.require_authenticated_principal.",
"in": "header",
"name": "X-Principal-Id",
"required": false,
"schema": {
"anyOf": [
{
"format": "uuid",
"type": "string"
},
{
"type": "null"
}
],
"description": "Legacy principal-id header (trust-the-proxy shape). When IDENTITY_PROVIDERS is configured (bearer-auth mode), this header is IGNORED and the verified bearer token from `BearerAuthMiddleware` (Authorization: Bearer) sets the principal. When no IdPs are configured (legacy mode), the application TRUSTS this header (no cryptographic verification) -- production deployments in legacy mode MUST front the API with an auth proxy that strips any client-supplied X-Principal-Id and sets it to the verified principal UUID. Behavior when absent: see Settings.require_authenticated_principal.",
"title": "X-Principal-Id"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RequestRatificationRequest"
}
}
},
"required": true
},
"responses": {
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RequestRatificationResponse"
}
}
},
"description": "Successful Response"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Domain invariant violated (e.g. empty consequence_class)."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Authorize port denied the command."
},
"409": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Ratification with this id already exists."
},
"422": {
"description": "Request body failed schema validation."
}
},
"summary": "Request a second-principal co-signature for a consequential action",
"tags": [
"trust"
]
}
},
"/ratifications/{ratification_id}/deny": {
"post": {
"operationId": "post_ratifications_deny_ratifications__ratification_id__deny_post",
"parameters": [
{
"description": "Target Ratification's id.",
"in": "path",
"name": "ratification_id",
"required": true,
"schema": {
"description": "Target Ratification's id.",
"format": "uuid",
"title": "Ratification Id",
"type": "string"
}
},
{
"description": "Legacy principal-id header (trust-the-proxy shape). When IDENTITY_PROVIDERS is configured (bearer-auth mode), this header is IGNORED and the verified bearer token from `BearerAuthMiddleware` (Authorization: Bearer) sets the principal. When no IdPs are configured (legacy mode), the application TRUSTS this header (no cryptographic verification) -- production deployments in legacy mode MUST front the API with an auth proxy that strips any client-supplied X-Principal-Id and sets it to the verified principal UUID. Behavior when absent: see Settings.require_authenticated_principal.",
"in": "header",
"name": "X-Principal-Id",
"required": false,
"schema": {
"anyOf": [
{
"format": "uuid",
"type": "string"
},
{
"type": "null"
}
],
"description": "Legacy principal-id header (trust-the-proxy shape). When IDENTITY_PROVIDERS is configured (bearer-auth mode), this header is IGNORED and the verified bearer token from `BearerAuthMiddleware` (Authorization: Bearer) sets the principal. When no IdPs are configured (legacy mode), the application TRUSTS this header (no cryptographic verification) -- production deployments in legacy mode MUST front the API with an auth proxy that strips any client-supplied X-Principal-Id and sets it to the verified principal UUID. Behavior when absent: see Settings.require_authenticated_principal.",
"title": "X-Principal-Id"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DenyRatificationRequest"
}
}
},
"required": true
},
"responses": {
"204": {
"description": "Successful Response"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Domain invariant violated (whitespace-only reason)."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Authorize port denied the command."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No Ratification exists with the given id."
},
"409": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Ratification is not in Requested status, or denier is the requester."
},
"422": {
"description": "Request body failed schema validation."
}
},
"summary": "Deny (refuse) a Requested Ratification (Requested -> Denied)",
"tags": [
"trust"
]
}
},
"/ratifications/{ratification_id}/grant": {
"post": {
"operationId": "post_ratifications_grant_ratifications__ratification_id__grant_post",
"parameters": [
{
"description": "Target Ratification's id.",
"in": "path",
"name": "ratification_id",
"required": true,
"schema": {
"description": "Target Ratification's id.",
"format": "uuid",
"title": "Ratification Id",
"type": "string"
}
},
{
"description": "Legacy principal-id header (trust-the-proxy shape). When IDENTITY_PROVIDERS is configured (bearer-auth mode), this header is IGNORED and the verified bearer token from `BearerAuthMiddleware` (Authorization: Bearer) sets the principal. When no IdPs are configured (legacy mode), the application TRUSTS this header (no cryptographic verification) -- production deployments in legacy mode MUST front the API with an auth proxy that strips any client-supplied X-Principal-Id and sets it to the verified principal UUID. Behavior when absent: see Settings.require_authenticated_principal.",
"in": "header",
"name": "X-Principal-Id",
"required": false,
"schema": {
"anyOf": [
{
"format": "uuid",
"type": "string"
},
{
"type": "null"
}
],
"description": "Legacy principal-id header (trust-the-proxy shape). When IDENTITY_PROVIDERS is configured (bearer-auth mode), this header is IGNORED and the verified bearer token from `BearerAuthMiddleware` (Authorization: Bearer) sets the principal. When no IdPs are configured (legacy mode), the application TRUSTS this header (no cryptographic verification) -- production deployments in legacy mode MUST front the API with an auth proxy that strips any client-supplied X-Principal-Id and sets it to the verified principal UUID. Behavior when absent: see Settings.require_authenticated_principal.",
"title": "X-Principal-Id"
}
}
],
"responses": {
"204": {
"description": "Successful Response"
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Authorize port denied the command."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No Ratification exists with the given id."
},
"409": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Ratification is not in Requested status, or grantor is the requester."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
"description": "Validation Error"
}
},
"summary": "Grant (co-sign) a Requested Ratification (Requested -> Granted)",
"tags": [
"trust"
]
}
},
"/recipes": {
"post": {
"operationId": "post_recipes_recipes_post",
Expand Down
6 changes: 6 additions & 0 deletions apps/api/src/cora/agent/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@
PROCEDURE_WATCHER_AGENT_ID,
seed_procedure_watcher_agent,
)
from cora.agent.seed_ratification_enforcer import (
RATIFICATION_ENFORCER_AGENT_ID,
seed_ratification_enforcer_agent,
)
from cora.agent.seed_run_initiator import (
RUN_INITIATOR_AGENT_ID,
seed_run_initiator_agent,
Expand All @@ -91,6 +95,7 @@
"CLEARANCE_WATCHER_AGENT_ID",
"EXPERIMENT_STEERER_AGENT_ID",
"PROCEDURE_WATCHER_AGENT_ID",
"RATIFICATION_ENFORCER_AGENT_ID",
"RUN_INITIATOR_AGENT_ID",
"RUN_SUPERVISOR_AGENT_ID",
"AgentHandlers",
Expand All @@ -114,6 +119,7 @@
"seed_clearance_watcher_agent",
"seed_experiment_steerer_agent",
"seed_procedure_watcher_agent",
"seed_ratification_enforcer_agent",
"seed_run_debriefer_agent",
"seed_run_initiator_agent",
"seed_run_supervisor_agent",
Expand Down
Loading
Loading