Skip to content

Authenticate inference endpoints in-process; add secure_remote/modal_remote configs#451

Open
vertix wants to merge 8 commits into
Positronic-Robotics:mainfrom
vertix:inference-endpoint-auth
Open

Authenticate inference endpoints in-process; add secure_remote/modal_remote configs#451
vertix wants to merge 8 commits into
Positronic-Robotics:mainfrom
vertix:inference-endpoint-auth

Conversation

@vertix

@vertix vertix commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Summary

Authenticated access to served inference endpoints, on by default. Auth is enforced in the server,
not at the Nebius ingress: a live test showed Nebius --auth token gates plain HTTP but drops the
inference WebSocket upgrade
(/api/v1/session → 404 even with a valid token), so it can't protect
the actual inference path. Instead VendorServer validates the bearer token itself, and endpoints are
served open at the Nebius layer.

  • In-process auth (default on): VendorServer reads AUTH_TOKEN from the environment and validates
    Authorization: Bearer <token> on the HTTP route (/api/v1/models) and the WebSocket routes
    (/api/v1/session[/{model_id}]) — constant-time compare, rejecting a missing/invalid token on the WS
    before accept(). Absent token ⇒ open server. Read once in the base class, so no per-vendor churn.
  • serve.sh: injects the token as the container's AUTH_TOKEN via --env-secret
    (NEBIUS_AUTH_TOKEN_SECRET, default positronic-serverless-inference-token), replacing --auth token.
    NEBIUS_AUTH_TOKEN_SECRET= serves an open endpoint; e2e.sh opts out for its smoke check.
  • Two client policy configs over remote that attach the auth header from the environment, so
    callers pass only --policy.host:
    • .secure_remoteAuthorization: Bearer from POSITRONIC_INFERENCE_TOKEN (our Nebius endpoints, HTTP :8000)
    • .modal_remoteModal-Key/Modal-Secret from MODAL_PROXY_TOKEN_ID/MODAL_PROXY_TOKEN_SECRET, TLS :443
    • Each raises immediately if its environment variable is unset.
  • Docs: the bearer-token secret joins the one-time setup; workflows/nebius/README.md and the
    remote-training skill describe the in-process-auth flow.
  • Also includes a small unrelated CLAUDE.md tweak (allow autonomous commits; prefer fewer test files).

Test plan

Verified:

  • Auth logic (local): FastAPI TestClient matrix — authed server rejects missing/wrong token (HTTP 401,
    WS rejected) and accepts a valid token (HTTP 200, WS → ready); open server passes through. Regression
    cases added to test_vendor_server.py exercise the same over real uvicorn + websockets.
  • Full suite: pytest --no-cov → 598 passed, 7 skipped. ruff check/format clean; bash -n clean.
  • Live Nebius control: deployed an open endpoint — raw WS upgrade → 101 and real
    InferenceClient.new_session() → ready. A prior authed (--auth token) endpoint showed tokenless
    HTTP → 401, authed HTTP → 200, but authed WS → 404 — confirming the ingress drops the WS upgrade.

Not verified (needs an image rebuild + deploy): the --env-secret AUTH_TOKEN= injection inside a live
Nebius container — it mirrors the existing, working --env-secret AWS_ACCESS_KEY_ID= line.

Both wrap `remote` with an auth header read from the environment, so callers pass only
the host: `.secure_remote` sends `Authorization: Bearer` from `POSITRONIC_INFERENCE_TOKEN`;
`.modal_remote` sends `Modal-Key`/`Modal-Secret` from `MODAL_PROXY_TOKEN_ID`/`MODAL_PROXY_TOKEN_SECRET`
on TLS :443. `serve.sh` gains opt-in Nebius `--auth token` via `NEBIUS_AUTH_TOKEN_SECRET`;
`workflows/nebius/README.md` documents the flow.
Comment thread workflows/nebius/README.md Outdated
Comment thread workflows/nebius/README.md
Comment thread workflows/nebius/README.md Outdated
vertix added 3 commits June 23, 2026 18:01
`serve.sh` defaults `NEBIUS_AUTH_TOKEN_SECRET` to `positronic-serverless-inference-token`, so
endpoints require `Authorization: Bearer <token>`; `NEBIUS_AUTH_TOKEN_SECRET=` opts out. `e2e.sh`
opts out for its smoke check; docs and the remote-training skill switch to `.secure_remote`.
@vertix vertix changed the title Add secure_remote and modal_remote authenticated inference configs Authenticate inference endpoints in-process; add secure_remote/modal_remote configs Jun 25, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6512580b30

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread workflows/nebius/README.md Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3b7a946d67

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread positronic/offboard/vendor_server.py Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c7d93149d8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread positronic/cfg/policy.py

# Our own Nebius endpoints answer plain HTTP on :8000 and validate the bearer token in-process.
# Front them with TLS instead by adding --policy.secure=True --policy.port=443.
secure_remote = remote.override(headers=bearer_headers)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Require TLS before sending bearer tokens

When callers follow the new .secure_remote guidance for public Nebius endpoints, this preset inherits remote's secure=False / port 8000 defaults while adding Authorization: Bearer .... That sends the long-lived POSITRONIC_INFERENCE_TOKEN over plain HTTP/WebSocket, so anyone on the client-to-endpoint path can capture and replay it against the public ingress; require TLS for the authenticated preset or avoid recommending bearer-token auth on http:// endpoints.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid concern, but the literal remedy is not applicable to these endpoints, and I want to leave this open for a human call rather than resolve it.

Nebius serverless AI endpoints are bare public IPs over plain HTTP with no TLS (confirmed in the docs: the endpoint exposes a public_ip, every example is http://<ip>, and there is no certificate/hostname; a live test also showed the --auth token proxy drops the inference WebSocket upgrade). Consequences:

  • Requiring secure=True on .secure_remote would make it speak wss:///https:// to an endpoint that only serves plain HTTP, so it could no longer reach the endpoints it exists for.
  • "Don't use bearer-on-http" isn't an option either: bearer-on-http is the only mechanism that authenticates a Nebius endpoint at all, which is the entire purpose of this change.

So the real hardening is fronting the endpoint with a TLS terminator (hostname + cert), which is separate infrastructure work, out of scope for this PR. What I did land (139af3c) is to make the exposure explicit at the config site rather than silently recommend cleartext bearer. The token is also rotatable (see the README rotation recipe). Leaving this open as a documented known limitation pending a decision on whether to add TLS fronting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant