Update
GeoIntel release gates / Compile, test, contracts and builds (push) Canceled after 0s
GeoIntel release gates / Python and npm vulnerability policy (push) Canceled after 0s
GeoIntel release gates / GIS image, SBOM and container scan (push) Canceled after 0s

This commit is contained in:
Jens
2026-07-27 23:28:43 +02:00
parent 21015757bd
commit c76a746cd7
39 changed files with 3268 additions and 519 deletions
+48 -14
View File
@@ -45,27 +45,37 @@ Any valid GeoJSON geometry object. V1 primarily expects `Polygon` and `MultiPoly
}
```
## Operator authentication
## Operator authentication and guest demo
Authentication is an optional single-operator access gate, not multi-user
account management. When `GEOINTEL_AUTH_ENABLED=true`, every `/api/v1/*`
request except the three authentication endpoints below requires a valid
signed `geointel_session` cookie. Missing, expired or modified sessions return
HTTP 401 with `AUTHENTICATION_REQUIRED`. Direct loopback calls to the backend
without proxy headers remain available to trusted in-container operator tools;
the backend is bound to loopback in the all-in-one runtime.
Authentication remains an optional single-operator access gate, not multi-user
account management or tenant isolation. When `GEOINTEL_AUTH_ENABLED=true`,
every `/api/v1/*` request except the four authentication endpoints below
requires a valid signed `geointel_session` cookie. Missing, expired or modified
sessions return HTTP 401 with `AUTHENTICATION_REQUIRED`. Direct loopback calls
to the backend without proxy headers remain available to trusted in-container
operator tools; the backend is bound to loopback in the all-in-one runtime.
The runtime stores only a PBKDF2-SHA256 password hash and an independent
session-signing secret. The browser receives an HttpOnly, SameSite=Strict,
time-limited cookie. Five failed attempts for one client/username combination
within five minutes temporarily return HTTP 429 `LOGIN_RATE_LIMITED`.
The runtime stores only a PBKDF2-SHA256 operator password hash and an
independent session-signing secret. The browser receives an HttpOnly,
SameSite=Strict, time-limited cookie. Five failed operator-login attempts for
one client/username combination within five minutes temporarily return HTTP
429 `LOGIN_RATE_LIMITED`.
Optional guest access is a configuration-gated demonstration mode. It creates
a shorter signed session with role `guest`, scopes that session to the
idempotently seeded demo project and blocks mutating operator routes. Project
listing is filtered to the bound demo project. The frontend exposes only the
map and the already calculated quality evidence. This is deliberately **not**
a substitute for user accounts, authorization or tenant isolation; expose it
only on a dedicated demo installation without private or operational data.
### GET `/api/v1/auth/session`
Public session probe used by the frontend before it mounts the workbench.
When authentication is disabled, `authenticated` is true and
`authentication_required` is false so local development retains its existing
direct workflow.
direct workflow. `guest_access_enabled` tells the landing page whether it may
show the guest action.
```json
{
@@ -73,11 +83,18 @@ direct workflow.
"authentication_required": true,
"authenticated": false,
"username": null,
"expires_at": null
"expires_at": null,
"role": null,
"guest_access_enabled": true,
"guest_project_id": null
}
}
```
Authenticated operator sessions return `role: "operator"`. Guest sessions
return `role: "guest"` and the UUID of their bound demo project in
`guest_project_id`.
### POST `/api/v1/auth/login`
```json
@@ -91,6 +108,23 @@ Successful login sets the session cookie and returns the authenticated session
shape. Invalid credentials return HTTP 401 `INVALID_CREDENTIALS`; username
existence is not disclosed.
### POST `/api/v1/auth/guest`
No request body is required. The endpoint is available only when both
`GEOINTEL_AUTH_ENABLED=true` and `GEOINTEL_GUEST_ACCESS_ENABLED=true`. It
idempotently prepares the canonical demo workflow, creates a short-lived guest
session bound to that project and returns the normal session shape.
Disabled guest access returns HTTP 403 `GUEST_ACCESS_DISABLED`. A guest request
for a different project returns HTTP 403 `GUEST_PROJECT_SCOPE_REQUIRED`; a
blocked mutation returns HTTP 403 `GUEST_READ_ONLY`. Unscoped read routes that
are not needed by the demo return HTTP 403 `GUEST_ROUTE_NOT_AVAILABLE`.
Guest reads are limited to the filtered project list, provider metadata and the
bound project tree. A small, explicit set of `POST` selection/read-analysis
routes remains available because those routes query persisted evidence without
exposing operator administration. Coverage resolution additionally verifies
the `project_id` in the request body against the guest-session scope.
### POST `/api/v1/auth/logout`
Clears the browser cookie and returns an unauthenticated session. Logout is