Skip to content

chore: bump OAuth Codex submodules + harden grupomirandas swarm#27

Closed
NeritonDias wants to merge 18 commits intoEvolutionAPI:mainfrom
NeritonDias:test/all-fixes-v2
Closed

chore: bump OAuth Codex submodules + harden grupomirandas swarm#27
NeritonDias wants to merge 18 commits intoEvolutionAPI:mainfrom
NeritonDias:test/all-fixes-v2

Conversation

@NeritonDias
Copy link
Copy Markdown

Summary

This PR is the monorepo counterpart of the OAuth Codex refactor split into three reviewable PRs. It:

  1. Bumps the processor + frontend submodule pointers to the corrected PKCE implementations.
  2. Fixes the grupomirandas Swarm stack so OAuth requests actually reach the processor and no longer leak secrets.
  3. Supersedes #14, which will be closed as part of this change.

Submodule pointers

Submodule Before After
evo-ai-processor-community 688eaf5 a6fc98d (upstream PR)
evo-ai-frontend-community 2a3e397 c70ad83 (upstream PR)

docker-compose.grupomirandas.yml

  • Gateway image: switched from evoapicloud/evo-crm-gateway:develop (upstream, no /api/v1/agents/oauth route) to ghcr.io/neritondias/evo-gateway:test — the custom gateway built by .github/workflows/build-test.yml that carries the nginx location sending OAuth traffic to the processor. With the upstream image in place, every OAuth call was falling through to the core service and returning 404.
  • VITE_WS_URL added to the frontend service env. The frontend image's docker-entrypoint.sh only rewrites a VITE_* placeholder when the matching env var is present; without this, VITE_WS_URL_PLACEHOLDER was leaking into the JS bundle and the ActionCable socket never connected.
  • All hardcoded shared secrets replaced by ${VAR} placeholders: SECRET_KEY_BASE, JWT_SECRET_KEY, DOORKEEPER_JWT_SECRET_KEY, EVOAI_CRM_API_TOKEN, ENCRYPTION_KEY, BOT_RUNTIME_SECRET, POSTGRES_PASSWORD, SMTP_PASSWORD (plus the embedded password in the processor's POSTGRES_CONNECTION_STRING). The previous values are in the public git history and must be rotated in Postgres and at the SMTP provider.

New file: .env.grupomirandas.example

Documents every variable the stack expects, how to generate each one, and which services consume it. The real .env stays gitignored.

Test plan

  • docker stack deploy -c docker-compose.grupomirandas.yml (or equivalent Portainer deploy) succeeds when the 9 env vars from .env.grupomirandas.example are provided
  • curl https://api-crm.grupomirandas.com.br/api/v1/agents/oauth/codex/auth-start (with valid JWT) reaches the processor, not the core service
  • Browser loads https://crm.grupomirandas.com.br, WebSocket connects to wss://api-crm.grupomirandas.com.br/cable, no VITE_WS_URL_PLACEHOLDER in the bundle
  • OAuth Codex sign-in end-to-end: agent created with model="chatgpt/gpt-5.4" replies using the ChatGPT subscription
  • Rotated secrets applied at Postgres, SMTP, and anywhere else the old values were copied

Supersedes

Closes #14 — that PR used device-code + openai/ remapping, which does not work against LiteLLM (the openai/ provider does not speak the ChatGPT backend API). This 3-PR split uses PKCE + the native chatgpt/ provider shipped in LiteLLM 1.83.3.

NeritonDias and others added 18 commits April 16, 2026 13:23
…-35030)

Adds OAuth Codex (OpenAI) as an alternative authentication method for AI
providers in Evo CRM, allowing ChatGPT Plus/Pro subscribers to use GPT-5.x
models without a separate API key. Includes critical LiteLLM security upgrade.

