mirror of
https://github.com/azaion/ui.git
synced 2026-06-21 12:11:11 +00:00
[AZ-501] [AZ-502] Cycle 2 Step 14 security audit + inline fixes
ci/woodpecker/push/build-arm Pipeline failed
ci/woodpecker/push/build-arm Pipeline failed
Security audit (5 phases) → reports under _docs/05_security/. AZ-501 (F-SAST-1, HIGH): Externalize hardcoded Google Geocode key from mission-planner/src/config.ts to VITE_GOOGLE_GEOCODE_KEY via new GeocodeService.ts; fail-soft warn when unset; STC-SEC1D static deny-list gate; +5 unit tests in tests/mission_planner_geocode.test.ts. AZ-502 (F-DEP-1, HIGH): Force vite>=6.4.2 and postcss>=8.5.10 via package.json overrides in both roots; clean reinstall clears all bun audit advisories. Test-spec sync (Step 12) + Update Docs (Step 13) deltas: AC-43, AC-44, NFT-SEC-09b, FT-P-61, FT-N-17, ripple log, batch_12 report. Pending user actions: revoke Google + OWM keys (AC-6 / AZ-499 AC-7). 229 PASS / 13 SKIP / 0 FAIL on static + fast suites. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -8,9 +8,9 @@
|
||||
|
||||
| Env | How it runs | API base | Auth | Tile providers |
|
||||
|-----|-------------|----------|------|----------------|
|
||||
| Development | `bun run dev` (Vite dev server, port 5173) | Vite dev proxy: `/api → http://localhost:8080` (configured in `vite.config.ts`) | Suite admin/ service running locally (typically via parent suite `docker-compose up`) | OSM + satellite (env-configurable in mission-planner only) |
|
||||
| Stage | nginx in container, ARM image `:stage-arm` | nginx `/api/<service>/ → http://<service>:8080/` (intra-cluster) | Stage suite admin/ service | Same |
|
||||
| Production | nginx in container, ARM image `:main-arm` | nginx `/api/<service>/ → http://<service>:8080/` | Prod suite admin/ service | Same |
|
||||
| Development | `bun run dev` (Vite dev server, port 5173) | Vite dev proxy: `/api → http://localhost:8080` (configured in `vite.config.ts`) | Suite admin/ service running locally (typically via parent suite `docker-compose up`) | Suite-internal `satellite-provider` via env-configurable `VITE_SATELLITE_TILE_URL` (defaults to `http://localhost:5100/tiles/{z}/{x}/{y}` when unset). Cookie auth requires same-origin; running the SPA at `localhost:5173` and `satellite-provider` at `localhost:5100` cannot send the auth cookie cross-port — recommend reaching `satellite-provider` through the suite's local nginx OR running it with auth disabled in dev (per AZ-498 risk #2). `mission-planner/` keeps its own independent `VITE_SATELLITE_TILE_URL`. |
|
||||
| Stage | nginx in container, ARM image `:stage-arm` | nginx `/api/<service>/ → http://<service>:8080/` (intra-cluster) | Stage suite admin/ service | Suite-internal `satellite-provider` on the same origin (nginx-fronted); cookie auth attached automatically. |
|
||||
| Production | nginx in container, ARM image `:main-arm` | nginx `/api/<service>/ → http://<service>:8080/` | Prod suite admin/ service | Same as Stage. Replaces the previously-used external OpenStreetMap and Esri tile providers as of cycle 2 / 2026-05-12 (AZ-498) — production deploy is gated on the cross-workspace satellite-provider cookie-auth ticket landing (autodev Step 16). |
|
||||
|
||||
## 2. Configuration model
|
||||
|
||||
@@ -21,20 +21,22 @@ The SPA bundle is **fully static**. No env vars are read at runtime by the bundl
|
||||
| Backend API URL | nginx `proxy_pass` (`nginx.conf`) — same nginx config across stage / prod | Base URLs are intra-cluster service names (`http://annotations:8080`, etc.); the URL difference between environments is hidden by the orchestrator's DNS |
|
||||
| Auth cookie domain | Set by suite admin/ service on `Set-Cookie` | UI does not control |
|
||||
| Refresh-token lifetime | Set by suite admin/ service | UI tolerates any TTL |
|
||||
| Tile provider URL (mission-planner) | `.env.example` declares `VITE_SATELLITE_TILE_URL` | mission-planner only; not deployed |
|
||||
| OpenWeatherMap API key | **Hardcoded in source** (`flightPlanUtils.ts:60`) | Security finding — Step 4 fix to remove + proxy via suite |
|
||||
| Satellite tile provider URL (main SPA) | `.env.example` declares `VITE_SATELLITE_TILE_URL`; resolved at build time via `getTileUrl()` (`src/features/flights/types.ts`) with `DEFAULT_SATELLITE_TILE_URL` fallback. Cycle 2 / AZ-498. |
|
||||
| Satellite tile provider URL (mission-planner) | `mission-planner/.env.example` declares its own independent `VITE_SATELLITE_TILE_URL` | mission-planner only; not deployed |
|
||||
| OpenWeatherMap API key + base URL (main SPA) | `.env.example` declares `VITE_OWM_API_KEY` + `VITE_OWM_BASE_URL`; resolved by `getOwmBaseUrl()` and the `flightPlanUtils.ts` builder. Closed AZ-448 / AZ-449 (no longer hardcoded). |
|
||||
| OpenWeatherMap API key + base URL (mission-planner) | `mission-planner/.env.example` declares `VITE_OWM_API_KEY` + `VITE_OWM_BASE_URL`; `WeatherService.getWeatherData(lat, lon)` returns `null` and issues NO outbound `fetch` when the key is unset (fail-soft). Closed cycle 2 / AZ-499. The previously-committed literal value MUST be revoked at the OWM dashboard (manual deliverable — AC-42 / AZ-499 AC-7); `STC-SEC1C` defends against re-introduction. |
|
||||
| `AZAION_REVISION` | Stamped into image at build time | For diagnostics |
|
||||
|
||||
## 3. Why no `.env`
|
||||
## 3. `.env` strategy
|
||||
|
||||
The workspace `.env.example` is **absent** today. The `README.md` "Local development" section explicitly notes this as a Step 4 testability fix.
|
||||
Step 4 testability + cycle 2 added a workspace `.env.example` (resolved by Vite at build time via `import.meta.env.VITE_*`). Today it declares: `VITE_OWM_API_KEY`, `VITE_OWM_BASE_URL` (AZ-448 / AZ-449), and `VITE_SATELLITE_TILE_URL` (AZ-498). `mission-planner/.env.example` mirrors the OWM pair (AZ-499) and keeps its own independent `VITE_SATELLITE_TILE_URL`.
|
||||
|
||||
**Trade-off**: avoiding a build-time env injection means `dist/` is identical across environments, which is great for promotability (the same image flows dev → stage → prod). The cost: the OpenWeatherMap key (and any future runtime config) cannot be changed without a rebuild.
|
||||
**Trade-off**: Vite resolves `import.meta.env.VITE_*` at build time, so `dist/` is environment-specific once a non-empty `VITE_OWM_API_KEY` is baked in — the OpenWeatherMap key (and any future build-time config) cannot be changed without a rebuild. This trades promotability for the air-gap-friendly pattern that lets a deploy ship with `VITE_OWM_API_KEY=""` (no OWM call, fail-soft `null` return) when the deployment must not touch the internet.
|
||||
|
||||
**Future direction** (Step 4 / Step 5):
|
||||
- Move the OpenWeatherMap call server-side (`flights/` service) — eliminates the bundled key entirely.
|
||||
- Introduce a runtime `/config.json` that nginx serves — lets ops change feature flags / tile URLs without rebuilding.
|
||||
- OR keep the static bundle and use Vite's `define` for build-time injection of safe-to-publish values (no secrets).
|
||||
**Future direction** (still open):
|
||||
- Move the OpenWeatherMap call server-side (`flights/` service) — would eliminate the bundled key entirely; the env-var hardening in cycle 2 reduces the urgency but does not remove the option.
|
||||
- Introduce a runtime `/config.json` that nginx serves — would let ops change feature flags / tile URLs without rebuilding.
|
||||
- OR keep the static bundle and continue using Vite's `import.meta.env` for build-time injection of safe-to-publish values (current approach).
|
||||
|
||||
## 4. Promotability
|
||||
|
||||
@@ -48,4 +50,4 @@ In practice: branch separation is the gating mechanism. Once dev → stage → m
|
||||
- **`bun.lock`**: committed (per `package.json`'s `packageManager` field). `package-lock.json` is gitignored.
|
||||
- **`.idea/`, `.claude/`, `.superpowers/`**: gitignored — IDE / agent metadata.
|
||||
- **Playwright entries in `.gitignore`**: present but aspirational — Playwright is not installed (Step 5–7 territory).
|
||||
- **mission-planner**: has its own `.env.example` declaring `VITE_SATELLITE_TILE_URL` and runs as a sibling Vite app. Not bundled into the deployed image.
|
||||
- **mission-planner**: has its own `.env.example` declaring `VITE_SATELLITE_TILE_URL` and (cycle 2 / AZ-499) `VITE_OWM_API_KEY` + `VITE_OWM_BASE_URL`. Runs as a sibling Vite app; not bundled into the deployed image (per AC-31 / NFT-RES-LIM-04).
|
||||
|
||||
Reference in New Issue
Block a user