{
  "openapi": "3.1.0",
  "info": {
    "title": "varsafe API",
    "version": "1.0.0",
    "summary": "Programmatic access to varsafe secrets management.",
    "description": "varsafe stores environment variables — database URLs, API keys, signing secrets — encrypted at rest, and hands them to the process that needs them without writing a `.env` file to disk.\n\n## When to use this API\n\n- Inject a project environment into a process or pipeline (`GET /secrets/inject`).\n- Read one secret value at the moment it is needed (`GET /secrets/value`), rather than caching a whole environment.\n- Create, update or delete secrets from automation (`POST /secrets`, `POST /secrets/bulk`).\n- Discover what a credential may do before acting (`GET /me/cli`, `GET /capabilities`).\n\nIf you are an AI agent, prefer the Model Context Protocol endpoint at `POST /mcp` over these REST routes: it exposes the same capabilities as typed tools with per-tool scope enforcement and a consent step. See https://docs.varsafe.dev/guides/mcp.\n\n## Authentication\n\nRead the `security` field on each operation — it is derived from what the guards and handlers actually accept, and it is not uniform.\n\nMost routes take an **API token** (`Authorization: Bearer …`), created self-serve in the dashboard and scopable to a project, an environment and read-only access. Routes carrying `x-varsafe-cli-scopes` also accept a **CLI grant** from the device authorization flow and enforce the listed scopes. Four routes are narrower: `GET /me/cli` and `POST /auth/cli/logout` answer only to a CLI grant, because both describe or revoke that grant itself; `POST /auth/cli/device/token` and `GET /auth/cli/device/events` authenticate with the device code rather than an account. `GET /me` accepts a session or a CLI grant but not an API token. The MCP endpoint at `POST /mcp` uses **OAuth 2.1**, or an API token, with the scope vocabulary in `components.securitySchemes.varsafeMcpOAuth`.\n\n## Responses\n\nEvery operation documents its success body with a JSON Schema under `components.schemas`, and every failure with the body the server actually sends: `ErrorResponse` (branch on its `code`) for REST routes, `OAuthErrorResponse` and `JsonRpcErrorResponse` for the MCP transport. The schemas are generated from the same Zod definitions the handlers are type-checked against and that the `@varsafe/shared` package exports. Objects list the properties sent today; a later release may add one, so ignore properties you do not recognise. Streaming routes (`text/event-stream`) describe their events in prose.\n\n## Scope of this document\n\nThis is the programmatic surface: the routes a token, a CLI grant or an agent may call. Dashboard-only and administrative routes are intentionally not described here. The same document is served at https://varsafe.dev/openapi.json and https://api.varsafe.dev/openapi.json.",
    "termsOfService": "https://varsafe.dev/terms",
    "contact": {
      "name": "varsafe support",
      "email": "support@varsafe.dev",
      "url": "https://varsafe.dev/contact"
    },
    "license": {
      "name": "Proprietary — varsafe Terms of Service",
      "url": "https://varsafe.dev/terms"
    }
  },
  "externalDocs": {
    "description": "varsafe documentation",
    "url": "https://docs.varsafe.dev"
  },
  "servers": [
    {
      "url": "https://api.varsafe.dev",
      "description": "Production (EU)"
    }
  ],
  "x-varsafe-scopes": {
    "secrets:read": "List secrets and read their metadata. Never returns a secret value.",
    "secrets:read_values": "Read decrypted secret values.",
    "secrets:write": "Create, update and delete secrets.",
    "secrets:run": "Resolve a full environment for injection into a process.",
    "projects:read": "List projects and environments.",
    "audit:read": "Read the audit trail. Available to MCP credentials only.",
    "identity:read": "Read the identity and team memberships of the calling credential."
  },
  "x-varsafe-mcp": {
    "endpoint": "https://api.varsafe.dev/mcp",
    "transport": "streamable-http",
    "protectedResourceMetadata": "https://api.varsafe.dev/.well-known/oauth-protected-resource/mcp",
    "documentation": "https://docs.varsafe.dev/guides/mcp"
  },
  "tags": [
    {
      "name": "Capabilities",
      "description": "What this deployment supports, so a client can adapt instead of probing."
    },
    {
      "name": "CliDeviceAuth",
      "description": "Device authorization grant — how a CLI or an unattended agent obtains a credential."
    },
    {
      "name": "CliSession",
      "description": "Lifecycle of a CLI grant, including self-revocation."
    },
    {
      "name": "Environments",
      "description": "Environments within a project — development, staging, production, and any others."
    },
    {
      "name": "Health",
      "description": "Liveness and readiness probes."
    },
    {
      "name": "Keypairs",
      "description": "Per-environment keypairs used to encrypt values into a committable .env file."
    },
    {
      "name": "McpTransport",
      "description": "Model Context Protocol endpoint over Streamable HTTP."
    },
    {
      "name": "Me",
      "description": "The identity and authority behind the calling credential."
    },
    {
      "name": "OAuthProviderWellKnown",
      "description": "RFC 8414 and RFC 9728 discovery documents for the OAuth 2.1 flow."
    },
    {
      "name": "Projects",
      "description": "Projects, the top-level grouping that owns environments and secrets."
    },
    {
      "name": "PublicOpenApi",
      "description": "This contract, as a machine-readable document."
    },
    {
      "name": "SecretComposition",
      "description": "How secrets reference one another through ${KEY} templates."
    },
    {
      "name": "Secrets",
      "description": "Reading, writing and resolving secrets. The core of the API."
    }
  ],
  "paths": {
    "/.well-known/oauth-authorization-server": {
      "get": {
        "operationId": "OAuthProviderWellKnownController_authorizationServer",
        "summary": "OAuth 2.1 authorization server metadata",
        "description": "RFC 8414 metadata describing the authorization and token endpoints, supported grant types and the scope vocabulary used by the MCP endpoint.",
        "tags": ["OAuthProviderWellKnown"],
        "parameters": [],
        "security": [],
        "responses": {
          "200": {
            "description": "RFC 8414 authorization server metadata.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthorizationServerMetadata"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/.well-known/oauth-protected-resource": {
      "get": {
        "operationId": "OAuthProviderWellKnownController_protectedResourceRoot",
        "summary": "Protected resource metadata",
        "description": "RFC 9728 metadata naming the authorization server for this API and the scopes it supports.",
        "tags": ["OAuthProviderWellKnown"],
        "parameters": [],
        "security": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProtectedResourceMetadata"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/.well-known/oauth-protected-resource/mcp": {
      "get": {
        "operationId": "OAuthProviderWellKnownController_protectedResourceMcp",
        "summary": "Protected resource metadata for the MCP endpoint",
        "description": "RFC 9728 metadata for https://api.varsafe.dev/mcp. MCP clients read this after a 401 to discover where to authorize.",
        "tags": ["OAuthProviderWellKnown"],
        "parameters": [],
        "security": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProtectedResourceMetadata"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/me/verify": {
      "get": {
        "operationId": "MeController_verify",
        "summary": "Verify the calling credential",
        "description": "Confirms that the presented credential is valid and returns the identity behind it. The cheapest call to make first when diagnosing an authentication problem.",
        "tags": ["Me"],
        "parameters": [],
        "security": [
          {
            "varsafeApiToken": []
          },
          {
            "varsafeCliGrant": []
          },
          {
            "varsafeSessionCookie": []
          }
        ],
        "x-varsafe-cli-scopes": ["identity:read"],
        "x-varsafe-cli-subject": "all-granted-teams",
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VerifyAuthResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/me/token": {
      "delete": {
        "operationId": "MeController_revokeOwnToken",
        "summary": "Revoke the calling API token",
        "description": "Revokes the API token presented on this request. It takes no id, so a token can only ever destroy itself — the safe thing for an automation to call when it believes it has been compromised. Idempotent: revoking an already-revoked token still answers 200.",
        "tags": ["Me"],
        "parameters": [],
        "security": [
          {
            "varsafeApiToken": []
          },
          {
            "varsafeSessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RevokedAck"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/me": {
      "get": {
        "operationId": "MeController_me",
        "summary": "Get the current identity",
        "description": "Returns the user, their teams and the active team for the calling credential.",
        "tags": ["Me"],
        "parameters": [],
        "security": [
          {
            "varsafeCliGrant": []
          },
          {
            "varsafeSessionCookie": []
          }
        ],
        "x-varsafe-cli-scopes": ["identity:read"],
        "x-varsafe-cli-subject": "all-granted-teams",
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MeResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/me/cli": {
      "get": {
        "operationId": "MeController_whoamiCli",
        "summary": "Get the CLI grant behind the credential",
        "description": "Returns what the person who approved this CLI credential consented to: the teams it may act on, the scopes it holds per team, and any project or environment restriction. This is what `varsafe whoami` prints.",
        "tags": ["Me"],
        "parameters": [],
        "security": [
          {
            "varsafeCliGrant": []
          }
        ],
        "x-varsafe-cli-scopes": ["identity:read"],
        "x-varsafe-cli-subject": "all-granted-teams",
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CliWhoamiResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/auth/cli/device": {
      "post": {
        "operationId": "CliDeviceAuthController_start",
        "summary": "Start device authorization",
        "description": "Begins the device authorization grant. Returns a user code and a verification URL that a human opens in a browser to approve the credential, plus a device code to poll with. This is how a CLI or an unattended agent obtains a credential without a password.",
        "tags": ["CliDeviceAuth"],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "anyOf": [
                  {
                    "type": "object",
                    "properties": {
                      "credentialProtection": {
                        "default": "os_keychain",
                        "type": "string",
                        "enum": ["os_keychain", "plaintext_local"]
                      },
                      "installationId": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "machineCredential": {
                        "type": "string",
                        "const": "grant"
                      },
                      "host": {
                        "type": "object",
                        "properties": {
                          "hostname": {
                            "type": "string",
                            "maxLength": 256
                          },
                          "os": {
                            "type": "string",
                            "maxLength": 256
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "additionalProperties": false
                  },
                  {}
                ]
              }
            }
          }
        },
        "security": [],
        "responses": {
          "201": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StartCliDeviceAuthResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/auth/cli/device/token": {
      "post": {
        "operationId": "CliDeviceAuthController_token",
        "summary": "Exchange a device code for a CLI credential",
        "description": "Polls the device authorization grant. Every answer is a 201 whose `status` says where the grant stands: `pending` (keep polling; `reason: slow_down` asks for a longer interval), `failed` (expired or denied — start again), or `granted` / `granted-machine`, which carries the credential exactly once.",
        "tags": ["CliDeviceAuth"],
        "parameters": [],
        "security": [
          {
            "varsafeDeviceCode": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExchangeCliDeviceCodeResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/auth/cli/device/events": {
      "get": {
        "operationId": "CliDeviceAuthController_events",
        "summary": "Stream device-approval events",
        "description": "Server-sent events that signal approval or denial of a pending device authorization, so a client can stop polling immediately instead of waiting for its next interval.",
        "tags": ["CliDeviceAuth"],
        "parameters": [],
        "security": [
          {
            "varsafeDeviceCode": []
          }
        ],
        "responses": {
          "200": {
            "description": "An event stream. Each event is named `connected`, `approved` or `denied`, and its data line is JSON: `{\"event\": \"<name>\"}`, plus `email` on a decision.",
            "content": {
              "text/event-stream": {
                "schema": {
                  "type": "string",
                  "description": "A server-sent event stream (`text/event-stream`); see the operation description."
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/auth/cli/logout": {
      "post": {
        "operationId": "CliSessionController_logout",
        "summary": "Revoke the calling CLI credential",
        "description": "Revokes the CLI grant presented on the request. Self-service and immediate — it needs no scope because it can only ever destroy the caller’s own credential.",
        "tags": ["CliSession"],
        "parameters": [],
        "security": [
          {
            "varsafeCliGrant": []
          }
        ],
        "x-varsafe-cli-scopes": [],
        "x-varsafe-cli-subject": "self",
        "responses": {
          "201": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RevokedAck"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/projects": {
      "get": {
        "operationId": "ProjectsController_list",
        "summary": "List projects",
        "description": "Lists the projects visible to the credential across every team it has been granted. A CLI credential restricted to a subset of projects sees only that subset.",
        "tags": ["Projects"],
        "parameters": [],
        "security": [
          {
            "varsafeApiToken": []
          },
          {
            "varsafeCliGrant": []
          },
          {
            "varsafeSessionCookie": []
          }
        ],
        "x-varsafe-cli-scopes": ["projects:read"],
        "x-varsafe-cli-subject": "each-granted-team",
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectList"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/projects/{projectId}/environments": {
      "get": {
        "operationId": "EnvironmentsController_list",
        "summary": "List environments in a project",
        "description": "Lists the environments of one project — the second half of resolving a `project/environment` context before reading secrets.",
        "tags": ["Environments"],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "security": [
          {
            "varsafeApiToken": []
          },
          {
            "varsafeCliGrant": []
          },
          {
            "varsafeSessionCookie": []
          }
        ],
        "x-varsafe-cli-scopes": ["projects:read"],
        "x-varsafe-cli-subject": "resource-team",
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectEnvironmentList"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/health/live": {
      "get": {
        "operationId": "HealthController_live",
        "summary": "Liveness check",
        "description": "Returns 200 while the process is running. It does not check dependencies — use the readiness probe for that.",
        "tags": ["Health"],
        "parameters": [],
        "security": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LivenessResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/health/ready": {
      "get": {
        "operationId": "HealthController_ready",
        "summary": "Readiness check",
        "description": "Reports whether the API and its dependencies (database, cache, vault) can serve traffic. Returns 503 when any dependency is unavailable.",
        "tags": ["Health"],
        "parameters": [],
        "security": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReadinessResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/NotReady"
          }
        }
      }
    },
    "/environments/{envId}/keypair": {
      "get": {
        "operationId": "KeypairsController_get",
        "summary": "Get an environment public key",
        "description": "Returns the public half of the environment keypair, used to encrypt values into a committable encrypted .env file. The private half is never returned by this route.",
        "tags": ["Keypairs"],
        "parameters": [
          {
            "name": "envId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "security": [
          {
            "varsafeApiToken": []
          },
          {
            "varsafeCliGrant": []
          },
          {
            "varsafeSessionCookie": []
          }
        ],
        "x-varsafe-cli-scopes": ["secrets:read"],
        "x-varsafe-cli-subject": "resource-team",
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EnvironmentKeypair"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/secrets": {
      "post": {
        "operationId": "SecretsController_create",
        "summary": "Create a secret",
        "description": "Creates one secret in a project environment. Fails rather than overwrites when the key already exists.",
        "tags": ["Secrets"],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "projectId": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "environment": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 50,
                    "pattern": "^[a-z0-9][a-z0-9-]*$"
                  },
                  "key": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "pattern": "^[A-Z][A-Z0-9_]*$"
                  },
                  "kind": {
                    "type": "string",
                    "enum": ["literal", "template"]
                  },
                  "value": {
                    "type": "string",
                    "maxLength": 65536
                  },
                  "source": {
                    "type": "string",
                    "maxLength": 65536
                  },
                  "expectedVersion": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  }
                },
                "required": ["projectId", "environment", "key"],
                "additionalProperties": false
              }
            }
          }
        },
        "security": [
          {
            "varsafeApiToken": []
          },
          {
            "varsafeCliGrant": []
          },
          {
            "varsafeSessionCookie": []
          }
        ],
        "x-varsafe-cli-scopes": ["secrets:write"],
        "x-varsafe-cli-subject": "resource-team",
        "responses": {
          "201": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SecretRef"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "get": {
        "operationId": "SecretsController_list",
        "summary": "List secrets",
        "description": "Lists secret keys and metadata for a project environment. Values are never included — that requires `secrets:read_values`.",
        "tags": ["Secrets"],
        "parameters": [
          {
            "name": "projectId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "environment",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 50,
              "pattern": "^[a-z0-9][a-z0-9-]*$"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 10000
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 500
            }
          },
          {
            "name": "representation",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["materialized", "source"]
            }
          }
        ],
        "security": [
          {
            "varsafeApiToken": []
          },
          {
            "varsafeCliGrant": []
          },
          {
            "varsafeSessionCookie": []
          }
        ],
        "x-varsafe-cli-scopes": ["secrets:read"],
        "x-varsafe-cli-subject": "resource-team",
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListSecretsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/secrets/bulk": {
      "post": {
        "operationId": "SecretsController_createBulk",
        "summary": "Create or update secrets in bulk",
        "description": "Writes many secrets to one environment in a single transaction. The intended path for importing an existing .env file.",
        "tags": ["Secrets"],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "projectId": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "environment": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 50,
                    "pattern": "^[a-z0-9][a-z0-9-]*$"
                  },
                  "secrets": {
                    "minItems": 1,
                    "maxItems": 100,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "key": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 255,
                          "pattern": "^[A-Z][A-Z0-9_]*$"
                        },
                        "value": {
                          "type": "string",
                          "maxLength": 65536
                        }
                      },
                      "required": ["key", "value"],
                      "additionalProperties": false
                    }
                  }
                },
                "required": ["projectId", "environment", "secrets"],
                "additionalProperties": false
              }
            }
          }
        },
        "security": [
          {
            "varsafeApiToken": []
          },
          {
            "varsafeCliGrant": []
          },
          {
            "varsafeSessionCookie": []
          }
        ],
        "x-varsafe-cli-scopes": ["secrets:write"],
        "x-varsafe-cli-subject": "resource-team",
        "responses": {
          "201": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkCreateResult"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/secrets/with-values": {
      "get": {
        "operationId": "SecretsController_listWithValues",
        "summary": "List secrets with values",
        "description": "Lists secrets for a project environment including decrypted values. Every call is recorded in the audit trail.",
        "tags": ["Secrets"],
        "parameters": [
          {
            "name": "projectId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "environment",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 50,
              "pattern": "^[a-z0-9][a-z0-9-]*$"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 10000
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 500
            }
          },
          {
            "name": "representation",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["materialized", "source"]
            }
          }
        ],
        "security": [
          {
            "varsafeApiToken": []
          },
          {
            "varsafeCliGrant": []
          },
          {
            "varsafeSessionCookie": []
          }
        ],
        "x-varsafe-cli-scopes": ["secrets:read_values"],
        "x-varsafe-cli-subject": "resource-team",
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SecretWithValueList"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/secrets/value": {
      "get": {
        "operationId": "SecretsController_getValue",
        "summary": "Read one secret value",
        "description": "Returns the decrypted value of a single secret. Prefer this over listing with values when only one key is needed, so the audit trail records what was actually read.",
        "tags": ["Secrets"],
        "parameters": [
          {
            "name": "projectId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "environment",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 50,
              "pattern": "^[a-z0-9][a-z0-9-]*$"
            }
          },
          {
            "name": "key",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255,
              "pattern": "^[A-Z][A-Z0-9_]*$"
            }
          },
          {
            "name": "representation",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["materialized", "source"]
            }
          }
        ],
        "security": [
          {
            "varsafeApiToken": []
          },
          {
            "varsafeCliGrant": []
          },
          {
            "varsafeSessionCookie": []
          }
        ],
        "x-varsafe-cli-scopes": ["secrets:read_values"],
        "x-varsafe-cli-subject": "resource-team",
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SecretWithValue"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/secrets/inject": {
      "get": {
        "operationId": "SecretsController_inject",
        "summary": "Resolve an environment for injection",
        "description": "Returns the fully resolved key/value set for a project environment, with composed secrets expanded. This is what `varsafe run` calls before spawning a child process.",
        "tags": ["Secrets"],
        "parameters": [
          {
            "name": "projectId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "environment",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 50,
              "pattern": "^[a-z0-9][a-z0-9-]*$"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 10000
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 500
            }
          },
          {
            "name": "representation",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["materialized", "source"]
            }
          }
        ],
        "security": [
          {
            "varsafeApiToken": []
          },
          {
            "varsafeCliGrant": []
          },
          {
            "varsafeSessionCookie": []
          }
        ],
        "x-varsafe-cli-scopes": ["secrets:run"],
        "x-varsafe-cli-subject": "resource-team",
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InjectedSecrets"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/secrets/diff": {
      "get": {
        "operationId": "SecretsController_diff",
        "summary": "Diff two environments",
        "description": "Compares the secret keys of two environments and reports what is added, removed or changed. Useful before promoting configuration between environments.",
        "tags": ["Secrets"],
        "parameters": [
          {
            "name": "projectId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "sourceEnv",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 50,
              "pattern": "^[a-z0-9][a-z0-9-]*$"
            }
          },
          {
            "name": "targetEnv",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 50,
              "pattern": "^[a-z0-9][a-z0-9-]*$"
            }
          }
        ],
        "security": [
          {
            "varsafeApiToken": []
          },
          {
            "varsafeCliGrant": []
          },
          {
            "varsafeSessionCookie": []
          }
        ],
        "x-varsafe-cli-scopes": ["secrets:read"],
        "x-varsafe-cli-subject": "resource-team",
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SecretDiff"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/secrets/{secretId}": {
      "delete": {
        "operationId": "SecretsController_delete",
        "summary": "Delete a secret",
        "description": "Deletes one secret from a project environment. The deletion is recorded in the audit trail and, on plans with versioning, earlier versions remain recoverable.",
        "tags": ["Secrets"],
        "parameters": [
          {
            "name": "secretId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "disposition",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["flatten", "cascade"]
            }
          }
        ],
        "security": [
          {
            "varsafeApiToken": []
          },
          {
            "varsafeCliGrant": []
          },
          {
            "varsafeSessionCookie": []
          }
        ],
        "x-varsafe-cli-scopes": ["secrets:write"],
        "x-varsafe-cli-subject": "resource-team",
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeleteSecretResult"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/secrets/delete-bulk": {
      "post": {
        "operationId": "SecretsController_deleteBulk",
        "summary": "Delete secrets in bulk",
        "description": "Deletes several secrets from one environment in a single transaction, so a partial failure leaves the environment unchanged.",
        "tags": ["Secrets"],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "ids": {
                    "minItems": 1,
                    "maxItems": 100,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    }
                  },
                  "projectId": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "environment": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 50,
                    "pattern": "^[a-z0-9][a-z0-9-]*$"
                  }
                },
                "required": ["ids", "projectId", "environment"],
                "additionalProperties": false
              }
            }
          }
        },
        "security": [
          {
            "varsafeApiToken": []
          },
          {
            "varsafeCliGrant": []
          },
          {
            "varsafeSessionCookie": []
          }
        ],
        "x-varsafe-cli-scopes": ["secrets:write"],
        "x-varsafe-cli-subject": "resource-team",
        "responses": {
          "201": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkDeleteResult"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/secrets/composition": {
      "get": {
        "operationId": "SecretCompositionController_composition",
        "summary": "Get the secret composition graph",
        "description": "Returns which secrets reference which others through `${KEY}` templates, so a caller can see what a rotation will change. Returns no values.",
        "tags": ["SecretComposition"],
        "parameters": [
          {
            "name": "projectId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "environment",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 50,
              "pattern": "^[a-z0-9][a-z0-9-]*$"
            }
          }
        ],
        "security": [
          {
            "varsafeApiToken": []
          },
          {
            "varsafeCliGrant": []
          },
          {
            "varsafeSessionCookie": []
          }
        ],
        "x-varsafe-cli-scopes": ["secrets:read"],
        "x-varsafe-cli-subject": "resource-team",
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SecretCompositionGraph"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/capabilities": {
      "get": {
        "operationId": "CapabilitiesController_get",
        "summary": "Get server capabilities",
        "description": "Reports the features and limits this deployment supports, so a client can adapt instead of probing endpoints and interpreting failures.",
        "tags": ["Capabilities"],
        "parameters": [],
        "security": [
          {
            "varsafeApiToken": []
          },
          {
            "varsafeCliGrant": []
          },
          {
            "varsafeSessionCookie": []
          }
        ],
        "x-varsafe-cli-scopes": [],
        "x-varsafe-cli-subject": "self",
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Capabilities"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/mcp": {
      "post": {
        "operationId": "McpTransportController_handlePost",
        "summary": "MCP transport (JSON-RPC request)",
        "description": "Model Context Protocol endpoint over Streamable HTTP. Send JSON-RPC requests here to list and call varsafe tools. Requires an OAuth 2.1 access token whose granted scopes cover the tool being called; an unauthenticated request answers 401 with a WWW-Authenticate header pointing at the protected-resource metadata.",
        "tags": ["McpTransport"],
        "parameters": [],
        "security": [
          {
            "varsafeMcpOAuth": []
          },
          {
            "varsafeApiToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "The JSON-RPC response(s), delivered as a server-sent event stream. The request must `Accept` both `application/json` and `text/event-stream`.",
            "content": {
              "text/event-stream": {
                "schema": {
                  "type": "string",
                  "description": "A server-sent event stream (`text/event-stream`); see the operation description."
                }
              }
            }
          },
          "202": {
            "description": "Accepted: the message carried only notifications or responses, so no reply."
          },
          "400": {
            "$ref": "#/components/responses/McpBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/McpUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/McpForbidden"
          },
          "406": {
            "$ref": "#/components/responses/McpNotAcceptable"
          },
          "415": {
            "$ref": "#/components/responses/McpUnsupportedMediaType"
          },
          "429": {
            "$ref": "#/components/responses/McpRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/McpUnavailable"
          }
        }
      },
      "get": {
        "operationId": "McpTransportController_handleGet",
        "summary": "MCP transport (event stream)",
        "description": "Opens the server-to-client server-sent event stream. The transport is stateless, so the stream carries no session-scoped messages; clients that probe for it get a valid, idle stream.",
        "tags": ["McpTransport"],
        "parameters": [],
        "security": [
          {
            "varsafeMcpOAuth": []
          },
          {
            "varsafeApiToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "The server-to-client event stream.",
            "content": {
              "text/event-stream": {
                "schema": {
                  "type": "string",
                  "description": "A server-sent event stream (`text/event-stream`); see the operation description."
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/McpBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/McpUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/McpForbidden"
          },
          "406": {
            "$ref": "#/components/responses/McpNotAcceptable"
          },
          "429": {
            "$ref": "#/components/responses/McpRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/McpUnavailable"
          }
        }
      },
      "delete": {
        "operationId": "McpTransportController_handleDelete",
        "summary": "MCP transport (end session)",
        "description": "The Streamable HTTP session-teardown call. The transport is stateless — every request stands alone — so there is no server-side session to release and this acknowledges with an empty 200.",
        "tags": ["McpTransport"],
        "parameters": [],
        "security": [
          {
            "varsafeMcpOAuth": []
          },
          {
            "varsafeApiToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Acknowledged, with an empty body."
          },
          "400": {
            "$ref": "#/components/responses/McpBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/McpUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/McpForbidden"
          },
          "429": {
            "$ref": "#/components/responses/McpRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/McpUnavailable"
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "operationId": "PublicOpenApiController_get",
        "summary": "Get this OpenAPI document",
        "description": "Returns this OpenAPI 3.1 document, byte for byte the same file published at https://varsafe.dev/openapi.json. Needs no credential and may be cached for five minutes.",
        "tags": ["PublicOpenApi"],
        "parameters": [],
        "security": [],
        "responses": {
          "200": {
            "description": "This OpenAPI 3.1 document, byte for byte as published at varsafe.dev.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenApiDocument"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "varsafeApiToken": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "varsafe API token",
        "description": "A team-scoped API token, created self-serve in the dashboard and presented as `Authorization: Bearer <token>`. A token can be restricted to specific projects and environments and to read-only access. Intended for CI pipelines and unattended automation."
      },
      "varsafeCliGrant": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "varsafe CLI grant",
        "description": "An opaque, database-backed credential obtained through the device authorization grant (`POST /auth/cli/device`) and revocable on the spot. Presented as `Authorization: Bearer <token>`. A route accepts it only when it declares CLI access; the scopes it must hold are listed per operation under `x-varsafe-cli-scopes`."
      },
      "varsafeSessionCookie": {
        "type": "apiKey",
        "in": "cookie",
        "name": "__Secure-varsafe.session_token",
        "description": "The browser session cookie issued to the dashboard (named `varsafe.session_token` without the `__Secure-` prefix on non-production deployments). Listed for completeness: it authorizes the same routes, but programmatic callers should use an API token or a CLI grant."
      },
      "varsafeDeviceCode": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "varsafe device code",
        "description": "The single-use device code returned by `POST /auth/cli/device`, presented as `Authorization: Bearer <device_code>` while polling for approval. It is a 48-byte secret and never travels in a query string — it is a credential, even though these routes need no account."
      },
      "varsafeMcpOAuth": {
        "type": "oauth2",
        "description": "OAuth 2.1 authorization code flow with PKCE, used by MCP clients against https://api.varsafe.dev/mcp. Clients may register dynamically (RFC 7591). The granted scopes are the intersection of what the client requests and what the approving user may delegate.",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://api.varsafe.dev/auth/oauth2/authorize",
            "tokenUrl": "https://api.varsafe.dev/auth/oauth2/token",
            "refreshUrl": "https://api.varsafe.dev/auth/oauth2/token",
            "scopes": {
              "secrets:read": "List secrets and read their metadata. Never returns a secret value.",
              "secrets:read_values": "Read decrypted secret values.",
              "secrets:write": "Create, update and delete secrets.",
              "secrets:run": "Resolve a full environment for injection into a process.",
              "projects:read": "List projects and environments.",
              "audit:read": "Read the audit trail. Available to MCP credentials only.",
              "identity:read": "Read the identity and team memberships of the calling credential.",
              "offline_access": "Issue a refresh token so the client can keep access without re-consent."
            }
          }
        }
      }
    },
    "schemas": {
      "AuthorizationServerMetadata": {
        "type": "object",
        "properties": {
          "issuer": {
            "type": "string",
            "format": "uri"
          },
          "authorization_endpoint": {
            "type": "string",
            "format": "uri"
          },
          "token_endpoint": {
            "type": "string",
            "format": "uri"
          },
          "registration_endpoint": {
            "description": "Dynamic client registration (RFC 7591), when enabled.",
            "type": "string",
            "format": "uri"
          },
          "scopes_supported": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "response_types_supported": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "grant_types_supported": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "code_challenge_methods_supported": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "issuer",
          "authorization_endpoint",
          "token_endpoint",
          "response_types_supported"
        ],
        "additionalProperties": {},
        "description": "RFC 8414 OAuth 2.0 authorization server metadata. Further standard members may be present."
      },
      "BulkCreateResult": {
        "type": "object",
        "properties": {
          "created": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "updated": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "failed": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string"
                },
                "status": {
                  "type": "string",
                  "enum": ["created", "updated", "failed"]
                },
                "error": {
                  "type": "string"
                }
              },
              "required": ["key", "status"]
            }
          }
        },
        "required": ["created", "updated", "failed", "results"]
      },
      "BulkDeleteResult": {
        "type": "object",
        "properties": {
          "deleted": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "failed": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          }
        },
        "required": ["deleted", "failed"]
      },
      "Capabilities": {
        "type": "object",
        "properties": {
          "secretComposition": {
            "type": "boolean"
          }
        },
        "required": ["secretComposition"]
      },
      "CliWhoamiResponse": {
        "type": "object",
        "properties": {
          "account": {
            "type": "object",
            "properties": {
              "userId": {
                "type": "string"
              },
              "email": {
                "type": "string",
                "format": "email"
              },
              "name": {
                "type": ["string", "null"]
              }
            },
            "required": ["userId", "email", "name"]
          },
          "grant": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": ["string", "null"]
              },
              "createdAt": {
                "type": "string",
                "format": "date-time"
              },
              "lastUsedAt": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "date-time"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "lastUsedIp": {
                "type": ["string", "null"]
              },
              "expiresAt": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "date-time"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "teams": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "teamId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "teamName": {
                      "type": "string"
                    },
                    "scopes": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "enum": [
                          "secrets:read",
                          "secrets:read_values",
                          "secrets:write",
                          "secrets:run",
                          "projects:read",
                          "identity:read"
                        ]
                      }
                    },
                    "projectSelection": {
                      "type": "string",
                      "enum": ["all", "subset"]
                    },
                    "environmentSelection": {
                      "type": "string",
                      "enum": ["all", "subset"]
                    }
                  },
                  "required": [
                    "teamId",
                    "teamName",
                    "scopes",
                    "projectSelection",
                    "environmentSelection"
                  ]
                }
              }
            },
            "required": [
              "id",
              "name",
              "createdAt",
              "lastUsedAt",
              "lastUsedIp",
              "expiresAt",
              "teams"
            ]
          }
        },
        "required": ["account", "grant"]
      },
      "DeleteSecretResult": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string"
          },
          "alsoDeleted": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "flattened": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": ["key", "alsoDeleted", "flattened"]
      },
      "EnvironmentKeypair": {
        "type": "object",
        "properties": {
          "keyId": {
            "type": "string"
          },
          "publicKey": {
            "type": "string"
          },
          "version": {
            "type": "number"
          },
          "isActive": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "rotatedAt": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": ["keyId", "publicKey", "version", "isActive", "createdAt", "rotatedAt"]
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "statusCode": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991,
            "description": "HTTP status code, repeated in the body."
          },
          "code": {
            "type": "string",
            "description": "Stable machine-readable error code, e.g. `SECRET_NOT_FOUND` or `FORBIDDEN`. Branch on this, never on the message."
          },
          "message": {
            "type": "string",
            "description": "Human-readable explanation. Wording may change."
          },
          "field": {
            "description": "The offending request field, present on validation failures.",
            "type": "string"
          }
        },
        "required": ["statusCode", "code", "message"],
        "description": "The error body every failing varsafe REST endpoint returns."
      },
      "ExchangeCliDeviceCodeResponse": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "const": "pending"
              },
              "reason": {
                "type": "string",
                "enum": ["authorization_pending", "slow_down"]
              }
            },
            "required": ["status", "reason"]
          },
          {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "const": "failed"
              },
              "reason": {
                "type": "string",
                "enum": ["expired", "denied"]
              }
            },
            "required": ["status", "reason"]
          },
          {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "const": "granted"
              },
              "token": {
                "type": "string",
                "minLength": 1
              },
              "grantId": {
                "type": "string",
                "format": "uuid"
              },
              "account": {
                "type": "object",
                "properties": {
                  "userId": {
                    "type": "string"
                  },
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "name": {
                    "type": ["string", "null"]
                  }
                },
                "required": ["userId", "email", "name"]
              },
              "teams": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "teamId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "teamName": {
                      "type": "string"
                    },
                    "scopes": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "enum": [
                          "secrets:read",
                          "secrets:read_values",
                          "secrets:write",
                          "secrets:run",
                          "projects:read",
                          "identity:read"
                        ]
                      }
                    }
                  },
                  "required": ["teamId", "teamName", "scopes"]
                }
              }
            },
            "required": ["status", "token", "grantId", "account", "teams"]
          },
          {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "const": "granted-machine"
              },
              "token": {
                "type": "string",
                "minLength": 1
              },
              "apiTokenId": {
                "type": "string",
                "minLength": 1
              },
              "grantId": {
                "type": "string",
                "format": "uuid"
              },
              "account": {
                "type": "object",
                "properties": {
                  "userId": {
                    "type": "string"
                  },
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "name": {
                    "type": ["string", "null"]
                  }
                },
                "required": ["userId", "email", "name"]
              },
              "team": {
                "type": "object",
                "properties": {
                  "teamId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "teamName": {
                    "type": "string"
                  }
                },
                "required": ["teamId", "teamName"]
              },
              "projects": {
                "minItems": 1,
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "environments": {
                "minItems": 1,
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "teams": {
                "minItems": 1,
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "teamId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "teamName": {
                      "type": "string"
                    },
                    "scopes": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "enum": [
                          "secrets:read",
                          "secrets:read_values",
                          "secrets:write",
                          "secrets:run",
                          "projects:read",
                          "identity:read"
                        ]
                      }
                    }
                  },
                  "required": ["teamId", "teamName", "scopes"]
                }
              },
              "expiresAt": {
                "type": "string",
                "format": "date-time"
              }
            },
            "required": ["status", "token", "account", "expiresAt"]
          }
        ]
      },
      "InjectedSecrets": {
        "type": "object",
        "propertyNames": {
          "type": "string"
        },
        "additionalProperties": {
          "type": "string"
        }
      },
      "JsonRpcErrorResponse": {
        "type": "object",
        "properties": {
          "jsonrpc": {
            "type": "string",
            "const": "2.0"
          },
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "message": {
                "type": "string"
              },
              "data": {}
            },
            "required": ["code", "message"]
          },
          "id": {
            "type": ["string", "number", "null"]
          }
        },
        "required": ["jsonrpc", "error", "id"],
        "description": "A JSON-RPC 2.0 error, returned by the MCP transport before any tool runs."
      },
      "ListSecretsResponse": {
        "anyOf": [
          {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SecretRef"
            }
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/SecretRef"
                }
              },
              "total": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "page": {
                "type": "integer",
                "exclusiveMinimum": 0,
                "maximum": 9007199254740991
              },
              "pageSize": {
                "type": "integer",
                "exclusiveMinimum": 0,
                "maximum": 9007199254740991
              }
            },
            "required": ["data", "total", "page", "pageSize"]
          }
        ]
      },
      "LivenessResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": ["ok", "disabled"]
          }
        },
        "required": ["status"]
      },
      "MeResponse": {
        "type": "object",
        "properties": {
          "user": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "minLength": 1
              },
              "email": {
                "type": "string",
                "format": "email"
              },
              "name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 255
              },
              "createdAt": {
                "type": "string"
              },
              "emailVerified": {
                "type": "boolean"
              },
              "hasPassword": {
                "type": "boolean"
              },
              "twoFactorEnabled": {
                "type": "boolean"
              },
              "passkeyOnlyMode": {
                "type": "boolean"
              },
              "isPlatformAdmin": {
                "type": "boolean"
              }
            },
            "required": ["id", "email", "name", "createdAt"]
          },
          "teams": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "name": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 255
                },
                "role": {
                  "type": "string",
                  "enum": ["owner", "admin", "developer", "operator", "viewer", "billing"]
                }
              },
              "required": ["id", "name", "role"]
            }
          },
          "maxActiveSessions": {
            "type": "number"
          },
          "activeSessionCount": {
            "type": "number"
          }
        },
        "required": ["user", "teams", "maxActiveSessions", "activeSessionCount"]
      },
      "OAuthErrorResponse": {
        "type": "object",
        "properties": {
          "statusCode": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991,
            "description": "HTTP status code, repeated in the body."
          },
          "error": {
            "type": "string",
            "description": "RFC 6750 error code, e.g. `invalid_token` or `insufficient_scope`."
          },
          "error_description": {
            "description": "Human-readable explanation.",
            "type": "string"
          }
        },
        "required": ["statusCode", "error"],
        "description": "An OAuth 2.0 bearer-token error (RFC 6750), as returned by the MCP endpoint."
      },
      "OpenApiDocument": {
        "type": "object",
        "properties": {
          "openapi": {
            "type": "string",
            "const": "3.1.0"
          },
          "info": {
            "type": "object",
            "properties": {
              "title": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            },
            "required": ["title", "version"],
            "additionalProperties": {}
          },
          "paths": {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {}
          }
        },
        "required": ["openapi", "info", "paths"],
        "additionalProperties": {},
        "description": "An OpenAPI 3.1 document — this one."
      },
      "Project": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "teamId": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": ["id", "name", "teamId", "createdAt"]
      },
      "ProjectEnvironment": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "projectId": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "slug": {
            "type": "string",
            "minLength": 1,
            "maxLength": 50
          },
          "color": {
            "type": "string",
            "pattern": "^#[0-9A-Fa-f]{6}$"
          },
          "sortOrder": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "isProtected": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "projectId",
          "name",
          "slug",
          "color",
          "sortOrder",
          "isProtected",
          "createdAt",
          "updatedAt"
        ]
      },
      "ProjectEnvironmentList": {
        "type": "array",
        "items": {
          "$ref": "#/components/schemas/ProjectEnvironment"
        }
      },
      "ProjectList": {
        "type": "array",
        "items": {
          "$ref": "#/components/schemas/Project"
        }
      },
      "ProtectedResourceMetadata": {
        "type": "object",
        "properties": {
          "resource": {
            "type": "string",
            "format": "uri",
            "description": "The MCP endpoint these tokens are for."
          },
          "authorization_servers": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uri"
            },
            "description": "Where to obtain an access token."
          },
          "scopes_supported": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "secrets:read",
                "secrets:read_values",
                "secrets:write",
                "secrets:run",
                "projects:read",
                "audit:read",
                "identity:read",
                "offline_access"
              ]
            }
          },
          "bearer_methods_supported": {
            "type": "array",
            "items": {
              "type": "string",
              "const": "header"
            }
          }
        },
        "required": [
          "resource",
          "authorization_servers",
          "scopes_supported",
          "bearer_methods_supported"
        ],
        "description": "RFC 9728 OAuth 2.0 protected resource metadata."
      },
      "ReadinessFailure": {
        "type": "object",
        "properties": {
          "statusCode": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991,
            "description": "HTTP status code, repeated in the body."
          },
          "status": {
            "type": "string",
            "description": "The failing verdict, e.g. `error`."
          }
        },
        "required": ["statusCode", "status"],
        "description": "Readiness failure. Deliberately names no dependency: the probe is unauthenticated, and which dependency is down is a map of the deployment."
      },
      "ReadinessResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "minLength": 1
          }
        },
        "required": ["status"]
      },
      "RevokedAck": {
        "type": "object",
        "properties": {
          "revoked": {
            "type": "boolean",
            "const": true
          }
        },
        "required": ["revoked"]
      },
      "SecretCompositionGraph": {
        "type": "object",
        "properties": {
          "projectId": {
            "type": "string",
            "format": "uuid"
          },
          "environment": {
            "type": "string",
            "minLength": 1,
            "maxLength": 50,
            "pattern": "^[a-z0-9][a-z0-9-]*$"
          },
          "nodes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 255
                },
                "kind": {
                  "type": "string",
                  "enum": ["literal", "template"]
                },
                "dependsOn": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "version": {
                  "type": "integer",
                  "exclusiveMinimum": 0,
                  "maximum": 9007199254740991
                },
                "dialect": {
                  "type": "string"
                }
              },
              "required": ["key", "kind", "dependsOn", "version"]
            }
          }
        },
        "required": ["projectId", "environment", "nodes"]
      },
      "SecretDiff": {
        "type": "object",
        "properties": {
          "project": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "source": {
            "type": "string",
            "minLength": 1,
            "maxLength": 50,
            "pattern": "^[a-z0-9][a-z0-9-]*$"
          },
          "target": {
            "type": "string",
            "minLength": 1,
            "maxLength": 50,
            "pattern": "^[a-z0-9][a-z0-9-]*$"
          },
          "onlyInSource": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          },
          "onlyInTarget": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          },
          "different": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          },
          "identical": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        },
        "required": [
          "project",
          "source",
          "target",
          "onlyInSource",
          "onlyInTarget",
          "different",
          "identical"
        ]
      },
      "SecretRef": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "projectId": {
            "type": "string",
            "format": "uuid"
          },
          "environment": {
            "type": "string",
            "minLength": 1,
            "maxLength": 50,
            "pattern": "^[a-z0-9][a-z0-9-]*$"
          },
          "key": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "version": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "maximum": 9007199254740991
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": ["id", "projectId", "environment", "key", "version", "createdAt", "updatedAt"]
      },
      "SecretWithValue": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "projectId": {
            "type": "string",
            "format": "uuid"
          },
          "environment": {
            "type": "string",
            "minLength": 1,
            "maxLength": 50,
            "pattern": "^[a-z0-9][a-z0-9-]*$"
          },
          "key": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "version": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "maximum": 9007199254740991
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "value": {
            "type": "string",
            "maxLength": 65536
          },
          "kind": {
            "type": "string",
            "enum": ["literal", "template"]
          },
          "dependencies": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "id",
          "projectId",
          "environment",
          "key",
          "version",
          "createdAt",
          "updatedAt",
          "value"
        ]
      },
      "SecretWithValueList": {
        "type": "array",
        "items": {
          "$ref": "#/components/schemas/SecretWithValue"
        }
      },
      "StartCliDeviceAuthResponse": {
        "type": "object",
        "properties": {
          "deviceCode": {
            "type": "string",
            "minLength": 1
          },
          "userCode": {
            "type": "string",
            "minLength": 1
          },
          "verificationUri": {
            "type": "string",
            "format": "uri"
          },
          "verificationUriComplete": {
            "type": "string",
            "format": "uri"
          },
          "expiresInSeconds": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "maximum": 9007199254740991
          },
          "pollIntervalSeconds": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "maximum": 9007199254740991
          }
        },
        "required": [
          "deviceCode",
          "userCode",
          "verificationUri",
          "verificationUriComplete",
          "expiresInSeconds",
          "pollIntervalSeconds"
        ]
      },
      "VerifyAuthResponse": {
        "type": "object",
        "properties": {
          "authenticated": {
            "type": "boolean",
            "const": true
          },
          "type": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "tokenName": {
            "type": ["string", "null"]
          },
          "teamId": {
            "type": ["string", "null"]
          },
          "projects": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "environments": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "accessLevel": {
            "type": "string",
            "enum": ["read", "write"]
          }
        },
        "required": [
          "authenticated",
          "type",
          "label",
          "tokenName",
          "teamId",
          "projects",
          "environments"
        ]
      }
    },
    "responses": {
      "BadRequest": {
        "description": "The request failed validation. `field` names the offending input.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "Forbidden": {
        "description": "The credential is valid but lacks the required scope, role or team access.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "InternalError": {
        "description": "Unexpected server error. The body never carries internal detail.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "McpBadRequest": {
        "description": "The body is not a valid JSON-RPC message, or names an unsupported MCP protocol version.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/JsonRpcErrorResponse"
            }
          }
        }
      },
      "McpForbidden": {
        "description": "The token lacks the grant the transport requires.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/OAuthErrorResponse"
            }
          }
        }
      },
      "McpNotAcceptable": {
        "description": "The `Accept` header must allow both `application/json` and `text/event-stream` (`GET` needs `text/event-stream`).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/JsonRpcErrorResponse"
            }
          }
        }
      },
      "McpRateLimited": {
        "description": "Too many rejected authentication attempts.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/OAuthErrorResponse"
            }
          }
        }
      },
      "McpUnauthorized": {
        "description": "No bearer token, or it is invalid, expired or revoked. The `WWW-Authenticate` header names the protected-resource metadata.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/OAuthErrorResponse"
            }
          }
        }
      },
      "McpUnavailable": {
        "description": "Token verification is temporarily unavailable. Retry later.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/OAuthErrorResponse"
            }
          }
        }
      },
      "McpUnsupportedMediaType": {
        "description": "The request `Content-Type` must be `application/json`.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/JsonRpcErrorResponse"
            }
          }
        }
      },
      "NotFound": {
        "description": "The resource does not exist, or is not visible to this credential.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "NotReady": {
        "description": "A dependency is unavailable. The body names none of them.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ReadinessFailure"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limited. Retry after the interval named in the response.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "No credential was presented, or it is invalid or revoked.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      }
    }
  }
}
