{"openapi":"3.1.0","info":{"title":"rosary API","version":"0.1.0","description":"Autonomous work orchestrator — auth, cert lifecycle, MCP proxy, dispatch"},"servers":[{"url":"https://rosary.bot/api"}],"components":{"schemas":{"CertResponse":{"type":"object","properties":{"certificate":{"type":"string"},"fingerprint":{"type":"string"},"type":{"type":"string"},"expires_at":{"type":"number"},"usage":{"type":"string"},"deprecated":{"type":"string"}},"required":["certificate","fingerprint","type","expires_at"]},"ErrorResponse":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"RateLimitResponse":{"type":"object","properties":{"error":{"type":"string"},"retry_after_seconds":{"type":"number"}},"required":["error","retry_after_seconds"]},"BootstrapRequest":{"type":"object","properties":{"public_key":{"type":"string","description":"PEM-encoded public key (ECDSA P-256 or Ed25519). If omitted, ephemeral key generated at edge."}}},"RegisterRequest":{"type":"object","properties":{"public_key":{"type":"string","description":"PEM-encoded public key. Required when agent_name is set (Go authority path)."},"agent_name":{"type":"string","description":"Agent identifier. When set, routes to Go authority to write OIDAgentName extension."},"scope":{"type":"string","description":"Scope restriction (e.g. repo:signet). Written as OIDScope extension when agent_name is set."}}},"RevokeRequest":{"type":"object","properties":{"fingerprint":{"type":"string","description":"SHA-256 cert fingerprint"},"reason":{"type":"string"}},"required":["fingerprint"]},"McpRequest":{"type":"object","properties":{"tool":{"type":"string"},"params":{"type":"object","additionalProperties":{"nullable":true}}},"required":["tool"]},"SetEnvRequest":{"type":"object","properties":{"vars":{"type":"object","additionalProperties":{"type":"string"}}},"required":["vars"]},"EnvKeysResponse":{"type":"object","properties":{"keys":{"type":"array","items":{"type":"string"}}},"required":["keys"]},"ImportBeadsResponse":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"imported":{"type":"number"},"skipped":{"type":"number"}},"required":["ok","imported","skipped"]},"DeviceTokenResponse":{"type":"object","properties":{"status":{"type":"string","enum":["pending","authorized","complete","expired","error","slow_down","denied"]},"certificate":{"type":"string"},"fingerprint":{"type":"string"},"expires_at":{"type":"number"},"subject":{"type":"string"},"error":{"type":"string"}},"required":["status"]},"DeviceTokenRequest":{"type":"object","properties":{"device_code":{"type":"string"},"public_key":{"type":"string","description":"PEM-encoded public key. Required when status is \"authorized\"."}},"required":["device_code"]},"RotateKeysRequest":{"type":"object","properties":{"old_key":{"type":"string","description":"Current SIGNET_MASTER_KEY PEM"},"new_key":{"type":"string","description":"New SIGNET_MASTER_KEY PEM"},"fix_hkdf":{"type":"boolean","description":"One-time migration from PEM-bytes to seed-based HKDF"},"verify_only":{"type":"boolean","description":"Only verify decryption, do not rotate"}},"required":["old_key","new_key"]},"WorkspaceCreateResponse":{"type":"object","properties":{"branch":{"type":"string"},"sha":{"type":"string"}},"required":["branch","sha"]},"WorkspaceCreateRequest":{"type":"object","properties":{"repo":{"type":"string","description":"Full repo name (owner/repo)"},"bead_id":{"type":"string","description":"Bead ID for the workspace branch"}},"required":["repo","bead_id"]},"WorkspacePRResponse":{"type":"object","properties":{"pr_number":{"type":"number"},"pr_url":{"type":"string"}},"required":["pr_number","pr_url"]},"WorkspacePRRequest":{"type":"object","properties":{"repo":{"type":"string","description":"Full repo name (owner/repo)"},"bead_id":{"type":"string","description":"Bead ID for the workspace branch"},"title":{"type":"string","description":"PR title"},"body":{"type":"string","description":"PR body/description"}},"required":["repo","bead_id","title","body"]}},"parameters":{}},"paths":{"/status":{"get":{"tags":["mcp"],"summary":"MCP server status","responses":{"200":{"description":"Status from rsry"}}}},"/beads":{"get":{"tags":["mcp"],"summary":"List beads","parameters":[{"schema":{"type":"string","description":"Filter by bead status"},"required":false,"description":"Filter by bead status","name":"status","in":"query"}],"responses":{"200":{"description":"Bead list"}}}},"/active":{"get":{"tags":["mcp"],"summary":"Active agents","responses":{"200":{"description":"Active dispatch list"}}}},"/cert/bootstrap":{"post":{"tags":["cert"],"summary":"Mint a bridge cert","security":[{"session":[]},{"bearer":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BootstrapRequest"}}}},"responses":{"200":{"description":"Bridge cert + fingerprint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CertResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitResponse"}}}}}}},"/cert/renew":{"post":{"tags":["cert"],"summary":"Renew expiring cert","security":[{"session":[]},{"bearer":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BootstrapRequest"}}}},"responses":{"200":{"description":"Renewed cert","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CertResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No existing cert","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Not yet eligible","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/cert/register":{"post":{"tags":["cert"],"summary":"Agent self-registration via GitHub token","security":[{"bearer":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterRequest"}}}},"responses":{"200":{"description":"Cert for agent","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CertResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/cert/bridge":{"post":{"tags":["cert"],"summary":"Dedicated bridge cert endpoint","security":[{"session":[]},{"bearer":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BootstrapRequest"}}}},"responses":{"200":{"description":"Bridge cert","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CertResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/cert/revoke":{"post":{"tags":["cert"],"summary":"Revoke a cert by fingerprint","security":[{"session":[]},{"bearer":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevokeRequest"}}}},"responses":{"200":{"description":"Revoked"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/cert/download":{"get":{"tags":["cert"],"summary":"Download cached public cert","security":[{"session":[]}],"responses":{"200":{"description":"PEM file"},"404":{"description":"No cert","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/mcp":{"post":{"tags":["mcp"],"summary":"MCP tool proxy","security":[{"session":[]},{"bearer":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpRequest"}}}},"responses":{"200":{"description":"Tool result"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/settings/env":{"post":{"tags":["settings"],"summary":"Set environment variables (encrypted)","security":[{"session":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetEnvRequest"}}}},"responses":{"200":{"description":"Saved","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"count":{"type":"number"}},"required":["ok","count"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"get":{"tags":["settings"],"summary":"List env var names (no values)","security":[{"session":[]}],"responses":{"200":{"description":"Key names","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvKeysResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/import-beads":{"post":{"tags":["beads"],"summary":"Import beads from rsry export","security":[{"session":[]}],"responses":{"200":{"description":"Import result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportBeadsResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/device/code":{"post":{"tags":["device-flow"],"summary":"Initiate GitHub Device Flow","responses":{"200":{"description":"device_code + user_code"}}}},"/device/token":{"post":{"tags":["device-flow"],"summary":"Poll Device Flow for cert","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceTokenRequest"}}}},"responses":{"200":{"description":"Flow status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceTokenResponse"}}}},"400":{"description":"Missing device_code","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/admin/rotate-keys":{"post":{"tags":["admin"],"summary":"HKDF key rotation for encrypted env vars","security":[{"session":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RotateKeysRequest"}}}},"responses":{"200":{"description":"Rotation result"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/workspace/create":{"post":{"tags":["workspace"],"summary":"Create a workspace branch for a bead","security":[{"session":[]},{"bearer":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceCreateRequest"}}}},"responses":{"200":{"description":"Branch created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceCreateResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/workspace/pr":{"post":{"tags":["workspace"],"summary":"Create a PR from a workspace branch","security":[{"session":[]},{"bearer":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspacePRRequest"}}}},"responses":{"200":{"description":"PR created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspacePRResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}