Skip to content

Latest commit

 

History

History
778 lines (568 loc) · 13.4 KB

File metadata and controls

778 lines (568 loc) · 13.4 KB

REST API Reference

ROCI provides a JSON-based REST API for programmatic access to all functionality. All endpoints are mounted under /api/v1/.

Authentication

The API uses session-based authentication. Authenticate through the Web UI to obtain a session cookie, then include it in API requests.

Common Response Formats

Success Response

{
  "success": true,
  "message": "Operation completed"
}

Error Response

{
  "error": {
    "code": "not_found",
    "message": "Agent not found"
  }
}

Error Codes

Code HTTP Status Description
bad_request 400 Invalid request parameters
validation_error 400 Request validation failed
not_found 404 Resource not found
conflict 409 Resource conflict (e.g., duplicate name)
internal_error 500 Internal server error

Health Endpoints

GET /api/v1/health

Get server health status including Docker connectivity and agent count.

Response

{
  "status": "ok",
  "version": "0.1.0",
  "uptime_secs": 3600,
  "agents": 5,
  "docker": true
}
Field Type Description
status string "ok" or "degraded"
version string Server version
uptime_secs number Seconds since server start
agents number Connected agent count
docker boolean Docker daemon reachable

GET /api/v1/health/lite

Lightweight health check (no Docker ping).

Response

{
  "status": "ok",
  "version": "0.1.0"
}

Agent Endpoints

GET /api/v1/agents

List all registered agents.

Response

{
  "agents": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "hostname": "docker-host-1",
      "ip_address": "192.168.1.100",
      "status": "approved",
      "volume_base": "/data",
      "last_seen": "2024-01-15T10:30:00Z",
      "created_at": "2024-01-01T00:00:00Z",
      "connected": true
    }
  ],
  "total": 1
}
Field Type Description
id UUID Agent unique identifier
hostname string Agent's hostname
ip_address string Agent's IP address
status string pending, approved, or rejected
volume_base string Configured volume base path
last_seen string Last heartbeat timestamp (ISO 8601)
created_at string Registration timestamp (ISO 8601)
connected boolean Currently connected via WebSocket

GET /api/v1/agents/pending

List agents awaiting approval.

Response

Same format as GET /api/v1/agents, filtered to pending status.

GET /api/v1/agents/{id}

Get a specific agent by ID.

Parameters

Name Type Location Description
id UUID path Agent ID

Response

Single agent object (same fields as list response).

POST /api/v1/agents/{id}/approve

Approve a pending agent.

Parameters

Name Type Location Description
id UUID path Agent ID

Response

{
  "success": true,
  "message": "Agent approved"
}

Errors

  • 404 - Agent not found
  • 409 - Agent is not pending

POST /api/v1/agents/{id}/reject

Reject a pending agent.

Parameters

Name Type Location Description
id UUID path Agent ID

Request Body (optional)

{
  "reason": "Not authorized"
}

Response

{
  "success": true,
  "message": "Agent rejected"
}

DELETE /api/v1/agents/{id}

Delete an agent from the system.

Parameters

Name Type Location Description
id UUID path Agent ID

Response

{
  "success": true,
  "message": "Agent deleted"
}

Application Endpoints

GET /api/v1/applications

List all applications.

Response

{
  "applications": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "name": "my-app",
      "description": "My application",
      "status": "running",
      "agent_id": "550e8400-e29b-41d4-a716-446655440000",
      "created_at": "2024-01-01T00:00:00Z",
      "updated_at": "2024-01-15T10:30:00Z"
    }
  ],
  "total": 1
}
Field Type Description
id UUID Application unique identifier
name string Unique application name
description string Optional description
status string stopped, deploying, running, failed
agent_id UUID Assigned agent (null if unassigned)
created_at string Creation timestamp (ISO 8601)
updated_at string Last update timestamp (ISO 8601)

GET /api/v1/applications/{id}

Get a specific application by ID.

Parameters

Name Type Location Description
id UUID path Application ID

Response

Single application object.

POST /api/v1/applications

Create a new application.

Request Body

{
  "name": "my-app",
  "description": "My application description",
  "compose_yaml": "version: '3.8'\nservices:\n  web:\n    image: nginx:latest\n    ports:\n      - '80:80'",
  "agent_id": "550e8400-e29b-41d4-a716-446655440000"
}
Field Type Required Description
name string Yes Unique application name
description string No Application description
compose_yaml string Yes Docker Compose YAML content
agent_id UUID No Agent to deploy to (can be assigned later)

Response

Returns the created application (HTTP 201).

Errors

  • 400 - Validation error (empty name or compose YAML)
  • 409 - Application name already exists

PUT /api/v1/applications/{id}

Update an application.

Parameters

Name Type Location Description
id UUID path Application ID

Request Body

{
  "description": "Updated description",
  "compose_yaml": "version: '3.8'\nservices:\n  web:\n    image: nginx:alpine"
}
Field Type Description
description string New description
compose_yaml string New compose YAML

Note: Cannot update compose_yaml while application is running. Stop it first.

Response

Returns the updated application.

POST /api/v1/applications/{id}/deploy

Deploy an application to an agent.

Parameters

Name Type Location Description
id UUID path Application ID

Request Body

{
  "agent_id": "550e8400-e29b-41d4-a716-446655440000",
  "secrets": [
    {
      "name": "DB_PASSWORD",
      "value": "supersecret"
    }
  ]
}
Field Type Required Description
agent_id UUID No Target agent (uses assigned agent if not specified)
secrets array No Environment secrets to inject

