M1: Complete all specification documents (kiro standards)
Completed comprehensive spec-driven documentation: - SPEC.md (222 lines): Project scope, objectives, constraints - ARCHITECTURE.md (290 lines): System design, components, data flow - REQUIREMENTS.md (168 lines): Functional & non-functional requirements - API_SPEC.md (556 lines): 15 API endpoints with schemas - SECURITY.md (188 lines): STRIDE threat model, security controls - ROADMAP.md (203 lines): 5 phases, 8 milestones, risk register Total: 1,627 lines of specification documentation Milestone M1 complete - Ready for Phase 0 (Rust scaffolding)
This commit is contained in:
579
API_SPEC.md
579
API_SPEC.md
@ -1,55 +1,556 @@
|
||||
# Linux_Patch_API - API Specification Document
|
||||
|
||||
## API Overview
|
||||
[Describe API purpose and design philosophy]
|
||||
|
||||
**Purpose:** Secure REST API for remote package and patch management on Linux systems
|
||||
|
||||
**Design Philosophy:**
|
||||
- Pure REST architecture (resources as nouns, HTTP verbs for actions)
|
||||
- mTLS certificate-based authentication (no sessions)
|
||||
- Hybrid execution model (sync for quick ops, async for long ops)
|
||||
- Real-time status via WebSocket streaming
|
||||
- JSON request/response with standard envelope
|
||||
|
||||
**Base Path:** `/api/v1/`
|
||||
**Protocol:** HTTPS (TLS 1.3 only)
|
||||
**Port:** 12443
|
||||
**Trailing Slashes:** Not required
|
||||
|
||||
---
|
||||
|
||||
## Authentication
|
||||
|
||||
### Authentication Method
|
||||
- Type: [TBD - JWT/OAuth2/API Key]
|
||||
- Token Endpoint: [TBD]
|
||||
- Token Expiry: [TBD]
|
||||
- **Type:** mTLS Certificate-Based Authentication
|
||||
- **CA:** Internal self-hosted Certificate Authority
|
||||
- **Certificate Validity:** 1 year maximum
|
||||
- **Client Identity:** Unique certificate per client
|
||||
- **Session Management:** None (stateless)
|
||||
|
||||
### Authorization
|
||||
- **Method:** IP Whitelist Enforcement
|
||||
- **Default:** Deny all (block unless explicitly allowed)
|
||||
- **Permissions:** Binary (whitelisted IP + valid cert = full access)
|
||||
- **No Granular Permissions:** All authenticated clients have full API access
|
||||
|
||||
### Connection Requirements
|
||||
- Valid client certificate signed by internal CA
|
||||
- Client IP must be in whitelist configuration
|
||||
- TLS 1.3 only
|
||||
- Silent drop for non-compliant connections (no response)
|
||||
|
||||
---
|
||||
|
||||
## Standard Response Envelope
|
||||
|
||||
All API responses use this standard structure:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"request_id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"timestamp": "2026-04-09T13:04:02Z",
|
||||
"data": {},
|
||||
"error": null
|
||||
}
|
||||
```
|
||||
|
||||
### Fields:
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `success` | boolean | true for successful requests, false for errors |
|
||||
| `request_id` | UUID | Unique identifier for request tracking/auditing |
|
||||
| `timestamp` | ISO 8601 | Server timestamp of response |
|
||||
| `data` | object | Response payload (null on error) |
|
||||
| `error` | object | Error details (null on success) |
|
||||
|
||||
---
|
||||
|
||||
## Error Response Format
|
||||
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"request_id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"timestamp": "2026-04-09T13:04:02Z",
|
||||
"data": null,
|
||||
"error": {
|
||||
"code": "ERROR_CODE",
|
||||
"message": "Human-readable description",
|
||||
"details": {},
|
||||
"retryable": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Error Codes:
|
||||
| Code | HTTP Status | Description |
|
||||
|------|-------------|-------------|
|
||||
| `AUTH_INVALID_CERT` | 401 | Certificate validation failed |
|
||||
| `AUTH_CERT_EXPIRED` | 401 | Certificate has expired |
|
||||
| `AUTHZ_IP_DENIED` | 403 | IP not in whitelist |
|
||||
| `PKG_NOT_FOUND` | 404 | Package not found |
|
||||
| `PKG_MANAGER_ERROR` | 500 | Package manager operation failed |
|
||||
| `JOB_NOT_FOUND` | 404 | Job ID not found |
|
||||
| `JOB_TIMEOUT` | 408 | Job exceeded 30-minute timeout |
|
||||
| `CONFIG_INVALID` | 400 | Configuration validation failed |
|
||||
| `SERVICE_UNHEALTHY` | 503 | Service not ready |
|
||||
|
||||
---
|
||||
|
||||
## Endpoints
|
||||
|
||||
### PATCH Management Endpoints
|
||||
#### GET /api/v1/patches
|
||||
[Describe endpoint]
|
||||
### Package Management Endpoints
|
||||
|
||||
#### POST /api/v1/patches/apply
|
||||
[Describe endpoint]
|
||||
#### POST /api/v1/packages
|
||||
|
||||
#### GET /api/v1/patches/status/{id}
|
||||
[Describe endpoint]
|
||||
**Description:** Install one or more packages (async operation)
|
||||
|
||||
### Software Management Endpoints
|
||||
#### GET /api/v1/software
|
||||
[Describe endpoint]
|
||||
**Request Body:**
|
||||
```json
|
||||
{
|
||||
"packages": [
|
||||
{
|
||||
"name": "nginx",
|
||||
"version": "1.24.0-1"
|
||||
}
|
||||
],
|
||||
"options": {
|
||||
"force": false,
|
||||
"no_recommends": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### POST /api/v1/software/install
|
||||
[Describe endpoint]
|
||||
|
||||
#### POST /api/v1/software/remove
|
||||
[Describe endpoint]
|
||||
|
||||
### System Endpoints
|
||||
#### GET /api/v1/system/status
|
||||
[Describe endpoint]
|
||||
|
||||
#### GET /api/v1/system/logs
|
||||
[Describe endpoint]
|
||||
|
||||
## Request/Response Formats
|
||||
### Standard Response Structure
|
||||
[Define response schema]
|
||||
|
||||
### Error Response Format
|
||||
[Define error response schema]
|
||||
|
||||
## Rate Limiting
|
||||
[Define rate limits]
|
||||
|
||||
## Versioning Strategy
|
||||
[API versioning approach]
|
||||
**Response (202 Accepted):**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"request_id": "uuid",
|
||||
"timestamp": "2026-04-09T13:04:02Z",
|
||||
"data": {
|
||||
"job_id": "uuid",
|
||||
"status": "pending",
|
||||
"operation": "install",
|
||||
"packages": ["nginx"]
|
||||
},
|
||||
"error": null
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### GET /api/v1/packages
|
||||
|
||||
**Description:** List installed packages with filtering and sorting
|
||||
|
||||
**Query Parameters:**
|
||||
| Parameter | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| `name` | string | Filter by package name (supports wildcard `*`) |
|
||||
| `status` | string | Filter: `installed`, `upgradable`, `available` |
|
||||
| `upgradable` | boolean | `true` to show only upgradable packages |
|
||||
| `sort` | string | Sort field: `name`, `version`, `status` (default: `name`) |
|
||||
| `order` | string | Sort order: `asc`, `desc` (default: `asc`) |
|
||||
|
||||
**Response (200 OK):**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"request_id": "uuid",
|
||||
"timestamp": "2026-04-09T13:04:02Z",
|
||||
"data": {
|
||||
"packages": [
|
||||
{
|
||||
"name": "nginx",
|
||||
"version": "1.24.0-1",
|
||||
"status": "installed",
|
||||
"upgradable": true,
|
||||
"latest_version": "1.25.0-1",
|
||||
"description": "High performance web server",
|
||||
"dependencies": ["libc6", "libssl3"],
|
||||
"reverse_dependencies": ["nginx-core"]
|
||||
}
|
||||
],
|
||||
"total": 1
|
||||
},
|
||||
"error": null
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### GET /api/v1/packages/{name}
|
||||
|
||||
**Description:** Get details of a specific package
|
||||
|
||||
**Response (200 OK):**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"request_id": "uuid",
|
||||
"timestamp": "2026-04-09T13:04:02Z",
|
||||
"data": {
|
||||
"name": "nginx",
|
||||
"version": "1.24.0-1",
|
||||
"status": "installed",
|
||||
"upgradable": true,
|
||||
"latest_version": "1.25.0-1",
|
||||
"description": "High performance web server",
|
||||
"dependencies": ["libc6", "libssl3"],
|
||||
"reverse_dependencies": ["nginx-core"],
|
||||
"install_date": "2026-01-15T10:30:00Z",
|
||||
"size_installed": "2.5 MB"
|
||||
},
|
||||
"error": null
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### PUT /api/v1/packages/{name}
|
||||
|
||||
**Description:** Update a specific package (async operation)
|
||||
|
||||
**Response (202 Accepted):**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"request_id": "uuid",
|
||||
"timestamp": "2026-04-09T13:04:02Z",
|
||||
"data": {
|
||||
"job_id": "uuid",
|
||||
"status": "pending",
|
||||
"operation": "update",
|
||||
"package": "nginx"
|
||||
},
|
||||
"error": null
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### DELETE /api/v1/packages/{name}
|
||||
|
||||
**Description:** Remove a package (async operation)
|
||||
|
||||
**Response (202 Accepted):**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"request_id": "uuid",
|
||||
"timestamp": "2026-04-09T13:04:02Z",
|
||||
"data": {
|
||||
"job_id": "uuid",
|
||||
"status": "pending",
|
||||
"operation": "remove",
|
||||
"package": "nginx"
|
||||
},
|
||||
"error": null
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Patch Management Endpoints
|
||||
|
||||
#### GET /api/v1/patches
|
||||
|
||||
**Description:** List available updates/patches
|
||||
|
||||
**Response (200 OK):**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"request_id": "uuid",
|
||||
"timestamp": "2026-04-09T13:04:02Z",
|
||||
"data": {
|
||||
"patches": [
|
||||
{
|
||||
"name": "linux-kernel",
|
||||
"current_version": "5.15.0-91",
|
||||
"available_version": "5.15.0-92",
|
||||
"severity": "critical",
|
||||
"description": "Security update for kernel vulnerabilities",
|
||||
"cve_ids": ["CVE-2024-1234"],
|
||||
"requires_reboot": true
|
||||
}
|
||||
],
|
||||
"total": 1,
|
||||
"security_updates": 1,
|
||||
"requires_reboot": true
|
||||
},
|
||||
"error": null
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### POST /api/v1/patches/apply
|
||||
|
||||
**Description:** Apply all or specific patches (async operation)
|
||||
|
||||
**Request Body:**
|
||||
```json
|
||||
{
|
||||
"packages": ["linux-kernel", "libc6"], // optional, all if omitted
|
||||
"reboot": true, // optional, auto-reboot after patching
|
||||
"reboot_delay_seconds": 60 // optional, delay before reboot
|
||||
}
|
||||
```
|
||||
|
||||
**Response (202 Accepted):**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"request_id": "uuid",
|
||||
"timestamp": "2026-04-09T13:04:02Z",
|
||||
"data": {
|
||||
"job_id": "uuid",
|
||||
"status": "pending",
|
||||
"operation": "patch_apply",
|
||||
"packages_count": 2,
|
||||
"reboot_scheduled": true
|
||||
},
|
||||
"error": null
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### System Endpoints
|
||||
|
||||
#### GET /api/v1/system/info
|
||||
|
||||
**Description:** Get system information
|
||||
|
||||
**Response (200 OK):**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"request_id": "uuid",
|
||||
"timestamp": "2026-04-09T13:04:02Z",
|
||||
"data": {
|
||||
"hostname": "server01",
|
||||
"os": "Ubuntu",
|
||||
"os_version": "22.04 LTS",
|
||||
"kernel": "5.15.0-91-generic",
|
||||
"architecture": "x86_64",
|
||||
"last_update_check": "2026-04-09T12:00:00Z",
|
||||
"last_update_apply": "2026-04-01T03:00:00Z",
|
||||
"pending_reboot": false
|
||||
},
|
||||
"error": null
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### GET /api/v1/health
|
||||
|
||||
**Description:** Health check endpoint
|
||||
|
||||
**Response (200 OK - Healthy):**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"request_id": "uuid",
|
||||
"timestamp": "2026-04-09T13:04:02Z",
|
||||
"data": {
|
||||
"status": "healthy",
|
||||
"uptime_seconds": 12345,
|
||||
"version": "0.0.1"
|
||||
},
|
||||
"error": null
|
||||
}
|
||||
```
|
||||
|
||||
**Response (503 - Unhealthy):**
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"request_id": "uuid",
|
||||
"timestamp": "2026-04-09T13:04:02Z",
|
||||
"data": null,
|
||||
"error": {
|
||||
"code": "SERVICE_UNHEALTHY",
|
||||
"message": "Service not ready",
|
||||
"details": {},
|
||||
"retryable": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### POST /api/v1/system/reboot
|
||||
|
||||
**Description:** Reboot the system (async operation)
|
||||
|
||||
**Request Body:**
|
||||
```json
|
||||
{
|
||||
"delay_seconds": 0, // optional, immediate if omitted
|
||||
"force": false // optional, skip pending job checks
|
||||
}
|
||||
```
|
||||
|
||||
**Response (202 Accepted):**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"request_id": "uuid",
|
||||
"timestamp": "2026-04-09T13:04:02Z",
|
||||
"data": {
|
||||
"job_id": "uuid",
|
||||
"status": "pending",
|
||||
"operation": "reboot",
|
||||
"scheduled_at": "2026-04-09T13:04:02Z"
|
||||
},
|
||||
"error": null
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Job Management Endpoints
|
||||
|
||||
#### GET /api/v1/jobs
|
||||
|
||||
**Description:** List all jobs with optional filtering
|
||||
|
||||
**Query Parameters:**
|
||||
| Parameter | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| `status` | string | Filter: `pending`, `running`, `completed`, `failed`, `cancelled` |
|
||||
| `limit` | integer | Max results (default: 50, no pagination beyond limit) |
|
||||
|
||||
**Response (200 OK):**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"request_id": "uuid",
|
||||
"timestamp": "2026-04-09T13:04:02Z",
|
||||
"data": {
|
||||
"jobs": [
|
||||
{
|
||||
"job_id": "uuid",
|
||||
"operation": "install",
|
||||
"status": "completed",
|
||||
"created_at": "2026-04-09T13:00:00Z",
|
||||
"completed_at": "2026-04-09T13:02:00Z",
|
||||
"packages": ["nginx"]
|
||||
}
|
||||
],
|
||||
"total": 1
|
||||
},
|
||||
"error": null
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### GET /api/v1/jobs/{id}
|
||||
|
||||
**Description:** Get specific job status
|
||||
|
||||
**Response (200 OK):**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"request_id": "uuid",
|
||||
"timestamp": "2026-04-09T13:04:02Z",
|
||||
"data": {
|
||||
"job_id": "uuid",
|
||||
"operation": "install",
|
||||
"status": "running",
|
||||
"progress": 45,
|
||||
"message": "Downloading package...",
|
||||
"created_at": "2026-04-09T13:00:00Z",
|
||||
"completed_at": null,
|
||||
"packages": ["nginx"],
|
||||
"logs": ["Starting installation...", "Resolving dependencies..."]
|
||||
},
|
||||
"error": null
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### POST /api/v1/jobs/{id}/rollback
|
||||
|
||||
**Description:** Rollback a completed/failed job (async, exclusive mode)
|
||||
|
||||
**Response (202 Accepted):**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"request_id": "uuid",
|
||||
"timestamp": "2026-04-09T13:04:02Z",
|
||||
"data": {
|
||||
"job_id": "uuid-rollback",
|
||||
"status": "pending",
|
||||
"operation": "rollback",
|
||||
"original_job_id": "uuid",
|
||||
"exclusive_mode": true
|
||||
},
|
||||
"error": null
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### WebSocket: /api/v1/ws/jobs
|
||||
|
||||
**Description:** Real-time job status streaming
|
||||
|
||||
**Connection:** Upgrade HTTP connection with mTLS
|
||||
|
||||
**Client → Server (subscribe):**
|
||||
```json
|
||||
{
|
||||
"action": "subscribe",
|
||||
"job_id": "uuid" // optional, omit for all jobs
|
||||
}
|
||||
```
|
||||
|
||||
**Server → Client (status update):**
|
||||
```json
|
||||
{
|
||||
"event": "job_status",
|
||||
"job_id": "uuid",
|
||||
"status": "running",
|
||||
"progress": 45,
|
||||
"message": "Installing package...",
|
||||
"timestamp": "2026-04-09T13:04:02Z"
|
||||
}
|
||||
```
|
||||
|
||||
**Server → Client (job complete):**
|
||||
```json
|
||||
{
|
||||
"event": "job_complete",
|
||||
"job_id": "uuid",
|
||||
"status": "completed",
|
||||
"progress": 100,
|
||||
"message": "Installation complete",
|
||||
"timestamp": "2026-04-09T13:04:02Z"
|
||||
}
|
||||
---
|
||||
|
||||
## Rate Limiting
|
||||
|
||||
**Not Required:** Internal network only with strict IP whitelist
|
||||
|
||||
---
|
||||
|
||||
## Versioning Strategy
|
||||
|
||||
- **Method:** URL Path Versioning (`/api/v1/`)
|
||||
- **Backward Compatibility:** Breaking changes require new major version
|
||||
- **Deprecation:** Old versions supported for 6 months after new version release
|
||||
- **Current Version:** v1
|
||||
|
||||
---
|
||||
|
||||
*Following kiro spec-driven development standards*
|
||||
|
||||
Reference in New Issue
Block a user