Add initial documentation

This commit is contained in:
2025-07-20 21:38:21 +03:00
parent 8ba0a0ba6d
commit 42d9d2d860
24 changed files with 4447 additions and 0 deletions

View File

@ -0,0 +1,329 @@
# API & CLI Reference
*Purpose* give operators and integrators a single, authoritative spec for REST/GRPC calls **and** firstparty CLI tools (`santech`, `zastava`, `stellopsctl`).
Everything here is *sourceoftruth* for generated Swagger/OpenAPI and the `--help` screens in the CLIs.
---
## 0 Quick Glance
| Area | Call / Flag | Notes |
| ------------------ | ------------------------------------------- | ------------------------------------------------------------------------------ |
| Scan entry | `POST /scan` | Accepts SBOM or image; sub5s target |
| Delta check | `POST /layers/missing` | <20ms reply; powers *delta SBOM* feature |
| Ratelimit / quota | | Headers **`XStellaQuotaRemaining`**, **`XStellaReset`** on every response |
| Policy I/O | `GET /policy/export`, `POST /policy/import` | YAML now; Rego coming |
| Policy lint | `POST /policy/validate` | Returns 200 OK if ruleset passes |
| Auth | `POST /connect/token` (OpenIddict) | Clientcredentials preferred |
| Health | `GET /healthz` | Simple liveness probe |
| Attestation * | `POST /attest` (TODO Q12026) | SLSA provenance + Rekor log |
| CLI flags | `--sbom-type` `--delta` `--policy-file` | Added to `santech` |
\* Marked **TODO** delivered after sixth month (kept on Feature Matrix To Do list).
---
## 1 Authentication
StellaOps uses **OAuth 2.0 / OIDC** (token endpoint mounted via OpenIddict).
```
POST /connect/token
ContentType: application/x-www-form-urlencoded
grant_type=client_credentials&
client_id=cibot&
client_secret=REDACTED&
scope=stella.api
```
Successful response:
```json
{
"access_token": "eyJraWQi...",
"token_type": "Bearer",
"expires_in": 3600
}
```
> **Tip**  pass the token via `Authorization: Bearer <token>` on every call.
---
## 2 REST API
###2.0Obtain / Refresh OfflineToken
```text
POST /token/offline
Authorization: Bearer <admintoken>
```
| Body field | Required | Example | Notes |
|------------|----------|---------|-------|
| `expiresDays` | no | `30` | Max 90 days |
```json
{
"jwt": "eyJhbGciOiJSUzI1NiIsInR5cCI6...",
"expires": "20250817T00:00:00Z"
}
```
Token is signed with the backends private key and already contains
`"maxScansPerDay": 333`.
### 2.1 Scan  Upload SBOM **or** Image
```
POST /scan
```
| Param / Header | In | Required | Description |
| -------------------- | ------ | -------- | --------------------------------------------------------------------- |
| `XStellaSbomType` | header | no | `trivy-json-v2`, `spdx-json`, `cyclonedx-json`; omitted autodetect |
| `?threshold` | query | no | `low`, `medium`, `high`, `critical`; default **critical** |
| body | body | yes | *Either* SBOM JSON *or* Docker image tarball/upload URL |
Every successful `/scan` response now includes:
| Header | Example |
|--------|---------|
| `XStellaQuotaRemaining` | `129` |
| `XStellaReset` | `20250718T23:59:59Z` |
| `XStellaTokenExpires` | `20250817T00:00:00Z` |
**Response 200** (scan completed):
```json
{
"digest": "sha256:…",
"summary": {
"Critical": 0,
"High": 3,
"Medium": 12,
"Low": 41
},
"policyStatus": "pass",
"quota": {
"remaining": 131,
"reset": "2025-07-18T00:00:00Z"
}
}
```
**Response 202** queued; polling URL in `Location` header.
---
### 2.2 Delta SBOM Layer Cache Check
```
POST /layers/missing
ContentType: application/json
Authorization: Bearer <token>
```
```json
{
"layers": [
"sha256:d38b...",
"sha256:af45..."
]
}
```
**Response 200**<20ms target:
```json
{
"missing": [
"sha256:af45..."
]
}
```
Client then generates SBOM **only** for the `missing` layers and reposts `/scan`.
---
### 2.3 Policy Endpoints
| Method | Path | Purpose |
| ------ | ------------------ | ------------------------------------ |
| `GET` | `/policy/export` | Download live YAML ruleset |
| `POST` | `/policy/import` | Upload YAML or Rego; replaces active |
| `POST` | `/policy/validate` | Lint only; returns 400 on error |
| `GET` | `/policy/history` | Paginated change log (audit trail) |
```yaml
# Example import payload (YAML)
version: "1.0"
rules:
- name: Ignore Low dev
severity: [Low, None]
environments: [dev, staging]
action: ignore
```
Validation errors come back as:
```json
{
"errors": [
{
"path": "$.rules[0].severity",
"msg": "Invalid level 'None'"
}
]
}
```
---
### 2.4 Attestation (Planned  Q12026)
```
POST /attest
```
| Param | Purpose |
| ----------- | ------------------------------------- |
| body (JSON) | SLSA v1.0 provenance doc |
| | Signed + stored in local Rekor mirror |
Returns `202 Accepted` and `Location: /attest/{id}` for async verify.
---
### 2.5 Misc Endpoints
| Path | Method | Description |
| ---------- | ------ | ---------------------------- |
| `/healthz` | GET | Liveness; returns `"ok"` |
| `/metrics` | GET | Prometheus exposition (OTel) |
| `/version` | GET | Git SHA + build date |
---
## 3 FirstParty CLI Tools
### 3.1 `stellasantech`
> *Package SBOM + Scan + Exit code* designed for CI.
```
Usage: santech [OPTIONS] IMAGE_OR_SBOM
```
| Flag / Option | Default | Description |
| --------------- | ----------------------- | -------------------------------------------------- |
| `--server` | `http://localhost:8080` | API root |
| `--token` | *env `STELLA_TOKEN`* | Bearer token |
| `--sbom-type` | *auto* | Force `trivy-json-v2`/`spdx-json`/`cyclonedx-json` |
| `--delta` | `false` | Enable delta layer optimisation |
| `--policy-file` | *none* | Override server rules with local YAML/Rego |
| `--threshold` | `critical` | Fail build if level found |
| `--output-json` | *none* | Write raw scan result to file |
| `--wait-quota` | `true` | If 429 received, automatically wait `RetryAfter` and retry once. |
**Exit codes**
| Code | Meaning |
| ---- | ------------------------------------------- |
| 0 | Scan OK, policy passed |
| 1 | Vulnerabilities threshold OR policy block |
| 2 | Internal error (network etc.) |
---
### 3.2 `stellazastava`
> *Daemon / K8s DaemonSet* watch container runtime, push SBOMs.
Core flags (excerpt):
| Flag | Purpose |
| ---------------- | ---------------------------------- |
| `--mode` | `listen` (default) / `enforce` |
| `--filter-image` | Regex; ignore infra/busybox images |
| `--threads` | Worker pool size |
---
### 3.3 `stellopsctl`
> *Admin utility* policy snapshots, feed status, user CRUD.
Examples:
```
stellopsctl policy export > policies/backup-2025-07-14.yaml
stellopsctl feed refresh # force OSV merge
stellopsctl user add dev-team --role developer
```
---
## 4 Error Model
Uniform problemdetails object (RFC 7807):
```json
{
"type": "https://stella-ops.ru/probs/validation",
"title": "Invalid request",
"status": 400,
"detail": "Layer digest malformed",
"traceId": "00-7c39..."
}
```
---
## 5 Rate Limits
Default **40 requests / second / token**.
429 responses include `Retry-After` seconds header.
---
## 6 FAQ & Tips
* **Skip SBOM generation in CI** supply a *prebuilt* SBOM and add `?sbom-only=true` to `/scan` for <1s path.
* **Airgapped?** point `--server` to `http://oukgw:8080` inside the Offline Update Kit.
* **YAML vs Rego** YAML simpler; Rego unlocks timebased logic (see samples).
* **Cosign verify plugins** enable `SCANNER_VERIFY_SIG=true` env to refuse unsigned plugins.
---
## 7 Planned Changes (Beyond 6 Months)
These stay in *Feature Matrix → To Do* until design is frozen.
| Epic / Feature | API Impact Sketch |
| ---------------------------- | ---------------------------------- |
| **SLSA L1L3** attestation | `/attest` (see §2.4) |
| Rekor transparency log | `/rekor/log/{id}` (GET) |
| Plugin Marketplace metadata | `/plugins/market` (catalog) |
| Horizontal scaling controls | `POST /cluster/node` (add/remove) |
| Windows agent support | Update LSAPI to PDE, no API change |
---
## 8 References
* OpenAPI YAML `/openapi/v1.yaml` (served by backend)
* OAuth2 spec: <https://datatracker.ietf.org/doc/html/rfc6749>
* SLSA spec: <https://slsa.dev/spec/v1.0>
---
## 9 Changelog (truncated)
* **20250714** added *delta SBOM*, policy import/export, CLI `--sbom-type`.
* **20250712** initial public reference.
---