Skip to content

Require operator token for gRPC pause and resume#7

Merged
homerquan merged 1 commit into
mainfrom
codex/propose-fix-for-grpc-vulnerability-371cem
May 18, 2026
Merged

Require operator token for gRPC pause and resume#7
homerquan merged 1 commit into
mainfrom
codex/propose-fix-for-grpc-vulnerability-371cem

Conversation

@homerquan

Copy link
Copy Markdown
Collaborator

Motivation

  • The PauseJob and ResumeJob gRPC RPCs previously allowed unauthenticated clients to change job lifecycle state, creating an availability/control vulnerability.
  • The change adds a minimal operator-auth guard to ensure only callers possessing an operator token can invoke these state-changing RPCs.

Description

  • Add MirrorNeuron.Grpc.Auth which reads MN_GRPC_OPERATOR_TOKEN and provides authorize_operator!/1 and authorized?/2 to validate bearer or MirrorNeuron-specific token headers with a constant-time compare.
  • Gate PauseJob and ResumeJob handlers by calling MirrorNeuron.Grpc.Auth.authorize_operator!(stream) before invoking MirrorNeuron.pause/1 or MirrorNeuron.resume/1.
  • Update README.md to document the new MN_GRPC_OPERATOR_TOKEN configuration key.
  • Add focused unit tests in tests/unit/grpc/auth_test.exs that exercise header extraction (including adapter/http request headers) and token matching behavior.

Testing

  • Ran mix format --check-formatted, which succeeded.
  • Ran the new tests directly with elixir -r lib/mirror_neuron_grpc/auth.ex -e 'ExUnit.start()' tests/unit/grpc/auth_test.exs, and they completed with 0 failures.
  • mix test could not be run to completion in this environment because Hex/dependency fetches failed (network/proxy prevented mix local.hex / dependency installation).

Codex Task

@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: 574a6ac2d2

ℹ️ 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".


def pause_job(request, _stream) do
def pause_job(request, stream) do
MirrorNeuron.Grpc.Auth.authorize_operator!(stream)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Protect all destructive gRPC controls with the token

When MN_GRPC_OPERATOR_TOKEN is set and the gRPC listener is reachable, this guard only protects PauseJob/ResumeJob; in the same server CancelJob and ClearJobs still call MirrorNeuron.cancel/1 and Monitor.clear_jobs/0 without authorize_operator!/1, and ClusterServer.remove_node/1 is likewise unguarded. Those RPCs are at least as destructive as pause/resume, so the new token gives operators a false sense that control RPCs are protected while unauthenticated clients can still cancel or delete job state.

Useful? React with 👍 / 👎.

@homerquan homerquan merged commit fba68a4 into main May 18, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant