handlers

package
v0.64.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 20, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package handlers contains HTTP handler functions for the codex-exec gateway. It must not import the parent codexexecgateway package to avoid import cycles; shared DTOs are imported from execmodel instead.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CloudRegister added in v0.50.7

func CloudRegister(store CloudRegisterStore, publicWSBaseURL string, validator AgentserverValidator, wsTicketSecret string) http.HandlerFunc

CloudRegister handles POST /cloud/executor/{exe_id}/register.

Auth: codex 0.132+ schemes only — Bearer (ChatGPT access_token) or AgentAssertion (Agent Identity), validated via agentserver. The pre-0.132 bcrypt registration_token bearer is gone (PR removing it).

On success, mints a short-lived HMAC ws ticket and returns `wss://.../codex-exec/{exe_id}?token=<ticket>`. The inbound ws handler verifies the ticket signature locally — no DB hop, no JWT verify, no validator round-trip.

publicWSBaseURL is the externally-visible wss:// origin (e.g. "wss://codex-exec.agent.cs.ac.cn:443"). When empty, the response URL is synthesised from r.Host with wss scheme — best-effort fallback for dev / direct in-cluster use.

func Connected

func Connected(store InternalConnectedStore, reg Registry) http.HandlerFunc

Connected returns the intersection of (workspace's bound executors) ∩ (currently-connected exe_ids). Used by codex-app-gateway when composing the per-turn manifest.

func DeleteBinding

func DeleteBinding(store BindingStore) http.HandlerFunc

DeleteBinding returns an http.HandlerFunc that removes a workspace ↔ executor binding.

func DeleteExecutor added in v0.59.1

func DeleteExecutor(store Store) http.HandlerFunc

DeleteExecutor handles DELETE /api/codex-exec/executors/{exe_id}. Idempotent — absent id returns 204 same as present. Surfaces 500 only on DB error.

func ListBinding

func ListBinding(store BindingStore, online OnlineSet) http.HandlerFunc

ListBinding returns an http.HandlerFunc that lists all executors bound to a workspace, annotated with IsOnline from the live registry so the UI doesn't have to guess from last_seen_at.

func MintWSTicket added in v0.64.0

func MintWSTicket(exeID, secret string) (string, error)

MintWSTicket returns a short-lived bearer that authorizes the `/codex-exec/{exe_id}?token=...` ws upgrade. Format:

<exe_id>.<expiry_unix>.<base64url(HMAC-SHA256(secret, "<exe_id>.<expiry>"))>

The inbound handler recomputes the HMAC with its own secret and confirms the exe_id matches and the expiry is in the future. No DB round-trip; no bcrypt; no JWT verification.

func PostBinding

func PostBinding(store BindingStore) http.HandlerFunc

PostBinding returns an http.HandlerFunc that binds an executor to a workspace.

func Register

func Register(store Store) http.HandlerFunc

Register returns an http.HandlerFunc that creates a new executor row and returns its id. The codex 0.132 bcrypt registration_token path is gone — auth on /cloud/.../register now goes through Agent Identity JWT or ChatGPT access_token validated by agentserver, and the inbound ws verifies a short-lived HMAC ticket minted at register time. So this endpoint no longer mints any per-executor bearer.

func RequireAgentserverSecret added in v0.50.7

func RequireAgentserverSecret(secret string) func(http.Handler) http.Handler

RequireAgentserverSecret rejects requests whose X-Internal-Secret header does not constant-time-match `secret`. When `secret` is empty, this middleware is a no-op (dev mode).

This is separate from RequireSharedSecret because the two represent different trust scopes:

  • RequireSharedSecret → cap-token admin API (called by codex-app-gateway via CXG_INTERNAL_SHARED_SECRET)
  • RequireAgentserverSecret → user-management API (called by agentserver on behalf of session-authenticated humans, via CXG_AGENTSERVER_INTERNAL_SECRET)

func RequireSharedSecret

func RequireSharedSecret(secret string) func(http.Handler) http.Handler

RequireSharedSecret rejects requests whose Authorization: Bearer header does not constant-time-match `secret`.

func RevokeTurn

func RevokeTurn(rev RevokedAdder) http.HandlerFunc

RevokeTurn adds a turn_id to the in-memory revoked set so future bridge connect attempts presenting that turn's CODEX_EXEC_GATEWAY_TOKEN are rejected even within the token's exp window.

func VerifyWSTicket added in v0.64.0

func VerifyWSTicket(ticket, expectedExeID, secret string) error

VerifyWSTicket returns nil iff the ticket is well-formed, signed with `secret`, names the expected exe_id, and has not yet expired.

Types

type AgentserverValidator added in v0.62.3

type AgentserverValidator struct {
	BaseURL        string // e.g. "http://agentserver.agentserver.svc:8080"
	InternalSecret string
	HTTPClient     *http.Client // optional; nil → default with 5s timeout
}

AgentserverValidator calls agentserver's /internal/codex-auth/validate to verify codex 0.132 Bearer / AgentAssertion auth on cloud register.

func (*AgentserverValidator) Validate added in v0.62.3

func (v *AgentserverValidator) Validate(ctx context.Context, req map[string]string) (userID string, err error)

Validate POSTs the request body to agentserver and returns the resolved user_id, or an error if validation fails.

type BindingStore

type BindingStore interface {
	BindWorkspaceExecutor(ctx context.Context, workspaceID, exeID, name, description string, isDefault bool) error
	UnbindWorkspaceExecutor(ctx context.Context, workspaceID, exeID string) error
	ListWorkspaceExecutors(ctx context.Context, workspaceID string) ([]execmodel.ConnectedExecutor, error)
}

BindingStore is the subset of storage required by the workspace binding handlers.

type CloudRegisterStore added in v0.50.7

type CloudRegisterStore interface{}

CloudRegisterStore is the subset of *codexexecgateway.Store the upstream-compat /cloud/executor/{id}/register handler needs. Ownership lookup is asserted via the ownerStore type-assertion in assertExeOwnedByUser; pure CloudRegister callers only need the empty interface here, which we keep as a sentinel for future shared methods.

type InternalConnectedStore

type InternalConnectedStore interface {
	ConnectedExecutorsForWorkspace(ctx context.Context, workspaceID string, connectedIDs []string) ([]execmodel.ConnectedExecutor, error)
}

InternalConnectedStore is the subset of storage required by Connected.

type OnlineSet added in v0.62.3

type OnlineSet func() map[string]struct{}

OnlineSet reports whether an exe_id has a live inbound ws right now. The gateway's ConnRegistry satisfies this via a tiny adapter in server.go. Defined here as a func type so the handler stays loosely coupled.

type Registry

type Registry interface {
	ConnectedIDs() []string
}

Registry is satisfied by *codexexecgateway.ConnRegistry.

type RevokedAdder

type RevokedAdder interface {
	Add(turnID string, exp int64) (evictedLive bool)
}

RevokedAdder is satisfied by *codexexecgateway.RevokedSet.

type Store

type Store interface {
	CreateExecutor(ctx context.Context, e execmodel.Executor) error
	DeleteExecutor(ctx context.Context, exeID string) error
}

Store is the subset of storage required by the register handler.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL