330 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Markdown
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			330 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Markdown
		
	
	
		
			Executable File
		
	
	
	
	
| # API & CLI Reference
 | ||
| 
 | ||
| *Purpose* – give operators and integrators a single, authoritative spec for REST/GRPC calls **and** first‑party CLI tools (`stella-cli`, `zastava`, `stella`).  
 | ||
| Everything here is *source‑of‑truth* 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; sub‑5 s target                                          |
 | ||
| | Delta check        | `POST /layers/missing`                      | <20 ms reply; powers *delta SBOM* feature                                      |
 | ||
| | Rate‑limit / quota | —                                           | Headers **`X‑Stella‑Quota‑Remaining`**, **`X‑Stella‑Reset`** 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)          | Client‑credentials preferred                                                   |
 | ||
| | Health             | `GET /healthz`                              | Simple liveness probe                                                          |
 | ||
| | Attestation *      | `POST /attest` (TODO Q1‑2026)               | SLSA provenance + Rekor log                                                    |
 | ||
| | CLI flags          | `--sbom-type` `--delta` `--policy-file`     | Added to `stella`                                                             |
 | ||
| 
 | ||
| \* Marked **TODO** → delivered after sixth month (kept on Feature Matrix “To Do” list).
 | ||
| 
 | ||
| ---
 | ||
| 
 | ||
| ## 1 Authentication
 | ||
| 
 | ||
| Stella Ops uses **OAuth 2.0 / OIDC** (token endpoint mounted via OpenIddict).
 | ||
| 
 | ||
| ```
 | ||
| POST /connect/token
 | ||
| Content‑Type: application/x-www-form-urlencoded
 | ||
| 
 | ||
| grant_type=client_credentials&
 | ||
| client_id=ci‑bot&
 | ||
| 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.0 Obtain / Refresh Offline‑Token
 | ||
| 
 | ||
| ```text
 | ||
| POST /token/offline
 | ||
| Authorization: Bearer <admin‑token>
 | ||
| ```
 | ||
| 
 | ||
| | Body field | Required | Example | Notes |
 | ||
| |------------|----------|---------|-------|
 | ||
| | `expiresDays` | no | `30` | Max 90 days |
 | ||
| 
 | ||
| ```json
 | ||
| {
 | ||
|   "jwt": "eyJhbGciOiJSUzI1NiIsInR5cCI6...",
 | ||
|   "expires": "2025‑08‑17T00:00:00Z"
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| Token is signed with the backend’s private key and already contains
 | ||
| `"maxScansPerDay": {{ quota_token }}`.
 | ||
| 
 | ||
| 
 | ||
| ### 2.1 Scan – Upload SBOM **or** Image
 | ||
| 
 | ||
| ```
 | ||
| POST /scan
 | ||
| ```
 | ||
| 
 | ||
| | Param / Header       | In     | Required | Description                                                           |
 | ||
| | -------------------- | ------ | -------- | --------------------------------------------------------------------- |
 | ||
| | `X‑Stella‑Sbom‑Type` | header | no       | `trivy-json-v2`, `spdx-json`, `cyclonedx-json`; omitted ➞ auto‑detect |
 | ||
| | `?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 |
 | ||
| |--------|---------|
 | ||
| | `X‑Stella‑Quota‑Remaining` | `129` |
 | ||
| | `X‑Stella‑Reset` | `2025‑07‑18T23:59:59Z` |
 | ||
| | `X‑Stella‑Token‑Expires` | `2025‑08‑17T00: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
 | ||
| Content‑Type: application/json
 | ||
| Authorization: Bearer <token>
 | ||
| ```
 | ||
| 
 | ||
| ```json
 | ||
| {
 | ||
|   "layers": [
 | ||
|     "sha256:d38b...",
 | ||
|     "sha256:af45..."
 | ||
|   ]
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| **Response 200** — <20 ms target:
 | ||
| 
 | ||
| ```json
 | ||
| {
 | ||
|   "missing": [
 | ||
|     "sha256:af45..."
 | ||
|   ]
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| Client then generates SBOM **only** for the `missing` layers and re‑posts `/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 – Q1‑2026)
 | ||
| 
 | ||
| ```
 | ||
| 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 First‑Party CLI Tools
 | ||
| 
 | ||
| ### 3.1 `stella`
 | ||
| 
 | ||
| > *Package SBOM + Scan + Exit code* – designed for CI.
 | ||
| 
 | ||
| ```
 | ||
| Usage: stella [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 `Retry‑After` 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 `stella‑zastava`
 | ||
| 
 | ||
| > *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 problem‑details object (RFC 7807):
 | ||
| 
 | ||
| ```json
 | ||
| {
 | ||
|   "type": "https://stella-ops.org/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 *pre‑built* SBOM and add `?sbom-only=true` to `/scan` for <1 s path.  
 | ||
| * **Air‑gapped?** – point `--server` to `http://oukgw:8080` inside the Offline Update Kit.  
 | ||
| * **YAML vs Rego** – YAML simpler; Rego unlocks time‑based logic (see samples).  
 | ||
| * **Cosign verify plug‑ins** – enable `SCANNER_VERIFY_SIG=true` env to refuse unsigned plug‑ins.
 | ||
| 
 | ||
| ---
 | ||
| 
 | ||
| ## 7 Planned Changes (Beyond 6 Months)
 | ||
| 
 | ||
| These stay in *Feature Matrix → To Do* until design is frozen.
 | ||
| 
 | ||
| | Epic / Feature               | API Impact Sketch                  |
 | ||
| | ---------------------------- | ---------------------------------- |
 | ||
| | **SLSA L1‑L3** attestation   | `/attest` (see §2.4)               |
 | ||
| | Rekor transparency log       | `/rekor/log/{id}` (GET)            |
 | ||
| | Plug‑in 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)
 | ||
| 
 | ||
| * **2025‑07‑14** – added *delta SBOM*, policy import/export, CLI `--sbom-type`.  
 | ||
| * **2025‑07‑12** – initial public reference.
 | ||
| 
 | ||
| ---
 |