diff --git a/CHANGELOG.md b/CHANGELOG.md index ecd89cc5..120e2441 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,24 @@ history of this codebase and was never published. This release is `[0.4.1]`. ## [Unreleased] +### Added + +- Gateway mode (#93): `OP_GATEWAY_SUBPATHS=true` makes Cropwright's nginx serve + Grafana, Prometheus, OpenSearch Dashboards and MLflow under `/grafana/`, + `/prometheus/`, `/dashboards/` and `/mlflow/` of its one published port, so the UIs + stay on `127.0.0.1`. One switch in `docker-compose.yml` starts each UI serving from + its sub-path, the API serves the path-relative `resource_links` and MLflow run + links (an explicit `OP_*_URL` still wins and a `0` port still hides the link), and + nginx upgrades Grafana Live websockets and forwards `Host` and `X-Forwarded-*`. + Fail closed: the UIs refuse to start when published beyond loopback, and Grafana + refuses the default or an empty admin password. Prometheus and MLflow still have no + authentication (`SECURITY.md`). The link audit is in the monitoring guide. + +### Fixed + +- Cropwright's nginx now answers redirects with relative `Location` headers; the + `/OpenProcessor` redirect used to name the container port 8080. + ### Changed - The experiment-tracking server and the trainer client move to MLflow 3.17 together diff --git a/INSTALLATION.md b/INSTALLATION.md index f3cb08a8..882da1bb 100644 --- a/INSTALLATION.md +++ b/INSTALLATION.md @@ -129,6 +129,10 @@ everything on 127.0.0.1.** `0.0.0.0`, so LAN browsers can follow resource links while the datastore and model APIs stay local. Change `GF_SECURITY_ADMIN_PASSWORD` first; MLflow and Prometheus have no auth. +- `OP_GATEWAY_SUBPATHS=true` (in `.env`, with the `cropwright` profile) serves the + four monitoring UIs under `/grafana/`, `/prometheus/`, `/dashboards/` and + `/mlflow/` on Cropwright's one port, so the UIs can stay on loopback; it needs a + non-default `GF_SECURITY_ADMIN_PASSWORD`. See the monitoring guide. - A re-run keeps the Cropwright bind you chose last time. Details: [SECURITY.md](SECURITY.md). diff --git a/SECURITY.md b/SECURITY.md index 9d1fc856..d95fc81f 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -71,7 +71,19 @@ the files it covers. Release signing is follow-up work. - **Grafana** ships with the default credentials `admin` / `admin` (`GF_SECURITY_ADMIN_USER` / `GF_SECURITY_ADMIN_PASSWORD` in `docker-compose.yml`). Change these before exposing Grafana to - anyone but yourself. + anyone but yourself. In gateway mode (`OP_GATEWAY_SUBPATHS=true`) Grafana + refuses to start with the default or an empty password. The variable only + sets the password when the `grafana_data` volume is first created; on an + existing volume change it with + `docker compose exec grafana grafana cli admin reset-admin-password `. +- **Prometheus and MLflow** have no authentication at all. In gateway mode + (see [the monitoring guide](docs-site/docs/operations/monitoring.mdx)) anyone + who can reach the gateway port can read Prometheus and read and write MLflow + experiments and registered models, exactly as they can already use the API. The + gateway moves these from "one port each" to "behind the one gateway port"; it + adds no login. Publish the gateway only on a trusted network or behind an + authenticating reverse proxy. Gateway mode also refuses to start the four UIs + when they are published beyond loopback. - **OpenSearch** ships with its security plugin disabled by default (`DISABLE_SECURITY_PLUGIN=true` / `DISABLE_SECURITY_DASHBOARDS_PLUGIN=true` in `docker-compose.yml`, commented "Disable security for dev (enable diff --git a/docker-compose.yml b/docker-compose.yml index 8687e04a..62e9d279 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -14,6 +14,54 @@ x-logging: &default-logging max-size: "10m" max-file: "5" +# Gateway mode (OP_GATEWAY_SUBPATHS=true): the Cropwright nginx serves Grafana, +# Prometheus, OpenSearch Dashboards and MLflow under /grafana/, /prometheus/, +# /dashboards/ and /mlflow/ of its one published port. Each UI must then serve +# FROM its sub-path, which Grafana and OpenSearch Dashboards take as env and +# Prometheus as flags (MLflow is left rooted and the gateway strips /mlflow: +# --static-prefix would also prefix /health and /api and break the in-network +# MLFLOW_TRACKING_URI). All four start through this one wrapper so the safety +# checks below apply to each: `sh -c