Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
2ae5aa8
chore(submodules): bump 5 services to develop HEAD
gomessguii Jul 20, 2026
aee4ac4
Merge pull request #167 from evolution-foundation/chore/bump-submodul…
gomessguii Jul 20, 2026
1e2cdb1
chore(EVO-2178): ship MEDIA_HOST_ALLOWLIST on every deploy surface
gomessguii Jul 21, 2026
2c348e4
Merge pull request #168 from evolution-foundation/fix/EVO-2178-media-…
gomessguii Jul 21, 2026
2920720
docs(readme): correct "no super-admin" in the monorepo README — the r…
pastoriniMatheus Aug 18, 2026
f765c37
docs(readme): state what the role model does NOT enforce (CRM-180)
gomessguii Aug 18, 2026
56f16c5
Merge pull request #173 from evolution-foundation/docs/CRM-180-super-…
gomessguii Aug 18, 2026
52e2381
chore: bump evo-ai-crm-community to develop head + wire EVO_AI_ENCRYP…
gomessguii Aug 20, 2026
cc29e0a
chore(submodules): bump the remaining stale services to their develop…
gomessguii Aug 20, 2026
cd5f1b5
Merge pull request #174 from evolution-foundation/chore/bump-crm-comm…
gomessguii Aug 20, 2026
69a4961
fix(compose): stop pinning AI_CALL_TIMEOUT_SECONDS=30 over the code d…
pastoriniMatheus Aug 22, 2026
122ce73
chore(submodules): bumpa os seis servicos atrasados ate os heads da d…
gomessguii Aug 23, 2026
5130c5c
chore(submodules): bumpa crm, frontend, flow, core e auth ate os head…
gomessguii Aug 26, 2026
f675987
chore(submodules): bumpa crm, frontend e core da community
gomessguii Aug 28, 2026
6b31254
Merge pull request #179 from evolution-foundation/chore/bump-ponteiro…
gomessguii Aug 28, 2026
62f75e2
docs: remove internal review notes from the public repo
gomessguii Aug 28, 2026
42b15ee
Merge pull request #180 from evolution-foundation/chore/remove-intern…
gomessguii Aug 28, 2026
504f71d
chore: drop the internal review stack from the repo
gomessguii Aug 29, 2026
de087c5
Merge pull request #182 from evolution-foundation/chore/drop-internal…
gomessguii Aug 29, 2026
6748602
chore(submodules): bump the family to the v1.1.0 release heads
gomessguii Sep 2, 2026
a600604
fix(swarm): pin evo-flow to :latest like every other service in the s…
gomessguii Sep 2, 2026
5ca8e7a
Merge pull request #184 from evolution-foundation/release/v1.1.0-bump
gomessguii Sep 2, 2026
e9e51c9
docs(changelog): add v1.1.0 release section
gomessguii Sep 2, 2026
3c19c2d
Merge pull request #185 from evolution-foundation/docs/changelog-v1.1.0
gomessguii Sep 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ REDIS_PASSWORD=evoai_redis_pass
SECRET_KEY_BASE=a]i9F#k2$$Lm7Nq0R!sT4uW6xZ8bD1eG3hJ5oP7rV9yAcE2fH4jM6pS8vX0zB3dK5nQ7tU9wY1
JWT_SECRET_KEY=a]i9F#k2$$Lm7Nq0R!sT4uW6xZ8bD1eG3hJ5oP7rV9yAcE2fH4jM6pS8vX0zB3dK5nQ7tU9wY1

# Used by: core-service, processor (API key encryption)
# Used by: core-service, processor (API key encryption); compose feeds it to the
# CRM as EVO_AI_ENCRYPTION_KEY (AI credentials)
ENCRYPTION_KEY=XoQPOBw2FrzjQS11utERG9qO2MsAnXFxlhIns_uUxRk=

# Used by: auth, crm, processor (service-to-service authentication)
Expand Down Expand Up @@ -220,7 +221,9 @@ APP_URL=http://localhost:8011
LISTEN_ADDR=0.0.0.0:8080
BOT_RUNTIME_SECRET=evo-bot-runtime-dev-secret
AI_PROCESSOR_API_KEY=evo-processor-dev-api-key
AI_CALL_TIMEOUT_SECONDS=30
# CRM-236: um turno com tool faz duas chamadas ao modelo e a cauda do
# provedor mede ~20s cada. Valor explicito aqui anula o default do codigo.
AI_CALL_TIMEOUT_SECONDS=90

# Bot Runtime integration (used by CRM service to connect to bot-runtime)
BOT_RUNTIME_URL=http://evo-bot-runtime:8080
Expand Down Expand Up @@ -309,3 +312,8 @@ VITE_TINYMCE_API_KEY=no-api-key

# # OpenAI (for AI-powered features)
# OPENAI_API_KEY=