Response (HTTP 202 Accepted)

{
  "success": true,
  "message": "Deployment initiated"
}

Errors

  • 400 - No agent specified and application has no assigned agent
  • 400 - Target agent is not connected

POST /api/v1/applications/{id}/stop

Stop a running application.

Parameters

Name Type Location Description
id UUID path Application ID

Response

{
  "success": true,
  "message": "Stop command sent"
}

POST /api/v1/applications/{id}/start

Start a stopped application.

Parameters

Name Type Location Description
id UUID path Application ID

Response

{
  "success": true,
  "message": "Start command sent"
}

DELETE /api/v1/applications/{id}

Delete an application.

Parameters

Name Type Location Description
id UUID path Application ID

Request Body

{
  "confirm_name": "my-app"
}
Field Type Required Description
confirm_name string Yes Must match the application name

Response

{
  "success": true,
  "message": "Application deleted"
}

Policy Endpoints

GET /api/v1/policies

List all policies ordered by priority.

Response

{
  "policies": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440002",
      "name": "Allow internal network",
      "priority": 10,
      "match_type": {
        "type": "cidr",
        "network": "192.168.0.0/16"
      },
      "action": "approve",
      "enabled": true,
      "created_at": "2024-01-01T00:00:00Z"
    }
  ],
  "total": 1
}

GET /api/v1/policies/{id}

Get a specific policy by ID.

Parameters

Name Type Location Description
id UUID path Policy ID

Response

Single policy object.

POST /api/v1/policies

Create a new policy.

Request Body

{
  "name": "Allow internal network",
  "priority": 10,
  "match_type": {
    "type": "cidr",
    "network": "192.168.0.0/16"
  },
  "action": "approve",
  "enabled": true
}
Field Type Required Default Description
name string Yes Policy name
priority integer Yes Evaluation priority (lower = first)
match_type object Yes Match condition (see below)
action string Yes approve, reject, or pending
enabled boolean No true Whether policy is active

Match Type Objects

CIDR:

{"type": "cidr", "network": "192.168.0.0/16"}

Reverse DNS:

{"type": "reverse_dns", "pattern": "*.internal.corp.com"}

TOTP:

{"type": "totp"}

Time Window:

{"type": "time_window", "seconds": 86400}

Any (catch-all):

{"type": "any"}

Response

Returns the created policy (HTTP 201).

PUT /api/v1/policies/{id}/priority

Update a policy's priority.

Parameters

Name Type Location Description
id UUID path Policy ID

Request Body

{
  "priority": 5
}

Response

{
  "success": true,
  "message": "Priority updated"
}

POST /api/v1/policies/{id}/enable

Enable a policy.

Parameters

Name Type Location Description
id UUID path Policy ID

Response

{
  "success": true,
  "message": "Policy enabled"
}

POST /api/v1/policies/{id}/disable

Disable a policy.

Parameters

Name Type Location Description
id UUID path Policy ID

Response

{
  "success": true,
  "message": "Policy disabled"
}

DELETE /api/v1/policies/{id}

Delete a policy.

Parameters

Name Type Location Description
id UUID path Policy ID

Response

{
  "success": true,
  "message": "Policy deleted"
}

POST /api/v1/policies/reload

Reload policies from database into the evaluator.

Response

{
  "success": true,
  "message": "Policies reloaded"
}

WebSocket API

Agents connect to the server via WebSocket at /ws/agent.

Agent → Server Messages

Registration

{
  "type": "register",
  "hostname": "docker-host-1",
  "ip_address": "192.168.1.100",
  "volume_base": "/data",
  "totp": "123456"
}

Heartbeat

{
  "type": "heartbeat",
  "containers": [
    {
      "id": "abc123",
      "name": "my-app_web_1",
      "image": "nginx:latest",
      "status": "running"
    }
  ]
}

Command Result

{
  "type": "result",
  "command_id": "550e8400-e29b-41d4-a716-446655440003",
  "success": true,
  "output": "Container started"
}

Server → Agent Messages

Registration Response

{
  "type": "registration_response",
  "status": "approved",
  "agent_id": "550e8400-e29b-41d4-a716-446655440000"
}

Deploy Command

{
  "type": "deploy",
  "app_id": "my-app",
  "compose_yml": "version: '3.8'\nservices: ...",
  "secrets": [
    {"name": "DB_PASSWORD", "value": "secret"}
  ]
}

Stop Command

{
  "type": "stop",
  "app_id": "my-app"
}

Start Command

{
  "type": "start",
  "app_id": "my-app"
}

Delete Command

{
  "type": "delete",
  "app_id": "my-app"
}

Examples

List All Agents (curl)

curl -s http://localhost:8080/api/v1/agents | jq

Create an Application (curl)

curl -X POST http://localhost:8080/api/v1/applications \
  -H "Content-Type: application/json" \
  -d '{
    "name": "nginx-demo",
    "description": "Demo nginx application",
    "compose_yaml": "version: '\''3.8'\''\nservices:\n  web:\n    image: nginx:alpine\n    ports:\n      - '\''8081:80'\''"
  }'

Deploy an Application (curl)

curl -X POST http://localhost:8080/api/v1/applications/{id}/deploy \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "550e8400-e29b-41d4-a716-446655440000"
  }'

Create a Policy (curl)

curl -X POST http://localhost:8080/api/v1/policies \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Allow local network",
    "priority": 10,
    "match_type": {"type": "cidr", "network": "192.168.0.0/16"},
    "action": "approve"
  }'