PLATFORM SYSTEMS
API Design
1. API 原则
- 所有 API 使用
/api/v1前缀。 - Console API 和 Edge Runtime API 分离。
- 所有响应包含 request_id。
- 业务错误使用统一结构。
- mutating API 支持 Idempotency-Key。
- Edge Runtime API 使用 device identity request signing。
- Subscription public API 不暴露后台结构。
- Console API 使用
X-OrbitMesh-Tenant传递租户上下文。 - OpenAPI 使用 proto 原始字段名生成,字段、查询参数和路径参数统一使用
snake_case。 docs/api/openapi.yaml和 proto 文件将在模型迁移阶段重新生成。
OpenAPI 生成约束:
plugins:
- plugin: openapi
opt:
- naming=proto
- enum_type=string
Console TypeScript SDK 从 services/control-plane/api/openapi.yaml 生成到对应应用的 app/generated/client/。
Tenant Console:
pnpm --filter @orbitmesh/console generate:openapi
Platform Console:
pnpm --filter @orbitmesh/platform generate:openapi
Plan API ownership:
GET /api/v1/plans
GET /api/v1/tenants/{tenant_id}/plan
GET /api/v1/platform/plans
PUT /api/v1/platform/tenants/{tenant_id}/plan-subscription
PlanService owns tenant/client-facing reads. PlatformService owns platform
operator plan lifecycle actions. Shared messages are defined in
orbitmesh/v1/plan.proto.
2. 错误格式
{
"request_id": "req_123",
"error": {
"code": "NODE_NOT_FOUND",
"message": "node not found"
}
}
3. Auth API
POST /api/v1/auth/login
POST /api/v1/auth/refresh
GET /api/v1/auth/sessions
POST /api/v1/auth/sessions/{id}/revoke
POST /api/v1/auth/logout
GET /api/v1/me
Auth API follows the OIDC token response shape for Console and API clients. Current implementation supports password login, refresh-token exchange, server-side auth sessions, logout, and per-session revocation. It is intentionally not a full OIDC Provider yet; authorization-code endpoints, discovery, and JWKS are future enterprise identity work.
Login request:
{
"email": "user@example.com",
"password": "secret",
"client_type": "console_web",
"device_name": "Chrome macOS"
}
client_type identifies the connecting client family. Current values are open strings normalized by the control plane; recommended values are:
console_webclidesktopmobileedge_runtime
Login and refresh responses:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 86400,
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"id_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"scope": "openid profile email",
"user": {
"id": "user_id",
"email": "user@example.com"
}
}
Refresh request:
{
"refresh_token": "refresh-token"
}
Auth session list:
GET /api/v1/auth/sessions
Authorization: Bearer <access_token>
This endpoint is account-scoped. It returns sessions owned by the authenticated user, not all sessions in the current tenant. Tenant-level session limits are policy inputs for login and refresh enforcement and should be exposed separately from personal session management.
Response:
{
"sessions": [
{
"id": "session_id",
"user_id": "user_id",
"client_type": "console_web",
"device_name": "Chrome macOS",
"user_agent": "Mozilla/5.0 ...",
"ip_address": "203.0.113.10",
"status": "active",
"current": true,
"last_seen_at": "2026-07-08T08:30:00Z",
"expires_at": "2026-08-07T08:30:00Z",
"created_at": "2026-07-08T08:30:00Z",
"updated_at": "2026-07-08T08:30:00Z"
}
]
}
Revoke a non-current session:
POST /api/v1/auth/sessions/{id}/revoke
Authorization: Bearer <access_token>
Content-Type: application/json
{
"id": "session_id"
}
Logout revokes the current access-token session and then the client should delete local credentials:
POST /api/v1/auth/logout
Authorization: Bearer <access_token>
Content-Type: application/json
{
"refresh_token": "refresh-token"
}
API requests use the access token:
Authorization: Bearer <access_token>
Token configuration:
ORBITMESH_AUTH_ISSUERORBITMESH_AUTH_AUDIENCEORBITMESH_ACCESS_TOKEN_TTLORBITMESH_ID_TOKEN_TTLORBITMESH_REFRESH_TOKEN_TTL
4. Enrollment API
POST /api/v1/deployment-tokens
请求:
{
"name": "tencent-hk",
"node_source_type": "byoh",
"initial_capability_roles": ["traffic.entry", "traffic.exit"]
}
响应:
{
"id": "token_id",
"expires_at": "2026-06-16T10:30:00Z",
"install_command": "curl -fsSL https://install.orbitmesh.dev | sudo env ORBITMESH_DEPLOYMENT_TOKEN='om_dt_xxx' sh"
}
5. Node API
GET /api/v1/nodes
GET /api/v1/nodes/{id}
DELETE /api/v1/nodes/{id}
Node response:
{
"id": "node_id",
"name": "tencent-hk",
"status": "online",
"provider": "tencent",
"region": "hk",
"source_type": "byoh",
"last_seen_at": "2026-06-16T10:00:00Z"
}
6. Capability Binding API
GET /api/v1/nodes/{node_id}/capability-bindings
POST /api/v1/nodes/{node_id}/capability-bindings
PUT /api/v1/nodes/{node_id}/capability-bindings/{id}
Example:
{
"capability": "traffic",
"role": "traffic.entry",
"values": {}
}
7. Runtime Binding API
GET /api/v1/nodes/{node_id}/runtime-bindings
POST /api/v1/nodes/{node_id}/runtime-bindings
PUT /api/v1/nodes/{node_id}/runtime-bindings/{id}
Example:
{
"capability_binding_id": "cb_xxx",
"runtime": "sing-box",
"values": {
"listen_port": 443
}
}
8. Edge Runtime API
POST /api/v1/edge-runtime/register
请求:
{
"deployment_token": "token",
"installation_id": "installation_id",
"public_key": "base64url-ed25519-public-key",
"device_fingerprint_hash": "sha256-hex",
"hostname": "vps-hostname",
"reported_address": "1.2.3.4",
"os": "ubuntu",
"arch": "amd64",
"edge_runtime_version": "0.1.0"
}
响应:
{
"node_id": "node_id",
"edge_runtime_id": "edge_runtime_id",
"control_plane_url": "https://api.orbitmesh.dev"
}
POST /api/v1/edge-runtime/heartbeat
Headers:
X-OrbitMesh-Node-Id
X-OrbitMesh-Edge-Runtime-Id
X-OrbitMesh-Installation-Id
X-OrbitMesh-Timestamp
X-OrbitMesh-Nonce
X-OrbitMesh-Body-SHA256
X-OrbitMesh-Signature
请求:
{
"node_id": "node_id",
"runtime_statuses": [
{
"runtime_binding_id": "rb_xxx",
"runtime": "sing-box",
"status": "running",
"runtime_version": "1.x"
}
],
"capability_statuses": [
{
"capability_binding_id": "cb_xxx",
"capability": "traffic",
"role": "traffic.entry",
"status": "ready"
}
]
}
GET /api/v1/edge-runtime/desired-state
响应:
{
"desired_state": {
"node_id": "node_id",
"version": 3,
"checksum": "sha256:xxx",
"spec": {}
},
"runtime_configurations": [
{
"runtime_binding_id": "rb_xxx",
"runtime": "sing-box",
"version": 3,
"checksum": "sha256:yyy",
"manifest": {}
}
]
}
9. Subscription API
GET /api/v1/subscriptions
POST /api/v1/subscriptions
POST /api/v1/subscriptions/ensure-client-access
POST /api/v1/subscriptions/{id}/rotate
POST /api/v1/subscriptions/{id}/revoke
DELETE /api/v1/subscriptions/{id}
GET /subscription/{token}
GET /subscription/{token}/sing-box
GET /subscription/{token}/clash
GET /subscription/{token}/surge
10. Traffic Policy API
GET /api/v1/traffic-policies
POST /api/v1/traffic-policies
PUT /api/v1/traffic-policies/{id}
POST /api/v1/traffic-policies/{id}/simulate
POST /api/v1/traffic-policies/preview
DELETE /api/v1/traffic-policies/{id}
11. Health API
Console 使用正式的 OpenAPI 合约接口获取控制平面版本与构建信息:
GET /api/v1/control-plane/health
响应:
{
"status": "ok",
"service": "orbitmesh-api",
"version": "v0.1.0",
"commit": "abcdef",
"build_time": "2026-06-30T00:00:00Z"
}
/healthz 和 /readyz 只作为部署探针使用,不作为 Console API 使用。
12. API 验收
- 所有错误使用统一格式。
- enrollment token 重复使用策略符合配置。
- Edge Runtime heartbeat 未签名返回 401。
- tenant 越权访问返回 403。
- subscription token 吊销后返回 404 或 403。