Backend:
- Alembic migration: auth_type + oauth_data columns on api_keys table
- OAuth device code flow service with thread-safe token refresh
- 4 new REST endpoints under /agents/oauth/codex/*
- Model remapping: chatgpt/ -> openai/ prefix with custom api_base

Frontend:
- New provider "ChatGPT (OAuth)" with 10 GPT-5.x models
- OAuthDeviceCodeFlow and OAuthStatusBadge components
- ApiKeysDialog conditional UI for OAuth vs API key

Security:
- LiteLLM upgrade v1.68.0 -> v1.83.3 (fixes CVE-2026-35030 OIDC bypass)
- Supply chain attack mitigation (v1.82.7/v1.82.8 compromised Mar 2026)
- 22 integration tests, 3-agent debug sweep with 10 findings fixed

Docs: OAUTH-CODEX-pt-BR.md + OAUTH-CODEX-en.md
- bash→sh Alpine compatibility fix (EvolutionAPI#22)
- Role select dropdown fix via frontend submodule (EvolutionAPI#17)
- OAuth Codex implementation docs (from main)
- .gitmodules switched to HTTPS for CI compatibility
- Frontend submodule points to NeritonDias fork with role fix
- Added build-test.yml workflow for Docker image builds
Docker Compose configured for grupomirandas.com.br deployment using
test images from ghcr.io/neritondias/* built from test/all-fixes branch.
Includes bash→sh fix for evocrm_auth and frontend with role select fix.
- Frontend: OAuth device code flow UI + OpenAI modal tabs (API Key / OAuth)
- Processor: OAuth service, token refresh, 4 endpoints + internal token endpoint
- CRM: Audio transcription with OAuth support (Whisper via ChatGPT subscription)
…essor + build gateway image

The 404 was caused by two issues:
1. oauth_routes.py was not registered in processor main.py
2. nginx gateway routes /api/v1/agents/* to Core service, not Processor

Fixes:
- Register oauth_router in processor main.py
- Change router prefix to /agents/oauth/codex
- Add nginx location for /api/v1/agents/oauth -> processor
- Add gateway to build workflow
The nginx.conf had hardcoded service names (evo_crm, evo_auth, etc.) but
Swarm services use different names (evocrm_crm, evocrm_auth, etc.).

Fix: replace hardcoded names with env vars (AUTH_UPSTREAM, CRM_UPSTREAM,
etc.) and use nginx:alpine templates dir for automatic envsubst at startup.
…vars

The previous approach used nginx templates dir which runs envsubst on ALL
variables, destroying nginx internals like \, \, etc.

Fix: use explicit envsubst with only the 5 upstream variables listed.
…ecrets

docker-compose.grupomirandas.yml:
- Point evocrm_gateway at ghcr.io/neritondias/evo-gateway:test (the
  custom gateway built by .github/workflows/build-test.yml) instead of
  evoapicloud/evo-crm-gateway:develop. The custom image carries the
  /api/v1/agents/oauth nginx location that routes OAuth requests to
  the processor. With the upstream image in place, every OAuth call
  was falling through to the core service and returning 404.
- Add VITE_WS_URL=wss://api-crm.grupomirandas.com.br/cable to the
  frontend service env. The frontend image's docker-entrypoint.sh
  only rewrites VITE_* placeholders when the matching env var is
  present; without this, VITE_WS_URL_PLACEHOLDER leaked into the JS
  bundle at runtime and the ActionCable socket never connected.
- Replace every hardcoded shared secret (SECRET_KEY_BASE,
  JWT_SECRET_KEY, DOORKEEPER_JWT_SECRET_KEY, EVOAI_CRM_API_TOKEN,
  ENCRYPTION_KEY, BOT_RUNTIME_SECRET, POSTGRES_PASSWORD, SMTP_PASSWORD)
  with ${VAR} placeholders so Docker Swarm / Portainer interpolates
  them from the stack env-file. The previous values are leaked in the
  public git history and MUST be rotated at the postgres server, at
  the SMTP provider, and at any external system that holds them.

.env.grupomirandas.example:
- New file documenting every variable the grupomirandas stack expects,
  how to generate each one, and which services consume it. The real
  .env stays gitignored as today.
The processor service read POSTGRES_CONNECTION_STRING rather than the
individual POSTGRES_* pieces, and the connection string still embedded
the raw password. Rewrite the string to use ${POSTGRES_PASSWORD} so
no credential stays in the YAML.
evo-ai-processor-community: 688eaf5 → a6fc98d (feat/oauth-codex-v2)
  - chore(deps): bump litellm 1.68.2 → 1.83.3 (CVE-2026-35030, supply chain)
  - fix(oauth): security hardening + align with Codex CLI spec
    (state validation, SELECT FOR UPDATE, scopes, plan_type, env constants)

evo-ai-frontend-community: 2a3e397 → c70ad83 (feat/oauth-codex-v2)
  - fix(oauth): validate callback origin, code, state, and errors in browser
  - fix: use account.id as clientId in OAuthStatusBadge (not apiKey.id)
Copy link
Copy Markdown

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Sorry @NeritonDias, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

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.

2 participants