- added /update/enroll endpoint and enrollment logic - migrated update client to v1 api endpoints and bearer auth - implemented remote status reporting in backend and scripts - updated requirements and project status
136 lines
3.2 KiB
Markdown
136 lines
3.2 KiB
Markdown
ID: DOC_000005 | Version: 0.1.0 | Status: Draft
|
|
|
|
# Third-Party API Guide
|
|
|
|
## Purpose
|
|
This document explains how third-party services integrate with the Update Webservice: obtaining tokens, fetching manifests, downloading artifacts, and reporting status.
|
|
|
|
## Quick Start (First Client)
|
|
1) Request a pre-shared enrollment token from an admin/operator.
|
|
2) Enroll once to obtain a long-term token.
|
|
3) Store the long-term token locally and use it for all API calls.
|
|
|
|
## Base URLs
|
|
- Production: `https://update.wlkns.org`
|
|
- Staging: `https://staging.update.wlkns.org`
|
|
|
|
All endpoints are versioned under `/v1`.
|
|
|
|
## Authentication
|
|
All endpoints require `Authorization: Bearer <token>`.
|
|
|
|
### Enrollment (Pre-Shared Token -> Long-Term Token)
|
|
Clients obtain a long-term token by exchanging a pre-shared token provided by an admin/operator.
|
|
|
|
Request (example):
|
|
```
|
|
POST /v1/enroll
|
|
{
|
|
"project_id": "<project>",
|
|
"client_id": "<client>",
|
|
"software_id": "<software>",
|
|
"enroll_token": "<pre_shared_token>"
|
|
}
|
|
```
|
|
|
|
Response (example):
|
|
```
|
|
200 OK
|
|
{
|
|
"token": "<long_term_token>",
|
|
"scope": "read_manifest report_status",
|
|
"expires_at": "<iso8601 or null>"
|
|
}
|
|
```
|
|
|
|
Notes:
|
|
- Enrollment tokens are single-use and must be invalidated after a successful exchange.
|
|
- If the token is invalid or reused, the server responds with `unauthorized` or `invalid_payload`.
|
|
- Enrollment does not require an existing bearer token.
|
|
- If the client is already enrolled, the server responds with `already_enrolled` (HTTP 409).
|
|
|
|
## Client API (Read + Report)
|
|
|
|
### Get Manifest
|
|
```
|
|
GET /v1/projects/{project_id}/manifest
|
|
```
|
|
|
|
Response:
|
|
```
|
|
{
|
|
"version": "0.1.2",
|
|
"artifact_url": "https://update.wlkns.org/v1/projects/<project_id>/releases/0.1.2/artifact",
|
|
"sha256": "<hex>",
|
|
"sig_url": "<optional>"
|
|
}
|
|
```
|
|
|
|
Required scope: `read_manifest`
|
|
|
|
### Download Artifact
|
|
```
|
|
GET /v1/projects/{project_id}/releases/{version}/artifact
|
|
```
|
|
|
|
Required scope: `read_manifest`
|
|
|
|
### Report Status
|
|
```
|
|
POST /v1/projects/{project_id}/status
|
|
{
|
|
"project_id": "<project_id>",
|
|
"version": "<semver>",
|
|
"status": "success|failed|in_progress",
|
|
"timestamp": "<iso8601>",
|
|
"client_id": "<optional>",
|
|
"duration_ms": "<optional>",
|
|
"error_code": "<optional>"
|
|
}
|
|
```
|
|
|
|
Required scope: `report_status`
|
|
|
|
## Release API (Upload)
|
|
|
|
### Upload Release
|
|
```
|
|
POST /v1/projects/{project_id}/releases
|
|
Content-Type: multipart/form-data
|
|
```
|
|
|
|
Required scope: `upload_release`
|
|
|
|
Required fields:
|
|
- `version` (SemVer)
|
|
- `artifact` (file)
|
|
- `sha256` (hex)
|
|
|
|
Optional fields:
|
|
- `sig_url` or inline signature
|
|
- `key_id`
|
|
|
|
## Error Codes
|
|
Common error codes:
|
|
`unauthorized`, `rate_limited`, `not_found`, `invalid_payload`, `version_invalid`,
|
|
`version_exists`, `checksum_mismatch`, `signature_missing`, `signature_invalid`,
|
|
`payload_too_large`, `status_invalid`
|
|
|
|
## Rate Limits
|
|
Limits are tiered by scope. See `docs/architecture/ARCHITECTURE.md` for current values.
|
|
|
|
## Examples
|
|
Fetch manifest:
|
|
```
|
|
curl -H "Authorization: Bearer $TOKEN" \
|
|
https://update.wlkns.org/v1/projects/$PROJECT_ID/manifest
|
|
```
|
|
|
|
Report status:
|
|
```
|
|
curl -H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"project_id":"'"$PROJECT_ID"'","version":"0.1.2","status":"success","timestamp":"2025-12-30T10:00:00Z"}' \
|
|
https://update.wlkns.org/v1/projects/$PROJECT_ID/status
|
|
```
|