Skip to content

feat(deploy): k8s helm chart + CI for codex-app-gateway + codex-exec-gateway - #82

Open
imryao wants to merge 1 commit into
mainfrom
worktree-codex-gateway-helm
Open

imryao wants to merge 1 commit into
mainfrom
worktree-codex-gateway-helm

Conversation

@imryao

@imryao imryao commented May 12, 2026

Copy link
Copy Markdown
Member

Adds deploy infrastructure for the codex-gateway service trio (env-mcp PR #78, codex-app-gateway PR #79, codex-exec-gateway PR #80) so an operator can `helm install` the chart and have the new services running alongside cc-broker / executor-registry / imbridge.

What's in here

  • 2 new Helm templates following the existing per-service pattern:
    • `templates/codex-app-gateway.yaml` — Secret + Deployment + Service. No Postgres (S3 + sqlite-in-CODEX_HOME). Pulls S3 creds from `existingSecret` (same shape as ccbroker.s3).
    • `templates/codex-exec-gateway.yaml` — Secret + Deployment + Service + Postgres init containers. Same shape as executor-registry.yaml.
  • Shared-secret pattern — single `{{ .Release.Name }}-codex-shared-secret` k8s Secret holds the captoken HMAC + internal-API shared-secret values that both gateways must agree on. Created by codex-app-gateway template (alphabetically first), referenced by name in codex-exec-gateway. `randAlphaNum 48` + `lookup` for stable values across `helm upgrade`.
  • `_helpers.tpl`: `agentserver.codexExecGatewayDatabaseUrl` helper following the same `dig`-safe pattern.
  • `values.yaml`: `codexAppGateway:`, `codexExecGateway:`, `codexShared:` blocks with operator-friendly comments. Both disabled by default.
  • `ingress.yaml`: routes `/codex-app/`, `/codex-exec/`, `/api/codex-exec/` to the respective Services. `/bridge/` and `/api/exec-gateway/` intentionally stay in-cluster only (defense in depth).
  • `Dockerfile.codex-app-gateway`: installs `codex` (npm `@openai/codex`, pinned via `CODEX_VERSION` build-arg, default 0.130.0). Without this, `spawnCodexAppServer()` fails at the first ws connect with `exec: codex: not found`.
  • `.github/workflows/build.yml`: `build-codex-app-gateway` and `build-codex-exec-gateway` jobs (cc-broker pattern). `publish-helm` and `release` `needs:` updated.
  • `Chart.yaml`: 0.47.0 → 0.48.0.

Verification

  • `helm template` renders cleanly with the gateways enabled — 30 resource documents, all expected k8s objects present, ingress paths correct.
  • All Go tests still pass (chart changes don't touch code, but ran the suite for sanity).
  • `go vet` clean.

Operator quickstart (after this lands + PR #81)

```yaml

values.yaml additions

codexAppGateway:
enabled: true
s3:
endpoint: http://minio:9000
region: us-east-1
bucket: codex-app-gateway
pathStyle: true
existingSecret: minio-creds # k8s secret with access_key_id, secret_access_key

codexExecGateway:
enabled: true # uses the in-chart Postgres by default
```

Then enable the chart's ingress with whatever `host:` you want, deploy, and the laptop side runs:

```bash

laptop A — register an executor (needs HMAC token from agentserver auth — see follow-ups)

curl -X POST https://agentserver.example.com/api/codex-exec/register \
-H 'X-User-Id: alice' \
-d '{"display_name":"Alice MacBook","default_cwd":"/home/alice/projects"}'

returns {exe_id, registration_token}; bind to workspace, then:

codex exec-server --remote wss://agentserver.example.com/codex-exec/$EXE_ID \
--executor-id $EXE_ID --auth-token-env CODEX_EXEC_TOKEN

laptop B — connect TUI

export CODEX_APP_TOKEN=$(printf '%s\0%s' ws_alice thr_001 | openssl dgst -sha256 -hmac $INBOUND_HMAC_SECRET | awk '{print "ws_alice.thr_001."$2}')
codex --remote wss://agentserver.example.com/codex-app/ws --remote-auth-token-env CODEX_APP_TOKEN
```

Outstanding pre-deploy items NOT addressed

Spec / Plan

Architecture: `docs/superpowers/specs/2026-05-10-codex-gateway-mcp-rewrite.md` (spec) and `2026-05-10-codex-app-gateway-subprocess.md` (Subsystem 2 refinement). Charts/CI follow this repo's existing per-service pattern (cc-broker, executor-registry).

…gateway

Adds Kubernetes deployment infrastructure for the codex-gateway service
trio (env-mcp PR #78, codex-app-gateway PR #79, codex-exec-gateway PR
#80) so an operator can `helm install` the chart and have the new
services running alongside the existing cc-broker / executor-registry.

- New helm templates: templates/codex-app-gateway.yaml (Deployment +
  Service + Secret with shared S3 + HMAC inbound), templates/codex-exec-gateway.yaml
  (Deployment + Service + Secret with Postgres init container).
- _helpers.tpl: codexExecGatewayDatabaseUrl helper following the
  same shape as ccbrokerDatabaseUrl / executorRegistryDatabaseUrl.
- values.yaml: codexAppGateway:, codexExecGateway:, codexShared: blocks
  (the shared block holds the captoken + internal HMAC secrets that
  both gateways need to match on).
- ingress.yaml: routes /codex-app/, /codex-exec/, /api/codex-exec/
  paths to the respective services. /bridge/ and /api/exec-gateway/
  intentionally stay in-cluster only.
- Dockerfile.codex-app-gateway: installs codex (npm @openai/codex,
  pinned via CODEX_VERSION build-arg, default 0.130.0). Without this,
  spawnCodexAppServer() would fail at runtime with "exec: codex: not
  found".
- .github/workflows/build.yml: build-codex-app-gateway and
  build-codex-exec-gateway jobs (cc-broker pattern); publish-helm and
  release jobs updated to depend on them.
- Chart.yaml: 0.47.0 → 0.48.0.

Operator notes (in values.yaml comments): both gateways disabled by
default; enabling either requires the shared captoken HMAC secret to
match between them (default: chart auto-generates if blank, stable via
existing Secret lookup pattern). codex-app-gateway also requires S3
(same shape as ccbroker.s3); codex-exec-gateway requires Postgres
(reuses the in-chart postgresql or external).

Outstanding pre-deploy items NOT addressed by this PR:
- PR #81 (buildConfig real-ification) must be merged for the spawned
  codex app-server subprocess to actually receive [mcp_servers.exe_*]
  entries; without #81 the LLM sees no executor shell tools.
- HMAC inbound token issuance UX for end users (currently power-user-
  only: hand-mint with the shared secret).
- Wiring revoke-turn on subprocess shutdown.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
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