# How it works

Explore plugin boundaries, provisioning, tenant isolation, and integration contracts.


This page explains what happens under the hood of Company Brain: the plugin
layout, how runtimes and workspaces are provisioned, and how access is
enforced. It is written for developers and operators; end users can stay on
the module guides.

## Plugin boundaries

Company Brain is delivered by the `agent` plugin, which pairs a backend API
and a frontend UI:

- `agent_api` — a backend plugin microservice registered with the erxes
  gateway through service discovery. It owns the assistant lifecycle, LLM
  connection management, runtime proxying, Discord gateway integration,
  assistant organization identifiers, and the Postiz module.
- `agent_ui` — a private frontend plugin loaded by the erxes core host via
  Module Federation. It provides the Company Brain navigation, the
  provisioning wizards, chat surfaces, fleet views, Discord sheets, and the
  Social / Postiz page under `/agent/*`.

The plugin follows the standard erxes plugin contract: its backend owns its
data model per tenant subdomain, exposes GraphQL through federation and tRPC
for service-to-service calls, and its frontend remote is consumed by core-ui.
No other plugin's code is imported; shared platform capabilities are used
through public interfaces.

## Module topology

### OpenClaw Assistant

- Each OpenClaw assistant is one managed runtime. The plugin asks the managed
  deployer to provision it; the deployer selects the Kubernetes provisioner
  when enabled and otherwise falls back to the legacy VM provisioner.
- Runtimes are reached only through authenticated runtime endpoints and the
  deployer; health probes gate the chat surface.
- Discord traffic flows through the assistant gateway, which signs tenant and
  assistant identity before it reaches a runtime adapter.

### Hermes Agent

- A separate controller reconciles one isolated Kubernetes namespace per
  Hermes runtime: its own Deployment, Service, Secrets, ConfigMap, and two
  persistent volumes.
- The controller also proxies browser access (minted login URLs, identity
  header injection) and the signed Discord adapter endpoint on the same
  runtime URL.
- Provider API keys and subscription credentials are forwarded into the
  runtime's Kubernetes secrets; they are never persisted by the plugin
  database, logs, or GraphQL responses.

### Social / Postiz

- Postiz is not a per-assistant pod. Your tenant receives a workspace on a
  gateway-assigned Postiz installation, created through an authenticated
  provisioning endpoint.
- erxes-side access is stored in a tenant-owned access record; placement is
  re-checked on every request, and the embedded page rechecks access
  periodically and on tab focus.

## Provisioning chains

### OpenClaw

1. The UI collects the identifier, provider, and credential mode.
2. The plugin creates the identifier inside a Redis quota lock, reserving a
   plan slot before any infrastructure work.
3. `deployManagedAgent` calls the deployer with a deployer-only secret
   header. Deployment waits (up to a 10-minute timeout) for the runtime to
   become ready.
4. The plugin records pending, deploying, approved, or failed state and
   refreshes live gateway tokens for approved runtimes.
5. Retries reuse the stored provider and credential mode unless the caller
   explicitly sends new values.

### Hermes

1. The identifier is created the same way (kind `hermes`).
2. The plugin posts to the deployer's Hermes relay, which forwards to the
   in-cluster controller with its own deployer secret. The controller fails
   closed if its secret is not configured.
3. The controller creates the namespace, volumes, and workload, then waits on
   rollout. Deploys wait up to 10 minutes; other operations return quickly.
4. A shared assistant-runtime secret is delivered through the chain so the
   assistant gateway can verify signed tenant and assistant identity at the
   runtime adapter.

### Postiz

1. The owner's placement request checks active core membership, then sends an
   expiring HMAC assertion to the Postiz gateway.
2. The gateway reserves one instance per tenant and creates the Postiz
   workspace through its authenticated provisioning endpoint; retries return
   the existing placement.
3. The team-access record is initialized with one initial admin; member
   updates use compare-and-set to reject stale concurrent writes.

## Identity, access, and isolation

- **Identifiers** (`assistant_orgs`) carry a name, unique slug, kind
  (`assistant` or `hermes`), description, and member list. Owners see all
  identifiers; other users only those they created or were invited to.
- **Manage operations** — edit, members, deploy, destroy, transfer, plan
  selection — require the owner or creator. View-only members can open the
  runtime and poll health (and mint Hermes login URLs) but nothing else.
- **Tenancy.** Models are scoped per subdomain; every request carries tenant
  context, and Postiz access fails closed across tenants (a user ID from
  another tenant cannot grant access).
- **Secrets handling.** Provider keys pasted in the UI are normalized, used
  transiently, and never persisted in plugin state. Deployer and runtime
  secrets are never returned to clients. Postiz passwords are forwarded once
  and never stored.
- **Quota serialization.** Identifier creation and plan selection run inside
  a short Redis lease keyed per tenant, so concurrent creations cannot
  overbook a plan.

## CMS ↔ Postiz bridge

When a Postiz Admin enables sharing, approved CMS content can be handed to
Postiz through a signed server-to-server chain: `content_api` → `agent_api`
→ Postiz gateway → Postiz. The envelope is signed with a key derived from the
shared JWT secret and carries tenant, user, action, and payload with a Redis
nonce for replay protection. The bridge is not an agent tool and never
exposes the assistant runtime; content_api still enforces its own CMS
permissions.

## What the plugin does not own

- The deployer and controller services (separate components with their own
  deployment) — the plugin only calls their HTTP APIs.
- The runtime pods and Postiz instances themselves.
- Postiz accounts, provider OAuth apps, or email delivery — those remain
  external systems.

Continue to [Setup and Kubernetes](https://erxes.io/docs/company-brain-setup) for deployment
topology and configuration, or back to
[Social / Postiz](https://erxes.io/docs/company-brain-postiz) for the user-facing flow.