# Host(s) allowed to serve incoming media to the AI agent, comma-separated,
# no scheme or port. Must match the host of BACKEND_URL above (that is what
# signs the attachment URLs); without it the agent receives no media.
MEDIA_HOST_ALLOWLIST=localhost
9 changes: 8 additions & 1 deletion .env.swarm.example
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
# placeholders: SUBDOMAIN_API / SUBDOMAIN_FRONTEND (your domains),
# every empty secret (SECRET_KEY_BASE, JWT_SECRET_KEY, EVOAI_CRM_API_TOKEN,
# DOORKEEPER_JWT_SECRET_KEY, ENCRYPTION_KEY, BOT_RUNTIME_SECRET — same
# value everywhere it appears), the Postgres password, and SMTP/S3 if used.
# value everywhere it appears; ENCRYPTION_KEY also fills the CRM's
# EVO_AI_ENCRYPTION_KEY), the Postgres password, and SMTP/S3 if used.
# 2. Create the external network/volumes and a pgvector Postgres (see the
# header of docker-compose.swarm.yaml for the full dependency list).
# 3. Deploy:
Expand Down Expand Up @@ -39,6 +40,7 @@ EVOAI_CRM_API_TOKEN=CHANGE_ME
BOT_RUNTIME_SECRET=CHANGE_ME

# Generate with: python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
# Also goes into crm/crm_sidekiq as EVO_AI_ENCRYPTION_KEY (AI credentials).
ENCRYPTION_KEY=CHANGE_ME

# =============================================================================
Expand Down Expand Up @@ -85,3 +87,8 @@ MFA_ISSUER=EvoCRM
SIDEKIQ_CONCURRENCY=10
ACTIVE_STORAGE_SERVICE=local
ORGANIZATION_NAME=Evo CRM

# Host(s) que servem a midia recebida ao agente, separados por virgula, sem
# esquema nem porta. Deve casar com o host do BACKEND_URL (quem assina a URL
# do anexo); sem isso o agente nao recebe midia. Ex.: crm.seudominio.com
MEDIA_HOST_ALLOWLIST=
97 changes: 94 additions & 3 deletions CHANGELOG.md

Large diffs are not rendered by default.

21 changes: 19 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,28 @@ The Evo CRM Community platform is composed of 6 independent services:
### Design principles (Community Edition)

- **Single-tenant** — one account, no multi-tenancy overhead
- **No super-admin** — all configuration via seed data and environment variables
- **No billing / plans** — all limits removed, features unlocked by default
- **Role hierarchy**: `account_owner` and `agent` — no intermediate roles
- **Configuration via seed data and environment variables** — with one exception: installation-level settings (SMTP, Storage, Social Login, OpenAI, Channels, Inbound Email, Frontend Runtime) live in the database, behind `installation_configs.manage`
- **Role hierarchy** — three seeded roles (`agent`, `account_owner`, `super_admin`), plus any custom role created at runtime — see [Roles](#roles)
- **Account resolution** via token — no `account-id` header required between services

#### Roles

`db/seeds/rbac.rb` in [`evo-auth-service-community`](./evo-auth-service-community) is the authoritative role model. It seeds three roles:

| Role | Scope | Permissions |
|---|---|---|
| `agent` | account | Attendance only — conversations, contacts, pipeline cards. Sees only the inboxes it is a member of |
| `account_owner` | account | The whole catalog except `accounts.stats` and `installation_configs.manage` |
| `super_admin` | installation | The whole catalog, including `installation_configs.manage` — the only role that renders Admin Settings and reaches `/api/v1/installation_configs/**` |

Two facts a security review needs, because neither is enforced by the code:

- **`super_admin` has no single-holder guarantee.** The setup wizard grants it to the user it creates, and the `PromoteFirstUserToSuperAdmin` migration grants it to the oldest user of an already-bootstrapped installation. Nothing prevents it being assigned to more — audit `user_roles` for the `super_admin` role key instead of assuming one installation owner.
- **The seeded three are not the whole set.** `account_owner` holds `roles.create` and `roles.bulk_update_permissions`, so custom roles with arbitrary permission sets can be created at runtime via `POST /api/v1/roles`.

`Role::ADMIN_ROLE_KEYS` (defined in `evo-ai-crm-community`, mirrored in auth and the frontend) is an admin-bypass allowlist, not the role model: it also names legacy `administrator`/`admin` keys the seed never creates, and the three copies disagree.

### Companion services (independent versioning)

The following services are part of the Evolution Foundation ecosystem but are not pinned to the Evo CRM release tag:
Expand Down
13 changes: 10 additions & 3 deletions docker-compose.swarm.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
## - JWT_SECRET_KEY .......... auth, auth_sidekiq, crm, crm_sidekiq, core
## - EVOAI_CRM_API_TOKEN ..... auth, auth_sidekiq, crm, crm_sidekiq, processor
## - DOORKEEPER_JWT_SECRET_KEY auth, auth_sidekiq
## - ENCRYPTION_KEY .......... core, processor
## - ENCRYPTION_KEY .......... core, processor; crm + crm_sidekiq (como EVO_AI_ENCRYPTION_KEY)
## - BOT_RUNTIME_SECRET ...... crm, crm_sidekiq, bot_runtime
## - AUTH_APIKEY_INTEGRATION_LOCAL crm, crm_sidekiq, evoflow
## - CLICKHOUSE_PASSWORD ..... clickhouse, evoflow
Expand Down Expand Up @@ -238,6 +238,7 @@ services:
- SECRET_KEY_BASE= # Mesmo valor de SECRET_KEY_BASE usado nos demais serviços
- JWT_SECRET_KEY= # Mesmo valor de JWT_SECRET_KEY usado nos demais serviços
- EVOAI_CRM_API_TOKEN= # Mesmo valor de EVOAI_CRM_API_TOKEN usado nos demais serviços
- EVO_AI_ENCRYPTION_KEY= # Mesma chave Fernet do ENCRYPTION_KEY (core/processor) — cifra credenciais de IA

## 🗄️ PostgreSQL
- POSTGRES_HOST=pgvector
Expand Down Expand Up @@ -316,6 +317,7 @@ services:
- SECRET_KEY_BASE= # Mesmo valor de SECRET_KEY_BASE usado nos demais serviços
- JWT_SECRET_KEY= # Mesmo valor de JWT_SECRET_KEY usado nos demais serviços
- EVOAI_CRM_API_TOKEN= # Mesmo valor de EVOAI_CRM_API_TOKEN usado nos demais serviços
- EVO_AI_ENCRYPTION_KEY= # Mesma chave Fernet do ENCRYPTION_KEY (core/processor) — cifra credenciais de IA

## 🗄️ PostgreSQL
- POSTGRES_HOST=pgvector
Expand Down Expand Up @@ -487,7 +489,12 @@ services:
## 🤖 Processor e segurança
- AI_PROCESSOR_URL=http://evocrm_processor:8000
- BOT_RUNTIME_SECRET= # Mesmo valor de BOT_RUNTIME_SECRET usado no evocrm_crm e evocrm_crm_sidekiq
- AI_CALL_TIMEOUT_SECONDS=30
# CRM-236: um turno com tool faz duas chamadas ao modelo e a cauda do
# provedor mede ~20s cada. Valor explicito aqui anula o default do codigo.
- AI_CALL_TIMEOUT_SECONDS=90
- MEDIA_HOST_ALLOWLIST= # Host(s) que servem a midia recebida, separados por virgula, sem esquema nem porta.
# Use o host do BACKEND_URL do CRM (o que assina a URL do anexo); sem isso o agente nao recebe midia.
# Ex.: "crm.seudominio.com".

deploy:
placement:
Expand Down Expand Up @@ -604,7 +611,7 @@ services:
## e roda as migrations. O banco do CRM (evocrm) não é tocado.
## O swarm ignora depends_on → o boot espera o ClickHouse por conta própria.
evocrm_evoflow:
image: evoapicloud/evo-flow-community:develop
image: evoapicloud/evo-flow-community:latest
command:
- sh
- -c
Expand Down
8 changes: 8 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ services:
POSTGRES_HOST: postgres
EVO_AUTH_SERVICE_URL: http://evo-auth:3001
EVO_AI_CORE_SERVICE_URL: http://evo-core:5555
# Same Fernet key core/processor read as ENCRYPTION_KEY; the CRM encrypts AI credentials with it.
EVO_AI_ENCRYPTION_KEY: ${ENCRYPTION_KEY:-XoQPOBw2FrzjQS11utERG9qO2MsAnXFxlhIns_uUxRk=}
BOT_RUNTIME_URL: http://evo-bot-runtime:8080
BOT_RUNTIME_SECRET: ${BOT_RUNTIME_SECRET:-evo-bot-runtime-dev-secret}
BOT_RUNTIME_POSTBACK_BASE_URL: http://evo-crm:3000
Expand Down Expand Up @@ -175,6 +177,8 @@ services:
POSTGRES_HOST: postgres
EVO_AUTH_SERVICE_URL: http://evo-auth:3001
EVO_AI_CORE_SERVICE_URL: http://evo-core:5555
# Same Fernet key core/processor read as ENCRYPTION_KEY; the CRM encrypts AI credentials with it.
EVO_AI_ENCRYPTION_KEY: ${ENCRYPTION_KEY:-XoQPOBw2FrzjQS11utERG9qO2MsAnXFxlhIns_uUxRk=}
BOT_RUNTIME_URL: http://evo-bot-runtime:8080
BOT_RUNTIME_SECRET: ${BOT_RUNTIME_SECRET:-evo-bot-runtime-dev-secret}
BOT_RUNTIME_POSTBACK_BASE_URL: http://evo-crm:3000
Expand Down Expand Up @@ -288,6 +292,10 @@ services:
REDIS_URL: redis://:${REDIS_PASSWORD:-evoai_redis_pass}@redis:6379
AI_PROCESSOR_URL: http://evo-processor:8000
BOT_RUNTIME_SECRET: ${BOT_RUNTIME_SECRET:-evo-bot-runtime-dev-secret}
# Hosts allowed to serve incoming media. Must cover the host the CRM signs
# attachment URLs with (ACTIVE_STORAGE_URL, or BACKEND_URL when unset), or
# the agent receives no media at all.
MEDIA_HOST_ALLOWLIST: ${MEDIA_HOST_ALLOWLIST:-localhost}
depends_on:
redis:
condition: service_healthy
Expand Down
Loading
Loading