chore: update configuration and Docker setup for JWT and test results
ci/woodpecker/push/build-arm Pipeline was successful

Enhanced the .gitignore to exclude test results and updated the Dockerfile to include a new entrypoint script for improved container initialization. Refactored JWT configuration to support additional parameters for automatic refresh intervals, ensuring better control over token management. Updated the ConfigurationResolver to enforce required environment variables without hardcoded fallbacks, enhancing security and flexibility.
This commit is contained in:
Oleksandr Bezdieniezhnykh
2026-05-15 03:23:23 +03:00
parent 7025f4d075
commit 78dea8ebab
40 changed files with 1990 additions and 510 deletions
+5 -5
View File
@@ -10,7 +10,7 @@
`missions` is the **edge-tier .NET 10 REST service** that owns the **mission domain** of an Azaion deployment: it is the local source of truth for the operator's vehicle inventory, mission plans, and ordered waypoints, and it is the orchestrator of the cross-service cascade-delete that keeps the rest of the device's edge stack consistent when missions or waypoints are removed.
It is one of ~6 backend services running side-by-side **on each customer device** (Jetson Orin / OrangePI / operator-PC). All edge services share **one local PostgreSQL** on the device; each migrates only the tables it owns. JWTs are minted by the central `admin` service and validated locally with a shared HMAC secret — `missions` never calls `admin` back.
It is one of ~6 backend services running side-by-side **on each customer device** (Jetson Orin / OrangePI / operator-PC). All edge services share **one local PostgreSQL** on the device; each migrates only the tables it owns. JWTs are minted by the central `admin` service using ECDSA-SHA256 and validated locally against `admin`'s JWKS, which `missions` fetches once at startup (and refreshes on schedule) and caches; request-path validation is local and does not call back.
## What problem does it solve?
@@ -20,7 +20,7 @@ When a human operator plans, runs, and tears down missions on the edge:
2. **Mission planning** — the operator must define a named mission against a chosen vehicle and lay out an ordered set of waypoints (lat/lon or MGRS, with per-waypoint source / objective / height).
3. **Mission lifecycle** — when a mission or waypoint is deleted, every downstream artefact (media uploaded by `annotations`, AI annotations, AI detections, autopilot-emitted `map_objects`) MUST be cleaned up in FK-safe order so the local DB doesn't accumulate orphans.
4. **Cross-service cohesion** — sibling services (`autopilot`, `annotations`, detection pipeline, `gps-denied`, `ui`) must be able to read mission/waypoint data without round-trips to the central admin and without their own copies. The shared local DB is that contract.
5. **Local trust** — the operator's device may be intermittently offline from the central network. Authn/authz cannot depend on a live `admin` callback; tokens validate locally with a shared secret.
5. **Local trust** — the operator's device may be intermittently offline from the central network. Once the JWKS has been cached, authn/authz does not depend on a live `admin` callback; tokens validate locally against the cached ECDSA public keys. `admin` must be reachable at the moment of the first JWKS fetch after a cold start (then again periodically on the manager's refresh schedule).
## Who are the users?
@@ -31,7 +31,7 @@ When a human operator plans, runs, and tears down missions on the edge:
| **`annotations`** | Sibling edge service (owns `media` / `annotations` table schemas) | Indirect — `missions` cascade-deletes from `media` / `annotations` when missions/waypoints are removed |
| **Detection pipeline** | Sibling edge service (owns the `detection` table schema) | Indirect — same pattern as `annotations` |
| **`gps-denied`** *(post-B7)* | Sibling edge service (owns `orthophotos` + `gps_corrections`) | None at runtime — references `mission_id` / `waypoint_id` as plain GUIDs in its own tables; manages its own cleanup |
| **`admin`** | Central .NET service (token issuer) | One-way: issues JWTs that this service validates locally. `admin` outages do NOT take this service down (until tokens expire) |
| **`admin`** | Central .NET service (token issuer + JWKS publisher) | This service fetches admin's public JWKS once at startup and on the `ConfigurationManager` refresh schedule; request-path validation does not call back. `admin` outage after the JWKS has been cached does NOT take this service down (until cache + tokens expire). `admin` outage at the time of the first JWKS fetch causes the first protected request to fail 500 |
There are **no application-level admin / superuser roles inside this service** — every protected endpoint is gated by the single `"FL"` permission. The role → permission matrix is suite-level (`../../suite/_docs/00_roles_permissions.md`).
@@ -55,13 +55,13 @@ Seven flows make up the runtime surface (`_docs/02_document/system-flows.md`):
- **F2** Mission create / read / update
- **F3** Mission delete + **cross-service cascade** (the most critical flow; not transaction-wrapped today — ADR-006)
- **F4** Waypoint create / read / update / delete (delete is a scoped F3)
- **F5** JWT bearer validation (cross-cutting; local HS256 only)
- **F5** JWT bearer validation (cross-cutting; local ECDSA-SHA256 against admin's cached JWKS; `iss` + `aud` validated; `alg` pinned)
- **F6** Service startup + idempotent schema migration
- **F7** Anonymous `GET /health` probe
## Cross-cutting contracts owned here
1. **JWT validation contract** — trust admin-issued tokens via shared HMAC secret (`JWT_SECRET`); reject everything else with `401`/`403`.
1. **JWT validation contract** — trust admin-issued tokens via ECDSA-SHA256 signature verification against admin's published JWKS (cached locally), with `iss == JWT_ISSUER` + `aud == JWT_AUDIENCE` + `exp` (30s skew) all enforced and `alg` pinned to `EcdsaSha256`; reject everything else with `401`/`403`.
2. **Mission ownership graph & cascade-delete** — only place in the system that knows `mission → {map_objects, waypoints → media → annotations → detection}`.
3. **Suite-standard wire shapes** *(currently divergent — see `_docs/02_document/architecture.md` ADR-002)* — error envelope and `PaginatedResponse<T>` are shared with `annotations`, `admin`, `satellite-provider`.