Merge pull request '[session 3] docs(devices,mgmt): MSP_ADMIN scope resolved fresh from mgmt (#196)' (#60) from docs/institutions-scope-196 into develop
CD - Develop (guide → bcos.dev) / build-and-deploy (push) Successful in 1m4s
CD - Develop (guide → bcos.dev) / build-and-deploy (push) Successful in 1m4s
This commit was merged in pull request #60.
This commit is contained in:
@@ -90,6 +90,7 @@ Base paths: `/api/atms` + `/api/devices`, `/api/atm-groups`, `/api/atm-makes`, `
|
||||
- **DB uses `DB_URL`** (full JDBC URL) via `spring.datasource.url=${DB_URL:...}`, not split host/port/name vars.
|
||||
- **Two auth realms.** Admin controllers use `@PreAuthorize("hasAnyRole('MSP_ADMIN','BCOS_ADMIN')")`; internal/agent controllers (`/api/internal/*`) use `hasRole('INTERNAL')` (e.g. `InternalAtmController`, `AgentTokenInternalController`, `InternalLogController`).
|
||||
- **Exception:** `POST` and `DELETE /api/institution-keys` are `hasRole('BCOS_ADMIN')` only — creating/removing an institution is a BCOS/mgmt task, not MSP (msp#29). `PUT`/update stays MSP+BCOS.
|
||||
- **MSP_ADMIN scope is resolved fresh from mgmt, not from the JWT claim** (#196, prod 2026-07-24). The `institutionKeys` claim is a login-time snapshot, so a newly provisioned institution allocated to an MSP was invisible (and its agent-properties unsaveable) until the user re-logged in. `JwtAuthenticationFilter` now calls `MgmtInstitutionClient.getInstitutionKeysForDomain(email-domain)` → mgmt `GET /api/internal/customers/domain/{domain}/institution-keys` (source of truth, `X-Internal-Secret`), 30 s cache, and uses that as the scope; it **falls back to the token claim if mgmt is unreachable**, so behaviour never degrades below the old path. `GET /api/institution-keys/accessible` additionally best-effort `syncFromMgmt()`s new institutions into the local `institution_keys` mirror (the FK needed to save agent-properties). mgmt base URL: `mgmt.base-url`/`MGMT_SERVICE_URL` (default `http://hiveiq-mgmt:8080`). Scope enforcement is unchanged — out-of-scope keys still 403.
|
||||
- **Phase-2 path aliases.** `/api/atms`, `/api/atm-groups`, `/api/atm-makes`, `/api/atm-models`, `/api/atm-field-definitions` each also respond on a `/api/device*` alias for the ongoing ATM→device rename; both must stay routable in nginx.
|
||||
- **CDN token.** `agent.cdn.token` (env `CDN_TOKEN`) has a hardcoded fallback in `application.properties` used by the `/api/agent-profiles/modules-manifest` proxy.
|
||||
- **Publish-on-every-change.** Device mirrors in incident/fleet/reports/recon depend on `hiveops.device.events`; any write path that skips `DeviceEventPublisher` leaves those mirrors stale (no reconciler).
|
||||
|
||||
@@ -58,7 +58,8 @@ REST base path `/api/v1` (plus `/api/internal/*` service-to-service, and Thymele
|
||||
| GET/PUT `/api/v1/msp/modules/users/{authUserId}` | MSP-scoped module allocations |
|
||||
| POST/GET `/api/v1/agent-tokens` , POST `/api/v1/agent-tokens/{id}/revoke` | Manage agent tokens |
|
||||
| POST `/api/internal/agent-tokens/validate` | Internal: validate an agent token |
|
||||
| GET `/api/internal/customers/domain/{domain}/institution-keys` | Internal: resolve institution keys by domain |
|
||||
| GET `/api/internal/customers/domain/{domain}/institution-keys` | Internal: resolve institution keys by domain (devices uses this for fresh MSP_ADMIN scope, #196) |
|
||||
| GET `/api/internal/institutions` | Internal: canonical institution list (`{key, name}`, deduped/sorted). Source of truth consumed by devices to sync its local mirror (#196) |
|
||||
| GET/PUT `/api/v1/billing/rates` , POST `/api/v1/billing/invoices/generate` | Billing rates + invoice generation |
|
||||
| GET `/api/v1/billing/qb/connect` , GET `/api/v1/billing/qb/callback` | QuickBooks OAuth connect/callback |
|
||||
|
||||
@@ -71,5 +72,6 @@ Not exhaustive — see the `controller/` and `controller/portal/` packages.
|
||||
- **DB name is env-driven, not literal.** Prod JDBC URL is assembled from `DB_HOST`/`DB_PORT`/`DB_NAME`; there is no hardcoded `hiveiq_mgmt` in `application.yml`.
|
||||
- **Bootstrap requires the config server.** `bootstrap.yml` sets `fail-fast: true` with `CONFIG_USERNAME`/`CONFIG_PASSWORD`; mgmt will not start if `hiveops-config` is unreachable.
|
||||
- **CORS is mandatory in prod.** `CORS_ALLOWED_ORIGINS` must list every frontend origin (and be mirrored in `hiveops-auth`); missing it blocks the SPAs.
|
||||
- **Internal service secret is shared.** `INTERNAL_SERVICE_SECRET` is reused for both the claims service call and the incident service-to-service trust.
|
||||
- **Internal service secret is shared.** `INTERNAL_SERVICE_SECRET` is reused for both the claims service call and the incident service-to-service trust (and the `/api/internal/institutions` + domain-scope endpoints devices calls, via the `X-Internal-Secret` header — mgmt treats a blank secret as open and logs a WARN).
|
||||
- **mgmt is the source of truth for institutions.** Downstream services must not duplicate provisioning — devices resolves MSP_ADMIN scope and mirrors new institutions off `/api/internal/customers/domain/{domain}/institution-keys` + `/api/internal/institutions` rather than trusting stale JWT claims (#196). See [technical.devices].
|
||||
- **Swagger and H2 console are disabled by default** (`SWAGGER_ENABLED=false`, H2 console off in prod) — security hardening, don't expect them live.
|
||||
|
||||
Reference in New Issue
Block a user