Add tests and implement StubBearer authentication for Signer endpoints
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
- Created SignerEndpointsTests to validate the SignDsse and VerifyReferrers endpoints. - Implemented StubBearerAuthenticationDefaults and StubBearerAuthenticationHandler for token-based authentication. - Developed ConcelierExporterClient for managing Trivy DB settings and export operations. - Added TrivyDbSettingsPageComponent for UI interactions with Trivy DB settings, including form handling and export triggering. - Implemented styles and HTML structure for Trivy DB settings page. - Created NotifySmokeCheck tool for validating Redis event streams and Notify deliveries.
This commit is contained in:
@@ -489,6 +489,71 @@ Returns `202 Accepted` and `Location: /attest/{id}` for async verify.
|
||||
|
||||
---
|
||||
|
||||
### 2.8 Runtime – Ingest Observer Events *(SCANNER-RUNTIME-12-301)*
|
||||
|
||||
```
|
||||
POST /api/v1/runtime/events
|
||||
Authorization: Bearer <token with scanner.runtime.ingest>
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
| Requirement | Details |
|
||||
|-------------|---------|
|
||||
| Auth scope | `scanner.runtime.ingest` |
|
||||
| Batch size | ≤ **256** envelopes (`scanner.runtime.maxBatchSize`, configurable) |
|
||||
| Payload cap | ≤ **1 MiB** serialized JSON (`scanner.runtime.maxPayloadBytes`) |
|
||||
| Rate limits | Per-tenant and per-node token buckets (default 200 events/s tenant, 50 events/s node, burst 200) – excess returns **429** with `Retry-After`. |
|
||||
| TTL | Runtime events retained **45 days** by default (`scanner.runtime.eventTtlDays`). |
|
||||
|
||||
**Request body**
|
||||
|
||||
```json
|
||||
{
|
||||
"batchId": "node-a-2025-10-20T15:03:12Z",
|
||||
"events": [
|
||||
{
|
||||
"schemaVersion": "zastava.runtime.event@v1",
|
||||
"event": {
|
||||
"eventId": "evt-2f9c02b8",
|
||||
"when": "2025-10-20T15:03:08Z",
|
||||
"kind": "ContainerStart",
|
||||
"tenant": "tenant-alpha",
|
||||
"node": "cluster-a/node-01",
|
||||
"runtime": { "engine": "containerd", "version": "1.7.19" },
|
||||
"workload": {
|
||||
"platform": "kubernetes",
|
||||
"namespace": "payments",
|
||||
"pod": "api-7c9fbbd8b7-ktd84",
|
||||
"container": "api",
|
||||
"containerId": "containerd://bead5...",
|
||||
"imageRef": "ghcr.io/acme/api@sha256:deadbeef"
|
||||
},
|
||||
"process": { "pid": 12345, "entrypoint": ["/start.sh", "--serve"] },
|
||||
"loadedLibs": [
|
||||
{ "path": "/lib/x86_64-linux-gnu/libssl.so.3", "inode": 123456, "sha256": "abc123..." }
|
||||
],
|
||||
"posture": { "imageSigned": true, "sbomReferrer": "present" },
|
||||
"delta": { "baselineImageDigest": "sha256:deadbeef" },
|
||||
"evidence": [ { "signal": "proc.maps", "value": "libssl.so.3@0x7f..." } ],
|
||||
"annotations": { "observerVersion": "1.0.0" }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Responses**
|
||||
|
||||
| Code | Body | Notes |
|
||||
|------|------|-------|
|
||||
| `202 Accepted` | `{ "accepted": 128, "duplicates": 2 }` | Batch persisted; duplicates are ignored via unique `eventId`. |
|
||||
| `400 Bad Request` | Problem+JSON | Validation failures – empty batch, duplicate IDs, unsupported schema version, payload too large. |
|
||||
| `429 Too Many Requests` | Problem+JSON | Per-tenant/node rate limit exceeded; `Retry-After` header emitted in seconds. |
|
||||
|
||||
Persisted documents capture the canonical envelope (`payload` field), tenant/node metadata, and set an automatic TTL on `expiresAt`. Observers should retry rejected batches with exponential backoff honouring the provided `Retry-After` hint.
|
||||
|
||||
---
|
||||
|
||||
## 3 StellaOps CLI (`stellaops-cli`)
|
||||
|
||||
The new CLI is built on **System.CommandLine 2.0.0‑beta5** and mirrors the Concelier backend REST API.
|
||||
@@ -521,6 +586,9 @@ See `docs/dev/32_AUTH_CLIENT_GUIDE.md` for recommended profiles (online vs. air-
|
||||
| `stellaops-cli auth <login\|logout\|status\|whoami>` | Manage cached tokens for StellaOps Authority | `auth login --force` (ignore cache)<br>`auth status`<br>`auth whoami` | Uses `StellaOps.Auth.Client`; honours `StellaOps:Authority:*` configuration, stores tokens under `~/.stellaops/tokens` by default, and `whoami` prints subject/scope/expiry |
|
||||
| `stellaops-cli auth revoke export` | Export the Authority revocation bundle | `--output <directory>` (defaults to CWD) | Writes `revocation-bundle.json`, `.json.jws`, and `.json.sha256`; verifies the digest locally and includes key metadata in the log summary. |
|
||||
| `stellaops-cli auth revoke verify` | Validate a revocation bundle offline | `--bundle <path>` `--signature <path>` `--key <path>`<br>`--verbose` | Verifies detached JWS signatures, reports the computed SHA-256, and can fall back to cached JWKS when `--key` is omitted. |
|
||||
| `stellaops-cli offline kit pull` | Download the latest offline kit bundle and manifest | `--bundle-id <id>` (optional)<br>`--destination <dir>`<br>`--overwrite`<br>`--no-resume` | Streams the bundle + manifest from the configured mirror/backend, resumes interrupted downloads, verifies SHA-256, and writes signatures plus a `.metadata.json` manifest alongside the artefacts. |
|
||||
| `stellaops-cli offline kit import` | Upload an offline kit bundle to the backend | `<bundle.tgz>` (argument)<br>`--manifest <path>`<br>`--bundle-signature <path>`<br>`--manifest-signature <path>` | Validates digests when metadata is present, then posts multipart payloads to `POST /api/offline-kit/import`; logs the submitted import ID/status for air-gapped rollout tracking. |
|
||||
| `stellaops-cli offline kit status` | Display imported offline kit details | `--json` | Shows bundle id/kind, captured/imported timestamps, digests, and component versions; `--json` emits machine-readable output for scripting. |
|
||||
| `stellaops-cli config show` | Display resolved configuration | — | Masks secret values; helpful for air‑gapped installs |
|
||||
| `stellaops-cli runtime policy test` | Ask Scanner.WebService for runtime verdicts (Webhook parity) | `--image/-i <digest>` (repeatable, comma/space lists supported)<br>`--file/-f <path>`<br>`--namespace/--ns <name>`<br>`--label/-l key=value` (repeatable)<br>`--json` | Posts to `POST /api/v1/scanner/policy/runtime`, deduplicates image digests, and prints TTL/policy revision plus per-image columns for signed state, SBOM referrers, quieted-by metadata, confidence, and Rekor attestation (uuid + verified flag). Accepts newline/whitespace-delimited stdin when piped; `--json` emits the raw response without additional logging. |
|
||||
|
||||
@@ -602,6 +670,8 @@ Authority-backed auth workflow:
|
||||
|
||||
Tokens live in `~/.stellaops/tokens` unless `StellaOps:Authority:TokenCacheDirectory` overrides it. Cached tokens are reused offline until they expire; the CLI surfaces clear errors if refresh fails.
|
||||
|
||||
For offline workflows, configure `StellaOps:Offline:KitsDirectory` (or `STELLAOPS_OFFLINE_KITS_DIR`) to control where bundles, manifests, and metadata are stored, and `StellaOps:Offline:KitMirror` (or `STELLAOPS_OFFLINE_MIRROR_URL`) to override the download base URL when pulling from a mirror.
|
||||
|
||||
**Configuration file template**
|
||||
|
||||
```jsonc
|
||||
@@ -614,6 +684,10 @@ Tokens live in `~/.stellaops/tokens` unless `StellaOps:Authority:TokenCacheDirec
|
||||
"DefaultRunner": "docker",
|
||||
"ScannerSignaturePublicKeyPath": "",
|
||||
"ScannerDownloadAttempts": 3,
|
||||
"Offline": {
|
||||
"KitsDirectory": "offline-kits",
|
||||
"KitMirror": "https://get.stella-ops.org/ouk/"
|
||||
},
|
||||
"Authority": {
|
||||
"Url": "https://authority.example.org",
|
||||
"ClientId": "concelier-cli",
|
||||
|
||||
Reference in New Issue
Block a user