docs/openapi.json
Ref: Size: 55.9 KiB History
{
"components": {
"schemas": {
"APIToken": {
"properties": {
"created_at": {
"type": "string"
},
"expires_at": {
"type": "string"
},
"id": {
"type": "string"
},
"last_used_at": {
"type": "string"
},
"name": {
"type": "string"
},
"revoked_at": {
"type": "string"
}
},
"required": [
"created_at",
"expires_at",
"id",
"last_used_at",
"name",
"revoked_at"
],
"type": "object"
},
"AuditEvent": {
"properties": {
"action": {
"type": "string"
},
"at": {
"format": "date-time",
"type": "string"
},
"detail": {}
},
"required": [
"action",
"at",
"detail"
],
"type": "object"
},
"Capacity": {
"properties": {
"disk_gb": {
"type": "integer"
},
"mem_mb": {
"type": "integer"
},
"vcpus": {
"type": "integer"
}
},
"required": [
"disk_gb",
"mem_mb",
"vcpus"
],
"type": "object"
},
"CreateAPITokenRequest": {
"properties": {
"name": {
"type": "string"
},
"ttl_seconds": {
"type": "integer"
}
},
"type": "object"
},
"CreateAPITokenResponse": {
"properties": {
"expires_at": {
"type": "string"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"token": {
"type": "string"
}
},
"required": [
"expires_at",
"id",
"name",
"token"
],
"type": "object"
},
"CreateExposureRequest": {
"properties": {
"guest_port": {
"type": "integer"
},
"host_port": {
"type": "integer"
},
"protocol": {
"type": "string"
}
},
"type": "object"
},
"CreateVMRequest": {
"properties": {
"cloud_init": {
"type": "string"
},
"disk_gb": {
"type": "integer"
},
"host_id": {
"type": "string"
},
"image_sha256": {
"type": "string"
},
"image_url": {
"type": "string"
},
"mem_mb": {
"type": "integer"
},
"name": {
"type": "string"
},
"network": {
"type": "string"
},
"power_state": {
"type": "string"
},
"ssh_authorized_key": {
"type": "string"
},
"vcpus": {
"type": "integer"
},
"volume_claims": {
"items": {
"type": "string"
},
"type": "array"
}
},
"type": "object"
},
"CreateVMResponse": {
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"id",
"name"
],
"type": "object"
},
"CreateVolumeClaimRequest": {
"properties": {
"name": {
"type": "string"
},
"size_gb": {
"type": "integer"
}
},
"type": "object"
},
"Delegation": {
"properties": {
"ca_fingerprint": {
"type": "string"
},
"expires_at": {
"type": "string"
},
"key_id": {
"type": "string"
},
"principals": {
"items": {
"type": "string"
},
"type": "array"
},
"public_key": {
"type": "string"
},
"serial": {
"type": "string"
}
},
"required": [
"ca_fingerprint",
"expires_at",
"key_id",
"principals",
"public_key",
"serial"
],
"type": "object"
},
"DelegationChallenge": {
"properties": {
"instructions": {
"type": "string"
},
"principal": {
"type": "string"
},
"public_key": {
"type": "string"
}
},
"required": [
"instructions",
"principal",
"public_key"
],
"type": "object"
},
"DelegationRequest": {
"properties": {
"certificate": {
"type": "string"
}
},
"type": "object"
},
"EnrollRequest": {
"properties": {
"arch": {
"type": "string"
},
"bridge_cidr": {
"type": [
"string",
"null"
]
},
"name": {
"type": "string"
},
"os": {
"type": "string"
},
"provisioner": {
"type": "string"
},
"token": {
"type": "string"
}
},
"type": "object"
},
"EnrollResponse": {
"properties": {
"bridge_cidr": {
"type": "string"
},
"credential": {
"type": "string"
},
"host_id": {
"type": "string"
},
"server_cert_sha256": {
"type": "string"
}
},
"required": [
"bridge_cidr",
"credential",
"host_id",
"server_cert_sha256"
],
"type": "object"
},
"EnrollTokenResponse": {
"properties": {
"join": {
"type": "string"
},
"token": {
"type": "string"
}
},
"required": [
"join",
"token"
],
"type": "object"
},
"Exposure": {
"properties": {
"created_at": {
"format": "date-time",
"type": "string"
},
"guest_port": {
"type": "integer"
},
"host_addr": {
"type": "string"
},
"host_id": {
"type": "string"
},
"host_port": {
"type": "integer"
},
"id": {
"type": "string"
},
"protocol": {
"type": "string"
},
"reason": {
"type": "string"
},
"scope": {
"type": "string"
},
"sessions": {
"anyOf": [
{
"$ref": "#/components/schemas/ExposureSessions"
},
{
"type": "null"
}
]
},
"state": {
"type": "string"
},
"vm_id": {
"type": "string"
}
},
"required": [
"created_at",
"guest_port",
"host_addr",
"host_id",
"host_port",
"id",
"protocol",
"reason",
"scope",
"state",
"vm_id"
],
"type": "object"
},
"ExposureSessions": {
"properties": {
"active": {
"type": "integer"
},
"dropped": {
"type": "integer"
},
"refused": {
"type": "integer"
}
},
"required": [
"active",
"dropped",
"refused"
],
"type": "object"
},
"Host": {
"properties": {
"agent_update_available": {
"type": "boolean"
},
"agent_version": {
"type": "string"
},
"allocated": {
"$ref": "#/components/schemas/Capacity"
},
"arch": {
"type": "string"
},
"bridge_cidr": {
"type": "string"
},
"capacity": {
"$ref": "#/components/schemas/Capacity"
},
"cpu_model": {
"type": "string"
},
"enrolled_at": {
"format": "date-time",
"type": "string"
},
"host_networks": {
"items": {
"type": "string"
},
"type": "array"
},
"id": {
"type": "string"
},
"kernel": {
"type": "string"
},
"last_seen": {
"format": "date-time",
"type": [
"string",
"null"
]
},
"metrics": {
"anyOf": [
{
"$ref": "#/components/schemas/Metrics"
},
{
"type": "null"
}
]
},
"name": {
"type": "string"
},
"online": {
"type": "boolean"
},
"os": {
"type": "string"
},
"os_id": {
"type": "string"
},
"os_pretty": {
"type": "string"
},
"os_version": {
"type": "string"
},
"pending_upgrade": {
"anyOf": [
{
"$ref": "#/components/schemas/PendingUpgrade"
},
{
"type": "null"
}
]
},
"provisioner": {
"type": "string"
},
"seconds_since_last_seen": {
"type": [
"integer",
"null"
]
},
"sessions": {
"type": "integer"
},
"stale": {
"type": "boolean"
},
"status": {
"type": "string"
},
"uplink_addr": {
"type": "string"
},
"virt": {
"type": "string"
}
},
"required": [
"agent_update_available",
"agent_version",
"allocated",
"arch",
"bridge_cidr",
"capacity",
"cpu_model",
"enrolled_at",
"host_networks",
"id",
"kernel",
"name",
"online",
"os",
"os_id",
"os_pretty",
"os_version",
"provisioner",
"sessions",
"stale",
"status",
"uplink_addr",
"virt"
],
"type": "object"
},
"InjectedKey": {
"properties": {
"comment": {
"type": "string"
},
"fingerprint": {
"type": "string"
},
"type": {
"type": "string"
}
},
"required": [
"comment",
"fingerprint",
"type"
],
"type": "object"
},
"Me": {
"properties": {
"email": {
"type": "string"
},
"ssh_gate": {
"type": "string"
},
"tenant": {
"type": "string"
}
},
"required": [
"email",
"ssh_gate",
"tenant"
],
"type": "object"
},
"Metrics": {
"properties": {
"disk_free_gb": {
"type": "integer"
},
"disk_used_gb": {
"type": "integer"
},
"load1": {
"type": "number"
},
"load15": {
"type": "number"
},
"load5": {
"type": "number"
},
"mem_available_mb": {
"type": "integer"
},
"mem_used_mb": {
"type": "integer"
},
"uptime_s": {
"type": "integer"
}
},
"required": [
"disk_free_gb",
"disk_used_gb",
"load1",
"load15",
"load5",
"mem_available_mb",
"mem_used_mb",
"uptime_s"
],
"type": "object"
},
"PatchVMRequest": {
"properties": {
"power_state": {
"type": "string"
}
},
"type": "object"
},
"PendingUpgrade": {
"properties": {
"age_s": {
"type": "integer"
},
"version": {
"type": "string"
}
},
"required": [
"age_s",
"version"
],
"type": "object"
},
"RevokeSSHCertRequest": {
"properties": {
"certificate": {
"type": "string"
},
"reason": {
"type": "string"
},
"serial": {
"type": [
"integer",
"null"
]
}
},
"type": "object"
},
"RevokedCert": {
"properties": {
"reason": {
"type": "string"
},
"revoked_at": {
"format": "date-time",
"type": "string"
},
"serial": {
"type": "string"
}
},
"required": [
"reason",
"revoked_at",
"serial"
],
"type": "object"
},
"SSHCAResponse": {
"properties": {
"ca": {
"type": "string"
}
},
"required": [
"ca"
],
"type": "object"
},
"StateSnapshot": {
"properties": {
"hosts": {
"items": {
"$ref": "#/components/schemas/Host"
},
"type": "array"
},
"latest_version": {
"type": "string"
},
"server_version": {
"type": "string"
},
"vms": {
"items": {
"$ref": "#/components/schemas/VM"
},
"type": "array"
}
},
"required": [
"hosts",
"latest_version",
"server_version",
"vms"
],
"type": "object"
},
"StreamTicketResponse": {
"properties": {
"ticket": {
"type": "string"
}
},
"required": [
"ticket"
],
"type": "object"
},
"TrustedCA": {
"properties": {
"fingerprint": {
"type": "string"
},
"label": {
"type": "string"
}
},
"required": [
"fingerprint",
"label"
],
"type": "object"
},
"UserCA": {
"properties": {
"fingerprint": {
"type": "string"
},
"label": {
"type": "string"
},
"pubkey": {
"type": "string"
}
},
"required": [
"fingerprint",
"label",
"pubkey"
],
"type": "object"
},
"UserCARequest": {
"properties": {
"label": {
"type": "string"
},
"public_key": {
"type": "string"
}
},
"type": "object"
},
"UserCAUploadResponse": {
"properties": {
"fingerprint": {
"type": "string"
}
},
"required": [
"fingerprint"
],
"type": "object"
},
"VM": {
"properties": {
"actual_power": {
"type": "string"
},
"assigned_ip": {
"type": "string"
},
"created_at": {
"format": "date-time",
"type": "string"
},
"deleted": {
"type": "boolean"
},
"destroy_at": {
"type": "integer"
},
"disk_gb": {
"type": "integer"
},
"host_id": {
"type": "string"
},
"id": {
"type": "string"
},
"image_url": {
"type": "string"
},
"injected_key": {
"anyOf": [
{
"$ref": "#/components/schemas/InjectedKey"
},
{
"type": "null"
}
]
},
"last_error": {
"type": "string"
},
"lifecycle": {
"type": "string"
},
"mem_mb": {
"type": "integer"
},
"name": {
"type": "string"
},
"network": {
"type": "string"
},
"network_ip": {
"type": "string"
},
"phase": {
"type": "string"
},
"power_state": {
"type": "string"
},
"status": {
"type": "string"
},
"status_detail": {
"type": "string"
},
"trusted_cas": {
"items": {
"$ref": "#/components/schemas/TrustedCA"
},
"type": [
"array",
"null"
]
},
"vcpus": {
"type": "integer"
}
},
"required": [
"actual_power",
"assigned_ip",
"created_at",
"deleted",
"destroy_at",
"disk_gb",
"host_id",
"id",
"image_url",
"last_error",
"lifecycle",
"mem_mb",
"name",
"network",
"network_ip",
"phase",
"power_state",
"status",
"status_detail",
"vcpus"
],
"type": "object"
},
"VolumeClaim": {
"properties": {
"created_at": {
"format": "date-time",
"type": "string"
},
"host_id": {
"type": "string"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"present": {
"type": [
"boolean",
"null"
]
},
"size_gb": {
"type": "integer"
},
"status": {
"type": "string"
},
"vm_id": {
"type": "string"
}
},
"required": [
"created_at",
"host_id",
"id",
"name",
"size_gb",
"status",
"vm_id"
],
"type": "object"
}
},
"securitySchemes": {
"patToken": {
"scheme": "bearer",
"type": "http"
}
}
},
"info": {
"title": "eitri server API",
"version": "v1"
},
"openapi": "3.1.0",
"paths": {
"/api/v1/audit": {
"get": {
"parameters": [
{
"description": "max rows to return (default 100, cap 1000)",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/AuditEvent"
},
"type": "array"
}
}
},
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "Newest audit log rows."
}
},
"/api/v1/delegations": {
"delete": {
"responses": {
"204": {
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "End the caller tenant's delegation now. eitri drops the certificate and can no longer reach that tenant's VMs."
},
"get": {
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Delegation"
}
}
},
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "Describe the caller tenant's live delegation, including when it expires. 404 when there is none."
},
"post": {
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DelegationChallenge"
}
}
},
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "Start a delegation: returns the ephemeral public key eitri will authenticate with, the principal the certificate must carry, and the ssh-keygen command that signs it. The key is stable for the life of the process once delegated; a begin left unsigned for an hour is abandoned and the next call returns a new key."
},
"put": {
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DelegationRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Delegation"
}
}
},
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "Complete a delegation with the certificate your CA signed. The certificate must be a user certificate over the key this delegation issued, signed by a CA registered to your tenant, naming the guest login user as a principal."
}
},
"/api/v1/enroll": {
"post": {
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/EnrollRequest"
}
}
},
"required": true
},
"responses": {
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/EnrollResponse"
}
}
},
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"summary": "Redeem a one-time enrollment token: a new host joins the fleet and receives its credential. Unauthenticated but rate-limited; the token is the proof."
}
},
"/api/v1/enroll-tokens": {
"post": {
"responses": {
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/EnrollTokenResponse"
}
}
},
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "Mint a one-time host enrollment token plus the join blob agents consume."
}
},
"/api/v1/events": {
"get": {
"parameters": [
{
"description": "one-time stream ticket",
"in": "query",
"name": "ticket",
"required": false,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"text/event-stream": {
"schema": {
"$ref": "#/components/schemas/StateSnapshot"
}
}
},
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"summary": "Live fleet state stream (Server-Sent Events); each 'state' event carries a StateSnapshot."
}
},
"/api/v1/exposures/{id}": {
"delete": {
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"204": {
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "Revoke an exposure; its host closes the listener on the next converge."
}
},
"/api/v1/hosts": {
"get": {
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/Host"
},
"type": "array"
}
}
},
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "List fleet hosts: durable rows merged with live agent state and allocation."
}
},
"/api/v1/hosts/{id}": {
"delete": {
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "purge VM rows and remove the host immediately (dead hardware escape hatch)",
"in": "query",
"name": "force",
"required": false,
"schema": {
"type": "string"
}
}
],
"responses": {
"202": {
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "Decommission a host: tombstone its VMs and drain gracefully (202). With ?force, purge and remove immediately, returning 200."
}
},
"/api/v1/hosts/{id}/revoke-credential": {
"post": {
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"204": {
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "Revoke a host's outstanding credential by bumping its generation; the host stays dark until re-enrolled."
}
},
"/api/v1/hosts/{id}/upgrade-agent": {
"post": {
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"202": {
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "Offer the host's agent a self-upgrade to the latest known release (per-host, human-controlled rollout)."
}
},
"/api/v1/me": {
"get": {
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Me"
}
}
},
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "The signed-in identity: the caller's tenant handle, bound email, and the plane's SSH jump-gate address (empty when it runs no gate)."
}
},
"/api/v1/ssh-ca": {
"get": {
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SSHCAResponse"
}
}
},
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"summary": "The eitri SSH host CA public key (public material) for pinning `@cert-authority` in known_hosts. 404 when the jump gate is off."
}
},
"/api/v1/ssh-certs/revoke": {
"post": {
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RevokeSSHCertRequest"
}
}
},
"required": true
},
"responses": {
"204": {
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "Revoke a minted SSH user certificate by serial or certificate line; the gate rejects it before its TTL expires. Idempotent."
}
},
"/api/v1/ssh-certs/revoked": {
"get": {
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/RevokedCert"
},
"type": "array"
}
}
},
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "List revoked SSH user certificate serials (with reason and time), newest first."
}
},
"/api/v1/stream-tickets": {
"post": {
"responses": {
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/StreamTicketResponse"
}
}
},
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "Mint a one-time short-TTL ticket for the SSE stream or console WebSocket — the only credential that ever rides in a URL."
}
},
"/api/v1/tenants/{tenant}/user-cas": {
"delete": {
"parameters": [
{
"in": "path",
"name": "tenant",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UserCARequest"
}
}
},
"required": true
},
"responses": {
"204": {
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "Remove a registered SSH user CA by its public_key line."
},
"get": {
"parameters": [
{
"in": "path",
"name": "tenant",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/UserCA"
},
"type": "array"
}
}
},
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "List the tenant's registered SSH user CAs (pubkey, label, fingerprint)."
},
"post": {
"parameters": [
{
"in": "path",
"name": "tenant",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UserCARequest"
}
}
},
"required": true
},
"responses": {
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UserCAUploadResponse"
}
}
},
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "Register a BYO SSH user CA public key for the tenant; eitri never holds a user signing key."
}
},
"/api/v1/tokens": {
"get": {
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/APIToken"
},
"type": "array"
}
}
},
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "List the tenant's personal access tokens (metadata only — never the secret), newest first."
},
"post": {
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateAPITokenRequest"
}
}
},
"required": true
},
"responses": {
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateAPITokenResponse"
}
}
},
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "Mint a personal access token; the secret is returned exactly once. An optional TTL sets expiry (0 = non-expiring)."
}
},
"/api/v1/tokens/{id}": {
"delete": {
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"204": {
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "Revoke a personal access token by id; unknown or foreign ids answer 404 (no existence leak)."
}
},
"/api/v1/user-cas": {
"get": {
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/UserCA"
},
"type": "array"
}
}
},
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "List the caller's own tenant's registered SSH user CAs (pubkey, label, fingerprint)."
},
"post": {
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UserCARequest"
}
}
},
"required": true
},
"responses": {
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UserCAUploadResponse"
}
}
},
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "Register a BYO SSH user CA public key for the caller's own tenant; eitri never holds a user signing key."
}
},
"/api/v1/vms": {
"get": {
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/VM"
},
"type": "array"
}
}
},
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "List VMs: durable rows merged with live agent-reported actual state."
},
"post": {
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateVMRequest"
}
}
},
"required": true
},
"responses": {
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateVMResponse"
}
}
},
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "Create a VM on a host. Omitted fields get one-click defaults; the tenant must have a registered SSH user CA first."
}
},
"/api/v1/vms/{id}": {
"delete": {
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"204": {
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "Tombstone a VM for teardown; restorable within the grace window via restore."
},
"patch": {
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PatchVMRequest"
}
}
},
"required": true
},
"responses": {
"204": {
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "Set a VM's desired power state (running or stopped)."
}
},
"/api/v1/vms/{id}/console/ws": {
"get": {
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "one-time stream ticket",
"in": "query",
"name": "ticket",
"required": false,
"schema": {
"type": "string"
}
}
],
"responses": {
"101": {
"description": "switching protocols (WebSocket)"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"summary": "Serial-console WebSocket: raw byte pipe to the VM's serial console."
}
},
"/api/v1/vms/{id}/events": {
"get": {
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "max rows to return (default 100, cap 1000)",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/AuditEvent"
},
"type": "array"
}
}
},
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "One VM's lifecycle timeline (audit rows carrying its vm_id), newest first; survives the VM row being reaped."
}
},
"/api/v1/vms/{id}/exposures": {
"get": {
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/Exposure"
},
"type": "array"
}
}
},
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "List the VM's published ports, with the host address to dial and each listener's reported state."
},
"post": {
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateExposureRequest"
}
}
},
"required": true
},
"responses": {
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Exposure"
}
}
},
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "Publish a guest port on the VM's host, protocol \"tcp\" (the default) or \"udp\". Omit host_port to allocate one from the reserved range 30000-32767; a named port must be \u003e= 1024 and is honored or refused, and is taken only by another exposure of the same protocol."
}
},
"/api/v1/vms/{id}/restore": {
"post": {
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"204": {
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "Un-tombstone a VM still within the teardown grace window; the agent re-adopts the guest."
}
},
"/api/v1/volume-claims": {
"get": {
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/VolumeClaim"
},
"type": "array"
}
}
},
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "List the tenant's claims: where each is bound, which VM holds it, and whether its host has the file."
},
"post": {
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateVolumeClaimRequest"
}
}
},
"required": true
},
"responses": {
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/VolumeClaim"
}
}
},
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "Claim durable storage. Pending until the first VM naming it is created; that VM's host then holds the bytes, and every later VM using the claim is placed there."
}
},
"/api/v1/volume-claims/{id}": {
"delete": {
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"204": {
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "Delete a claim and the data behind it. Refused (409) while a VM holds it."
},
"get": {
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/VolumeClaim"
}
}
},
"description": "success"
},
"default": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "error (plain text)"
}
},
"security": [
{
"patToken": []
}
],
"summary": "One claim."
}
}
}
}