From 1644dcec978bbb93d576b9bb6640c70855b17b44 Mon Sep 17 00:00:00 2001 From: 1Pro-L4R8 Date: Sun, 8 Nov 2026 02:35:09 +0700 Subject: [PATCH 1/4] docs(engines): Trino engines authenticate and refuse plain-HTTP identity (platform #TBD) Co-Authored-By: Claude Opus 5.5 --- .../query-engines/engine-detail.md | 2 +- platform/control-plane/query-engines/index.md | 2 ++ .../control-plane/query-engines/provision.md | 15 +++++++++++++ platform/deploy-operate/engines-and-ranger.md | 2 +- platform/deploy-operate/upgrade.md | 21 +++++++++++++++++++ platform/known-issues.md | 1 + 6 files changed, 41 insertions(+), 2 deletions(-) diff --git a/platform/control-plane/query-engines/engine-detail.md b/platform/control-plane/query-engines/engine-detail.md index e690a9d..e9a3652 100644 --- a/platform/control-plane/query-engines/engine-detail.md +++ b/platform/control-plane/query-engines/engine-detail.md @@ -71,7 +71,7 @@ How Egret signs in to the coordinator depends on the engine: |---|---|---| | JWT delegation (the default for a provisioned Trino engine) | **You**, with the engine token Egret mints for you | What the engine's own policy lets you see: other users' queries only if it lets you view them. Killing a query is decided the same way. | | Password users or impersonation | The engine's `egret-monitor` account | The queries that account may see. | -| No authentication | `egret-monitor` | Every query. | +| No authentication (an external engine only; a provisioned Trino engine always authenticates since platform #TBD) | `egret-monitor` | Every query. | The node list comes from Trino's `GET /v1/node` where the coordinator serves it. Trino 483 does not by default, and then Egret reads `system.runtime.nodes` instead. That query runs as the same sign-in, so on a JWT engine it appears in the **Queries** table under your name (on the demo stack: `SELECT http_uri FROM system.runtime.nodes`, user `admin`, **FINISHED**). If it is refused too, **nodes** shows `—`: the count is unknown, not zero, and the query counts are still shown. diff --git a/platform/control-plane/query-engines/index.md b/platform/control-plane/query-engines/index.md index b55b2db..4e08868 100644 --- a/platform/control-plane/query-engines/index.md +++ b/platform/control-plane/query-engines/index.md @@ -22,6 +22,8 @@ A summary strip counts **engines**, how many are **running** and **not running** | **Status** | The lifecycle status of a provisioned engine (**Provisioning**, **Running**, **Failed**). **External** for a registered one: egret does not monitor it. | | Actions | **Details** opens the engine. | +A provisioned Trino engine can also carry an amber **Re-apply needed** badge (the API field is `securityReapplyNeeded` on the engine). Its tooltip says *This engine still accepts unauthenticated requests on port 8080. Re-apply it to turn on authentication.* The engine was applied before platform #TBD and still runs the old configuration. The badge clears after the next successful apply. An engine with JWT only and no password users never shows it, because it was already closed. See [Provision an engine](./provision.md#security--exposure). + ## Add an engine Two buttons sit at the top right: diff --git a/platform/control-plane/query-engines/provision.md b/platform/control-plane/query-engines/provision.md index d456da4..534c107 100644 --- a/platform/control-plane/query-engines/provision.md +++ b/platform/control-plane/query-engines/provision.md @@ -52,6 +52,21 @@ The form shows *Cluster-wide, coordinator, and worker Trino config. Leave fields | **Per-user delegation** | How queries from SQL Lab, charts and dashboards run as the calling user (below). | | **Ingress exposure** | *Create a Kubernetes Ingress for the coordinator. TLS terminates at the ingress.* With **Expose via ingress** on you set **Host**, **Ingress class**, **Ingress TLS cert** and **Annotations**. **Host** is required: without it the field says *Enter the host the ingress serves, or turn off Expose via ingress.* and **Create** stays disabled. | +Every provisioned Trino engine authenticates, since platform #TBD. A spec saved without an authentication setting is stored and applied as password authentication with no users, so an engine never answers an anonymous request. Egret still provisions its own `egret-monitor` account and, in impersonate mode, the `egret_delegator` account. External engines are not affected: Egret does not render their configuration. + +The coordinator also refuses authentication over plain HTTP (`http-server.authentication.allow-insecure-over-http=false`). Measured on Trino 483: + +| Request to the coordinator | Result | +|---|---| +| Plain HTTP on port 8080, no `X-Forwarded-Proto: https` header | `403`, *Authentication over HTTP is not enabled*, before any identity is read. A client cannot claim to be another user by setting `X-Trino-User`. | +| The same with `X-Forwarded-Proto: https` and no credential | `401`. | +| The engine's ingress (HTTPS), or HTTPS on port 8443, with a password or a JWT | Accepted. | +| `GET /v1/info`, no credential | `200`. Health checks keep working. | + +Egret's own monitor and query paths are not affected. A client that dials `http://:8080` directly with no password, for example `trino --server http://:8080 --user x`, no longer works: connect through the engine's ingress or on HTTPS 8443, with a password or JWT. Impersonation does not make plain HTTP safe: the earlier belief that an impersonate engine was safe over plain HTTP because only the delegator could impersonate was measured to be false, and is why the flag is now off. + +An engine that was applied before this release still runs the old configuration. See **Re-apply needed** in [the engine list](./index.md#the-engine-list) (the badge) and the [upgrade notes](../../deploy-operate/upgrade.md#trino-engines-authenticate-and-refuse-plain-http-identity). + The delegation modes: | Mode | What it does | diff --git a/platform/deploy-operate/engines-and-ranger.md b/platform/deploy-operate/engines-and-ranger.md index 3753cfe..65d36ee 100644 --- a/platform/deploy-operate/engines-and-ranger.md +++ b/platform/deploy-operate/engines-and-ranger.md @@ -119,7 +119,7 @@ names them, and the engine's **Logs** and **Exec** buttons answer *not available | Engine | Requirement | |---|---| | Trino | `http-server.process-forwarded=true`. Egret sends `X-Forwarded-Proto`; without the setting Trino answers *406* and Egret reports *502*. See [Engine 406 and 502 errors](./troubleshooting/engine-406-502). | -| Trino | For per-user delegation, JWT authentication (`http-server.authentication.type=JWT`) with `principal-field=preferred_username` and `required-audience=trino`, **over HTTPS**. Over plain HTTP Trino accepts a valid JWT but does not require one. | +| Trino | For per-user delegation, JWT authentication (`http-server.authentication.type=JWT`) with `principal-field=preferred_username` and `required-audience=trino`, **over HTTPS**. Over plain HTTP Trino accepts a valid JWT but does not require one. Engines Egret provisions set `allow-insecure-over-http=false` themselves (platform #TBD); for an engine you run, set it too, or a plain-HTTP client can claim any user. | | StarRocks | A security integration of type `authentication_jwt` for per-user delegation, with `required_issuer` equal to Egret's issuer and `required_audience` `starrocks`. The `jwks_url` must start with `http://` or `https://`. | | Both | A network path from the engine to Egret for policy downloads, and to the catalog if you use it. | diff --git a/platform/deploy-operate/upgrade.md b/platform/deploy-operate/upgrade.md index ae411e2..dc96b0a 100644 --- a/platform/deploy-operate/upgrade.md +++ b/platform/deploy-operate/upgrade.md @@ -612,6 +612,27 @@ returned by the API; keep `SECRET` values in `SECRET` outputs and inputs. There is no supported in-place rollback. Restore the database from the backup taken in step 2, then start the previous binary. Object storage is not changed by migrations, but files written by the newer version stay in the bucket. +### Trino engines authenticate and refuse plain-HTTP identity + +From platform #TBD every provisioned Trino engine authenticates, and its coordinator refuses authentication over plain HTTP +(`http-server.authentication.allow-insecure-over-http=false`). There is a migration (`0215`, one column that records which +security revision an engine was last applied with) and one API field, `securityReapplyNeeded`. + +Upgrading does not change a running engine: it keeps the configuration of its last apply, and still accepts unauthenticated +requests on port 8080 until you re-apply it. + +- **Re-apply every provisioned Trino engine** after the upgrade. In **Control plane → Engines** the engines that still need it + show an amber **Re-apply needed** badge; the badge clears after the next successful apply. An engine with JWT only and no + password users never shows it. +- **Direct plain-HTTP clients stop working** once an engine is re-applied: `trino --server http://:8080 --user x` + with no password gets 403 *Authentication over HTTP is not enabled*. Point such clients at the engine's ingress (HTTPS) or + at HTTPS on port 8443, with a password or a JWT. +- `/v1/info` stays open, and Egret's own monitor and query paths are unaffected. +- External engines are not changed by Egret. + +See [Security & Exposure](../control-plane/query-engines/provision.md#security--exposure) and KI-355 in +[Known issues](../known-issues.md). + ## Further reading - [Backup and restore](./backup-restore) diff --git a/platform/known-issues.md b/platform/known-issues.md index 7ea2996..540dc78 100644 --- a/platform/known-issues.md +++ b/platform/known-issues.md @@ -405,6 +405,7 @@ Collected while writing the detailed pages for each area (October 2026), checked | KI-352 | Governance / Trino on OPA | UX | S3 | On a Trino profile on OPA, a deny of one privilege hides an object from listings even when the user may read it: a user who may read `s1.t2` but is denied **write** on it can `SELECT` from it, yet `SHOW TABLES`, `information_schema` and so JDBC metadata and catalog browsers do not list `t2`. On Ranger they list it. OPA is stricter by design (Egret hides an object any deny or withheld classification covers), never looser. *Workaround:* none on OPA; query the table by its full name. (Measured end to end on Trino 483 for platform #839; see [Trino on OPA](./data-governance/engines-and-policy/trino-on-opa.md#known-differences-from-ranger).) | | KI-353 | Governance / Trino on OPA | Gap | S2 | View lineage is not captured through a Trino engine whose profile is on OPA: OPA refuses the `egret-lineage` principal the unmasked reads the Ranger download gives it on JWT-mode engines, so its lineage `EXPLAIN` fails closed. *Workaround:* keep the profile on Ranger where view lineage matters. (Platform #839.) | | KI-354 | Governance / Trino on OPA | Gap | S1 | An external Trino 483 engine bound to its own compiled profile on OPA cannot run any query: the profile gets no infrastructure rows (query execution, self-impersonation), and no grant can add them, so Trino's per-query checks are denied. *Workaround:* keep such an engine's profile on Ranger. (Measured on the end-to-end stack for platform #839.) | +| KI-355 | Engines / Trino | Security | S1 | A provisioned Trino engine could run with no authentication, and its coordinator accepted authentication over plain HTTP (`allow-insecure-over-http=true`). Anyone who could reach port 8080 and set `X-Trino-User` (or `trino --user ann --session-user bob`) ran queries as that user, including on engines in impersonate mode: the belief that impersonation is delegator-only made plain HTTP safe was measured to be false. *Status:* fixed in platform #TBD (November 2026): every provisioned Trino engine authenticates (a spec without `trinoConfig.auth` is applied as password authentication) and the coordinator refuses authentication over plain HTTP: plain HTTP without `X-Forwarded-Proto: https` gets 403 *Authentication over HTTP is not enabled*, and a request with the header and no credential gets 401. Measured on Trino 483. `/v1/info` stays open and Egret's own monitor and query paths are unaffected. An engine applied before the fix keeps the old configuration until you re-apply it: the engine list shows **Re-apply needed**. A client that used `http://:8080` with no password must use the engine's ingress or HTTPS 8443 with a password or JWT. External engines are not changed by Egret; set the flag on them yourself. | ## Not verified From 3da704de49887accba833740b1509d02eaee4097 Mon Sep 17 00:00:00 2001 From: 1Pro-L4R8 Date: Sun, 8 Nov 2026 02:37:31 +0700 Subject: [PATCH 2/4] docs: scope measured claims; 8443 only on delegation-capable engines Co-Authored-By: Claude Opus 5.5 --- .../control-plane/query-engines/engine-detail.md | 1 - platform/control-plane/query-engines/index.md | 2 +- platform/control-plane/query-engines/provision.md | 9 ++++++--- platform/deploy-operate/engines-and-ranger.md | 2 +- platform/deploy-operate/upgrade.md | 14 ++++++++------ platform/known-issues.md | 2 +- 6 files changed, 17 insertions(+), 13 deletions(-) diff --git a/platform/control-plane/query-engines/engine-detail.md b/platform/control-plane/query-engines/engine-detail.md index e9a3652..3f0a166 100644 --- a/platform/control-plane/query-engines/engine-detail.md +++ b/platform/control-plane/query-engines/engine-detail.md @@ -71,7 +71,6 @@ How Egret signs in to the coordinator depends on the engine: |---|---|---| | JWT delegation (the default for a provisioned Trino engine) | **You**, with the engine token Egret mints for you | What the engine's own policy lets you see: other users' queries only if it lets you view them. Killing a query is decided the same way. | | Password users or impersonation | The engine's `egret-monitor` account | The queries that account may see. | -| No authentication (an external engine only; a provisioned Trino engine always authenticates since platform #TBD) | `egret-monitor` | Every query. | The node list comes from Trino's `GET /v1/node` where the coordinator serves it. Trino 483 does not by default, and then Egret reads `system.runtime.nodes` instead. That query runs as the same sign-in, so on a JWT engine it appears in the **Queries** table under your name (on the demo stack: `SELECT http_uri FROM system.runtime.nodes`, user `admin`, **FINISHED**). If it is refused too, **nodes** shows `—`: the count is unknown, not zero, and the query counts are still shown. diff --git a/platform/control-plane/query-engines/index.md b/platform/control-plane/query-engines/index.md index 4e08868..0653f5b 100644 --- a/platform/control-plane/query-engines/index.md +++ b/platform/control-plane/query-engines/index.md @@ -22,7 +22,7 @@ A summary strip counts **engines**, how many are **running** and **not running** | **Status** | The lifecycle status of a provisioned engine (**Provisioning**, **Running**, **Failed**). **External** for a registered one: egret does not monitor it. | | Actions | **Details** opens the engine. | -A provisioned Trino engine can also carry an amber **Re-apply needed** badge (the API field is `securityReapplyNeeded` on the engine). Its tooltip says *This engine still accepts unauthenticated requests on port 8080. Re-apply it to turn on authentication.* The engine was applied before platform #TBD and still runs the old configuration. The badge clears after the next successful apply. An engine with JWT only and no password users never shows it, because it was already closed. See [Provision an engine](./provision.md#security--exposure). +A provisioned Trino engine can also carry a **Re-apply needed** badge (the API field is `securityReapplyNeeded` on the engine). Its tooltip says *This engine still accepts unauthenticated requests on port 8080. Re-apply it to turn on authentication.* The engine was applied before platform #TBD and still runs the old configuration. The badge clears after the next successful apply. An engine with JWT only and no password users never shows it. See [Provision an engine](./provision.md#security--exposure). ## Add an engine diff --git a/platform/control-plane/query-engines/provision.md b/platform/control-plane/query-engines/provision.md index 534c107..203eabc 100644 --- a/platform/control-plane/query-engines/provision.md +++ b/platform/control-plane/query-engines/provision.md @@ -52,7 +52,7 @@ The form shows *Cluster-wide, coordinator, and worker Trino config. Leave fields | **Per-user delegation** | How queries from SQL Lab, charts and dashboards run as the calling user (below). | | **Ingress exposure** | *Create a Kubernetes Ingress for the coordinator. TLS terminates at the ingress.* With **Expose via ingress** on you set **Host**, **Ingress class**, **Ingress TLS cert** and **Annotations**. **Host** is required: without it the field says *Enter the host the ingress serves, or turn off Expose via ingress.* and **Create** stays disabled. | -Every provisioned Trino engine authenticates, since platform #TBD. A spec saved without an authentication setting is stored and applied as password authentication with no users, so an engine never answers an anonymous request. Egret still provisions its own `egret-monitor` account and, in impersonate mode, the `egret_delegator` account. External engines are not affected: Egret does not render their configuration. +Every provisioned Trino engine authenticates, since platform #TBD. An engine created or updated with no authentication setting has `{"password":{}}` stored (password authentication with no users) and applied; an existing engine gains it at its next apply. Egret still provisions its own `egret-monitor` account and, in impersonate mode, the `egret_delegator` account. External engines are not affected: Egret does not render their configuration. The coordinator also refuses authentication over plain HTTP (`http-server.authentication.allow-insecure-over-http=false`). Measured on Trino 483: @@ -60,10 +60,13 @@ The coordinator also refuses authentication over plain HTTP (`http-server.authen |---|---| | Plain HTTP on port 8080, no `X-Forwarded-Proto: https` header | `403`, *Authentication over HTTP is not enabled*, before any identity is read. A client cannot claim to be another user by setting `X-Trino-User`. | | The same with `X-Forwarded-Proto: https` and no credential | `401`. | -| The engine's ingress (HTTPS), or HTTPS on port 8443, with a password or a JWT | Accepted. | +| The same with `X-Forwarded-Proto: https` and a Basic credential | Accepted. | +| The delegator over HTTPS 8443 | Accepted. | | `GET /v1/info`, no credential | `200`. Health checks keep working. | -Egret's own monitor and query paths are not affected. A client that dials `http://:8080` directly with no password, for example `trino --server http://:8080 --user x`, no longer works: connect through the engine's ingress or on HTTPS 8443, with a password or JWT. Impersonation does not make plain HTTP safe: the earlier belief that an impersonate engine was safe over plain HTTP because only the delegator could impersonate was measured to be false, and is why the flag is now off. +Egret's own monitor and query paths, and the engine's ingress, send `X-Forwarded-Proto: https` with a credential, so they keep working. That was simulated with a hand-set header; it was not measured against a real ingress controller or kube proxy. + +A client that dials `http://:8080` directly with no password, for example `trino --server http://:8080 --user x`, no longer works. Connect through the engine's ingress, or on HTTPS 8443 on engines that serve it (delegation-capable engines: impersonate mode, and JWT mode with a JWT block), with a password or JWT. An engine with neither an ingress nor port 8443 has no direct client path, only Egret's own. Impersonation does not make plain HTTP safe: the earlier belief that an impersonate engine was safe over plain HTTP because only the delegator could impersonate was measured to be false, and is why the flag is now off. An engine that was applied before this release still runs the old configuration. See **Re-apply needed** in [the engine list](./index.md#the-engine-list) (the badge) and the [upgrade notes](../../deploy-operate/upgrade.md#trino-engines-authenticate-and-refuse-plain-http-identity). diff --git a/platform/deploy-operate/engines-and-ranger.md b/platform/deploy-operate/engines-and-ranger.md index 65d36ee..966b7f5 100644 --- a/platform/deploy-operate/engines-and-ranger.md +++ b/platform/deploy-operate/engines-and-ranger.md @@ -119,7 +119,7 @@ names them, and the engine's **Logs** and **Exec** buttons answer *not available | Engine | Requirement | |---|---| | Trino | `http-server.process-forwarded=true`. Egret sends `X-Forwarded-Proto`; without the setting Trino answers *406* and Egret reports *502*. See [Engine 406 and 502 errors](./troubleshooting/engine-406-502). | -| Trino | For per-user delegation, JWT authentication (`http-server.authentication.type=JWT`) with `principal-field=preferred_username` and `required-audience=trino`, **over HTTPS**. Over plain HTTP Trino accepts a valid JWT but does not require one. Engines Egret provisions set `allow-insecure-over-http=false` themselves (platform #TBD); for an engine you run, set it too, or a plain-HTTP client can claim any user. | +| Trino | For per-user delegation, JWT authentication (`http-server.authentication.type=JWT`) with `principal-field=preferred_username` and `required-audience=trino`, **over HTTPS**. Over plain HTTP, with `allow-insecure-over-http=true`, Trino accepts a valid JWT but does not require one. Engines Egret provisions set that flag to `false` and always authenticate (platform #TBD). An engine you run needs both an authenticator and `allow-insecure-over-http=false`: without an authenticator anyone can claim any user, whatever the flag says. | | StarRocks | A security integration of type `authentication_jwt` for per-user delegation, with `required_issuer` equal to Egret's issuer and `required_audience` `starrocks`. The `jwks_url` must start with `http://` or `https://`. | | Both | A network path from the engine to Egret for policy downloads, and to the catalog if you use it. | diff --git a/platform/deploy-operate/upgrade.md b/platform/deploy-operate/upgrade.md index dc96b0a..c9404e9 100644 --- a/platform/deploy-operate/upgrade.md +++ b/platform/deploy-operate/upgrade.md @@ -618,16 +618,18 @@ From platform #TBD every provisioned Trino engine authenticates, and its coordin (`http-server.authentication.allow-insecure-over-http=false`). There is a migration (`0215`, one column that records which security revision an engine was last applied with) and one API field, `securityReapplyNeeded`. -Upgrading does not change a running engine: it keeps the configuration of its last apply, and still accepts unauthenticated -requests on port 8080 until you re-apply it. +The new settings take effect when an engine is next applied (re-apply, or any change that applies it). Until then it keeps the +configuration of its last apply. - **Re-apply every provisioned Trino engine** after the upgrade. In **Control plane → Engines** the engines that still need it - show an amber **Re-apply needed** badge; the badge clears after the next successful apply. An engine with JWT only and no + show a **Re-apply needed** badge; the badge clears after the next successful apply. An engine with JWT only and no password users never shows it. - **Direct plain-HTTP clients stop working** once an engine is re-applied: `trino --server http://:8080 --user x` - with no password gets 403 *Authentication over HTTP is not enabled*. Point such clients at the engine's ingress (HTTPS) or - at HTTPS on port 8443, with a password or a JWT. -- `/v1/info` stays open, and Egret's own monitor and query paths are unaffected. + with no password gets 403 *Authentication over HTTP is not enabled*. Point such clients at the engine's ingress, or at HTTPS + on port 8443 where the engine serves it (delegation-capable engines), with a password or a JWT. An engine with neither has no + direct client path, only Egret's own. +- `/v1/info` stays open. Egret's own monitor and query paths send `X-Forwarded-Proto: https` with a credential and keep working + (simulated with a hand-set header; not measured against a real ingress controller). - External engines are not changed by Egret. See [Security & Exposure](../control-plane/query-engines/provision.md#security--exposure) and KI-355 in diff --git a/platform/known-issues.md b/platform/known-issues.md index 540dc78..64f762c 100644 --- a/platform/known-issues.md +++ b/platform/known-issues.md @@ -405,7 +405,7 @@ Collected while writing the detailed pages for each area (October 2026), checked | KI-352 | Governance / Trino on OPA | UX | S3 | On a Trino profile on OPA, a deny of one privilege hides an object from listings even when the user may read it: a user who may read `s1.t2` but is denied **write** on it can `SELECT` from it, yet `SHOW TABLES`, `information_schema` and so JDBC metadata and catalog browsers do not list `t2`. On Ranger they list it. OPA is stricter by design (Egret hides an object any deny or withheld classification covers), never looser. *Workaround:* none on OPA; query the table by its full name. (Measured end to end on Trino 483 for platform #839; see [Trino on OPA](./data-governance/engines-and-policy/trino-on-opa.md#known-differences-from-ranger).) | | KI-353 | Governance / Trino on OPA | Gap | S2 | View lineage is not captured through a Trino engine whose profile is on OPA: OPA refuses the `egret-lineage` principal the unmasked reads the Ranger download gives it on JWT-mode engines, so its lineage `EXPLAIN` fails closed. *Workaround:* keep the profile on Ranger where view lineage matters. (Platform #839.) | | KI-354 | Governance / Trino on OPA | Gap | S1 | An external Trino 483 engine bound to its own compiled profile on OPA cannot run any query: the profile gets no infrastructure rows (query execution, self-impersonation), and no grant can add them, so Trino's per-query checks are denied. *Workaround:* keep such an engine's profile on Ranger. (Measured on the end-to-end stack for platform #839.) | -| KI-355 | Engines / Trino | Security | S1 | A provisioned Trino engine could run with no authentication, and its coordinator accepted authentication over plain HTTP (`allow-insecure-over-http=true`). Anyone who could reach port 8080 and set `X-Trino-User` (or `trino --user ann --session-user bob`) ran queries as that user, including on engines in impersonate mode: the belief that impersonation is delegator-only made plain HTTP safe was measured to be false. *Status:* fixed in platform #TBD (November 2026): every provisioned Trino engine authenticates (a spec without `trinoConfig.auth` is applied as password authentication) and the coordinator refuses authentication over plain HTTP: plain HTTP without `X-Forwarded-Proto: https` gets 403 *Authentication over HTTP is not enabled*, and a request with the header and no credential gets 401. Measured on Trino 483. `/v1/info` stays open and Egret's own monitor and query paths are unaffected. An engine applied before the fix keeps the old configuration until you re-apply it: the engine list shows **Re-apply needed**. A client that used `http://:8080` with no password must use the engine's ingress or HTTPS 8443 with a password or JWT. External engines are not changed by Egret; set the flag on them yourself. | +| KI-355 | Engines / Trino | Security | S1 | **Fixed in platform #TBD (November 2026).** A provisioned Trino engine could run with no authentication and accepted authentication over plain HTTP, so anyone who reached port 8080 and set `X-Trino-User` (or `--session-user`) ran queries as that user, impersonate-mode engines included. Every provisioned Trino engine now authenticates and refuses plain HTTP without `X-Forwarded-Proto: https` (403 *Authentication over HTTP is not enabled*; with the header and no credential, 401). Measured on Trino 483. `/v1/info` stays open; Egret's monitor and the ingress send the header with a credential (simulated, not measured against a real ingress controller). An engine applied before the fix keeps the old configuration until it is next applied: the engine list shows **Re-apply needed**. A client with no password must use the engine's ingress, or HTTPS 8443 where the engine serves it. External engines are not changed by Egret. | ## Not verified From dd454d7acf96ba0291c08bc5169bb4a2243b2c41 Mon Sep 17 00:00:00 2001 From: 1Pro-L4R8 Date: Sun, 8 Nov 2026 02:58:36 +0700 Subject: [PATCH 3/4] docs(engines): delegated queries use HTTPS 8443, not the forwarded header Only the monitor sends X-Forwarded-Proto: https with a password; delegated queries go to the coordinator's HTTPS listener on 8443. Co-Authored-By: Claude Opus 5.5 --- platform/control-plane/query-engines/provision.md | 2 +- platform/deploy-operate/upgrade.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/control-plane/query-engines/provision.md b/platform/control-plane/query-engines/provision.md index 203eabc..208998f 100644 --- a/platform/control-plane/query-engines/provision.md +++ b/platform/control-plane/query-engines/provision.md @@ -64,7 +64,7 @@ The coordinator also refuses authentication over plain HTTP (`http-server.authen | The delegator over HTTPS 8443 | Accepted. | | `GET /v1/info`, no credential | `200`. Health checks keep working. | -Egret's own monitor and query paths, and the engine's ingress, send `X-Forwarded-Proto: https` with a credential, so they keep working. That was simulated with a hand-set header; it was not measured against a real ingress controller or kube proxy. +Egret's monitor sends `X-Forwarded-Proto: https` with a password; delegated queries use HTTPS on port 8443. The engine's ingress sends the header too. The header was simulated by hand; it was not measured against a real ingress controller or kube proxy. A client that dials `http://:8080` directly with no password, for example `trino --server http://:8080 --user x`, no longer works. Connect through the engine's ingress, or on HTTPS 8443 on engines that serve it (delegation-capable engines: impersonate mode, and JWT mode with a JWT block), with a password or JWT. An engine with neither an ingress nor port 8443 has no direct client path, only Egret's own. Impersonation does not make plain HTTP safe: the earlier belief that an impersonate engine was safe over plain HTTP because only the delegator could impersonate was measured to be false, and is why the flag is now off. diff --git a/platform/deploy-operate/upgrade.md b/platform/deploy-operate/upgrade.md index c9404e9..152cdba 100644 --- a/platform/deploy-operate/upgrade.md +++ b/platform/deploy-operate/upgrade.md @@ -628,8 +628,8 @@ configuration of its last apply. with no password gets 403 *Authentication over HTTP is not enabled*. Point such clients at the engine's ingress, or at HTTPS on port 8443 where the engine serves it (delegation-capable engines), with a password or a JWT. An engine with neither has no direct client path, only Egret's own. -- `/v1/info` stays open. Egret's own monitor and query paths send `X-Forwarded-Proto: https` with a credential and keep working - (simulated with a hand-set header; not measured against a real ingress controller). +- `/v1/info` stays open. Egret's monitor sends `X-Forwarded-Proto: https` with a password; delegated queries use HTTPS on + port 8443. The ingress sends the header too (simulated with a hand-set header; not measured against a real ingress controller). - External engines are not changed by Egret. See [Security & Exposure](../control-plane/query-engines/provision.md#security--exposure) and KI-355 in From adef920e02e370b55cf02c6ba7f91b1e7fa83a33 Mon Sep 17 00:00:00 2001 From: 1Pro-L4R8 Date: Sun, 8 Nov 2026 03:02:46 +0700 Subject: [PATCH 4/4] docs: name platform #842; the monitor sends a credential Co-Authored-By: Claude Opus 5.5 --- platform/control-plane/query-engines/index.md | 2 +- platform/control-plane/query-engines/provision.md | 4 ++-- platform/deploy-operate/engines-and-ranger.md | 2 +- platform/deploy-operate/upgrade.md | 4 ++-- platform/known-issues.md | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/platform/control-plane/query-engines/index.md b/platform/control-plane/query-engines/index.md index 0653f5b..e4bc8b4 100644 --- a/platform/control-plane/query-engines/index.md +++ b/platform/control-plane/query-engines/index.md @@ -22,7 +22,7 @@ A summary strip counts **engines**, how many are **running** and **not running** | **Status** | The lifecycle status of a provisioned engine (**Provisioning**, **Running**, **Failed**). **External** for a registered one: egret does not monitor it. | | Actions | **Details** opens the engine. | -A provisioned Trino engine can also carry a **Re-apply needed** badge (the API field is `securityReapplyNeeded` on the engine). Its tooltip says *This engine still accepts unauthenticated requests on port 8080. Re-apply it to turn on authentication.* The engine was applied before platform #TBD and still runs the old configuration. The badge clears after the next successful apply. An engine with JWT only and no password users never shows it. See [Provision an engine](./provision.md#security--exposure). +A provisioned Trino engine can also carry a **Re-apply needed** badge (the API field is `securityReapplyNeeded` on the engine). Its tooltip says *This engine still accepts unauthenticated requests on port 8080. Re-apply it to turn on authentication.* The engine was applied before platform #842 and still runs the old configuration. The badge clears after the next successful apply. An engine with JWT only and no password users never shows it. See [Provision an engine](./provision.md#security--exposure). ## Add an engine diff --git a/platform/control-plane/query-engines/provision.md b/platform/control-plane/query-engines/provision.md index 208998f..babd973 100644 --- a/platform/control-plane/query-engines/provision.md +++ b/platform/control-plane/query-engines/provision.md @@ -52,7 +52,7 @@ The form shows *Cluster-wide, coordinator, and worker Trino config. Leave fields | **Per-user delegation** | How queries from SQL Lab, charts and dashboards run as the calling user (below). | | **Ingress exposure** | *Create a Kubernetes Ingress for the coordinator. TLS terminates at the ingress.* With **Expose via ingress** on you set **Host**, **Ingress class**, **Ingress TLS cert** and **Annotations**. **Host** is required: without it the field says *Enter the host the ingress serves, or turn off Expose via ingress.* and **Create** stays disabled. | -Every provisioned Trino engine authenticates, since platform #TBD. An engine created or updated with no authentication setting has `{"password":{}}` stored (password authentication with no users) and applied; an existing engine gains it at its next apply. Egret still provisions its own `egret-monitor` account and, in impersonate mode, the `egret_delegator` account. External engines are not affected: Egret does not render their configuration. +Every provisioned Trino engine authenticates, since platform #842. An engine created or updated with no authentication setting has `{"password":{}}` stored (password authentication with no users) and applied; an existing engine gains it at its next apply. Egret still provisions its own `egret-monitor` account and, in impersonate mode, the `egret_delegator` account. External engines are not affected: Egret does not render their configuration. The coordinator also refuses authentication over plain HTTP (`http-server.authentication.allow-insecure-over-http=false`). Measured on Trino 483: @@ -64,7 +64,7 @@ The coordinator also refuses authentication over plain HTTP (`http-server.authen | The delegator over HTTPS 8443 | Accepted. | | `GET /v1/info`, no credential | `200`. Health checks keep working. | -Egret's monitor sends `X-Forwarded-Proto: https` with a password; delegated queries use HTTPS on port 8443. The engine's ingress sends the header too. The header was simulated by hand; it was not measured against a real ingress controller or kube proxy. +Egret's monitor sends `X-Forwarded-Proto: https` with a credential; delegated queries use HTTPS on port 8443. The engine's ingress sends the header too. The header was simulated by hand; it was not measured against a real ingress controller or kube proxy. A client that dials `http://:8080` directly with no password, for example `trino --server http://:8080 --user x`, no longer works. Connect through the engine's ingress, or on HTTPS 8443 on engines that serve it (delegation-capable engines: impersonate mode, and JWT mode with a JWT block), with a password or JWT. An engine with neither an ingress nor port 8443 has no direct client path, only Egret's own. Impersonation does not make plain HTTP safe: the earlier belief that an impersonate engine was safe over plain HTTP because only the delegator could impersonate was measured to be false, and is why the flag is now off. diff --git a/platform/deploy-operate/engines-and-ranger.md b/platform/deploy-operate/engines-and-ranger.md index 966b7f5..e947426 100644 --- a/platform/deploy-operate/engines-and-ranger.md +++ b/platform/deploy-operate/engines-and-ranger.md @@ -119,7 +119,7 @@ names them, and the engine's **Logs** and **Exec** buttons answer *not available | Engine | Requirement | |---|---| | Trino | `http-server.process-forwarded=true`. Egret sends `X-Forwarded-Proto`; without the setting Trino answers *406* and Egret reports *502*. See [Engine 406 and 502 errors](./troubleshooting/engine-406-502). | -| Trino | For per-user delegation, JWT authentication (`http-server.authentication.type=JWT`) with `principal-field=preferred_username` and `required-audience=trino`, **over HTTPS**. Over plain HTTP, with `allow-insecure-over-http=true`, Trino accepts a valid JWT but does not require one. Engines Egret provisions set that flag to `false` and always authenticate (platform #TBD). An engine you run needs both an authenticator and `allow-insecure-over-http=false`: without an authenticator anyone can claim any user, whatever the flag says. | +| Trino | For per-user delegation, JWT authentication (`http-server.authentication.type=JWT`) with `principal-field=preferred_username` and `required-audience=trino`, **over HTTPS**. Over plain HTTP, with `allow-insecure-over-http=true`, Trino accepts a valid JWT but does not require one. Engines Egret provisions set that flag to `false` and always authenticate (platform #842). An engine you run needs both an authenticator and `allow-insecure-over-http=false`: without an authenticator anyone can claim any user, whatever the flag says. | | StarRocks | A security integration of type `authentication_jwt` for per-user delegation, with `required_issuer` equal to Egret's issuer and `required_audience` `starrocks`. The `jwks_url` must start with `http://` or `https://`. | | Both | A network path from the engine to Egret for policy downloads, and to the catalog if you use it. | diff --git a/platform/deploy-operate/upgrade.md b/platform/deploy-operate/upgrade.md index 152cdba..1629d07 100644 --- a/platform/deploy-operate/upgrade.md +++ b/platform/deploy-operate/upgrade.md @@ -614,7 +614,7 @@ binary. Object storage is not changed by migrations, but files written by the ne ### Trino engines authenticate and refuse plain-HTTP identity -From platform #TBD every provisioned Trino engine authenticates, and its coordinator refuses authentication over plain HTTP +From platform #842 every provisioned Trino engine authenticates, and its coordinator refuses authentication over plain HTTP (`http-server.authentication.allow-insecure-over-http=false`). There is a migration (`0215`, one column that records which security revision an engine was last applied with) and one API field, `securityReapplyNeeded`. @@ -628,7 +628,7 @@ configuration of its last apply. with no password gets 403 *Authentication over HTTP is not enabled*. Point such clients at the engine's ingress, or at HTTPS on port 8443 where the engine serves it (delegation-capable engines), with a password or a JWT. An engine with neither has no direct client path, only Egret's own. -- `/v1/info` stays open. Egret's monitor sends `X-Forwarded-Proto: https` with a password; delegated queries use HTTPS on +- `/v1/info` stays open. Egret's monitor sends `X-Forwarded-Proto: https` with a credential; delegated queries use HTTPS on port 8443. The ingress sends the header too (simulated with a hand-set header; not measured against a real ingress controller). - External engines are not changed by Egret. diff --git a/platform/known-issues.md b/platform/known-issues.md index 64f762c..be9de2d 100644 --- a/platform/known-issues.md +++ b/platform/known-issues.md @@ -405,7 +405,7 @@ Collected while writing the detailed pages for each area (October 2026), checked | KI-352 | Governance / Trino on OPA | UX | S3 | On a Trino profile on OPA, a deny of one privilege hides an object from listings even when the user may read it: a user who may read `s1.t2` but is denied **write** on it can `SELECT` from it, yet `SHOW TABLES`, `information_schema` and so JDBC metadata and catalog browsers do not list `t2`. On Ranger they list it. OPA is stricter by design (Egret hides an object any deny or withheld classification covers), never looser. *Workaround:* none on OPA; query the table by its full name. (Measured end to end on Trino 483 for platform #839; see [Trino on OPA](./data-governance/engines-and-policy/trino-on-opa.md#known-differences-from-ranger).) | | KI-353 | Governance / Trino on OPA | Gap | S2 | View lineage is not captured through a Trino engine whose profile is on OPA: OPA refuses the `egret-lineage` principal the unmasked reads the Ranger download gives it on JWT-mode engines, so its lineage `EXPLAIN` fails closed. *Workaround:* keep the profile on Ranger where view lineage matters. (Platform #839.) | | KI-354 | Governance / Trino on OPA | Gap | S1 | An external Trino 483 engine bound to its own compiled profile on OPA cannot run any query: the profile gets no infrastructure rows (query execution, self-impersonation), and no grant can add them, so Trino's per-query checks are denied. *Workaround:* keep such an engine's profile on Ranger. (Measured on the end-to-end stack for platform #839.) | -| KI-355 | Engines / Trino | Security | S1 | **Fixed in platform #TBD (November 2026).** A provisioned Trino engine could run with no authentication and accepted authentication over plain HTTP, so anyone who reached port 8080 and set `X-Trino-User` (or `--session-user`) ran queries as that user, impersonate-mode engines included. Every provisioned Trino engine now authenticates and refuses plain HTTP without `X-Forwarded-Proto: https` (403 *Authentication over HTTP is not enabled*; with the header and no credential, 401). Measured on Trino 483. `/v1/info` stays open; Egret's monitor and the ingress send the header with a credential (simulated, not measured against a real ingress controller). An engine applied before the fix keeps the old configuration until it is next applied: the engine list shows **Re-apply needed**. A client with no password must use the engine's ingress, or HTTPS 8443 where the engine serves it. External engines are not changed by Egret. | +| KI-355 | Engines / Trino | Security | S1 | **Fixed in platform #842 (November 2026).** A provisioned Trino engine could run with no authentication and accepted authentication over plain HTTP, so anyone who reached port 8080 and set `X-Trino-User` (or `--session-user`) ran queries as that user, impersonate-mode engines included. Every provisioned Trino engine now authenticates and refuses plain HTTP without `X-Forwarded-Proto: https` (403 *Authentication over HTTP is not enabled*; with the header and no credential, 401). Measured on Trino 483. `/v1/info` stays open; Egret's monitor and the ingress send the header with a credential (simulated, not measured against a real ingress controller). An engine applied before the fix keeps the old configuration until it is next applied: the engine list shows **Re-apply needed**. A client with no password must use the engine's ingress, or HTTPS 8443 where the engine serves it. External engines are not changed by Egret. | ## Not verified