Skip to content

config-plane: /v1/config 'app' selector is ungated while org/model require a token #1102

Description

@mdheller

Found in my adversarial review of session work (Copilot also flagged it on #1029, now merged).

GET /v1/config (compute-gateway server.py) gates scoped reads like this:

if (model or org) and authorization.removeprefix("Bearer ").strip() != GATEWAY_TOKEN:
    raise HTTPException(status_code=401, detail="scoped config reads require a token")

org and model are token-gated (fixed during #1029 review — they were the original tenancy leak). But app is also a scope selector (def config_snapshot(app: str = "noetica", ...)config_plane.get_snapshot(app=app, ...)) and is not gated. If app namespaces tenant- or product-sensitive flags and multiple apps exist, a caller can enumerate other apps' snapshots by guessing app names, unauthenticated.

The open question (threat model — Michael's call)

Is app a tenant/customer dimension (→ must be token-gated like org/model) or just the requesting product/binary name (noetica vs socioprophet-web — public, correctly open)?

  • If tenant-sensitive: gate app when it differs from a safe default, same pattern as org/model.
  • If public product name: document it as deliberately-open in the endpoint docstring so this doesn't get re-flagged.

The default scope must stay open regardless (a client that can't reach the plane needs its last-cached snapshot — gating the common read deepens an outage). This is only about the app selector.

Not fixed in code yet because it changes a merged auth decision and depends on the threat-model answer. Relates to the config-plane tenancy fixes in #1029.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions