Oduflow dashboard and shared IDE¶
Oduflow opens Dashboard, with Customers, Instances, and IDE tiles. Customers opens the contact directory in customer mode. Instances opens the existing client instance action. IDE opens a shared development environment containing one project per client instance.
Access and projects¶
The shared IDE is an administrative environment spanning the control inventory.
Opening it requires both Oduflow Admin and Settings / Administration
(base.group_system). Observer users retain access to the dashboard, contacts and
instance views, but cannot enter the shared IDE.
The tile starts a signed, single-use login with a 30-second lifetime. The browser posts the ticket to the IDE; tickets are never placed in URL query parameters. The gateway sets a host-only, Secure, HttpOnly session cookie lasting one hour. Launch nonces and the gateway signing identity survive container restarts. The Odoo signing key is encrypted using the existing control-plane encryption key; only its public verification key is supplied to the IDE container. Opening the gateway directly without a session asks the user to enter through Odoo.
Every minute the IDE service requests the inventory using its own signed request. Odoo trusts an explicitly registered service public key. The inventory supplies only each instance's own repository deploy key, never platform-wide GitHub tokens. Repositories are cloned at their confirmed branch, using pinned GitHub host keys. Instances whose repository grant is not ready receive a project directory until the repository can be imported. An existing nonempty directory is never replaced by a clone. Removed instances' repository keys are removed from the service; their working copies are retained for administrator review.
Each project lives at /data/home/projects/<slug>. Registration is idempotent;
existing origins and ownership receipts are checked. Synchronization never pulls,
resets or cleans a working copy, and preserves uncommitted changes. These are
central working copies of client repositories. Client VM files and running client
services are managed separately through the existing instance operations.
The IDE runtime is Oduflow IDE 0.8.0, built on the target server from
oduflow/paseo commit 3f3555c5a64e9bbffa139c1482c691757a2a5a25. Agent provider
authentication is configured in the IDE separately; a repository deploy key does not authorize an AI provider.
Deployment¶
Use the configured Oduflow MCP for the selected control environment:
- Commit and push the code, then
pull_and_apply(upgrade="oduflow")for the first installation. Later Python-only changes require restart, and new fields/data require upgrade. - Create
control-ide-configandcontrol-ide-datanamed volumes. Copy the committeddocker/control-ide/andsalt/states/control_ide/trees to the configuration volume, preserving their repository-relative paths. - In Odoo shell, call
odoo.addons.oduflow.ide.initialize_signing_key(env)and setoduflow.ide_urlto the HTTPS origin. The initializer returns only the public key. Supply its base64-encoded PEM asODUFLOW_CONTROL_PUBLIC_KEY. - Create the
control-ideservice using the pinned Node image below, port 8080, commandsh /config/docker/control-ide/start.sh, and mountscontrol-ide-config:/config:ro,control-ide-data:/data. - Supply
ODUFLOW_IDE_URL,ODUFLOW_CONTROL_PUBLIC_URL,ODUFLOW_CONTROL_URL(the trusted internal Odoo HTTP endpoint), andODUFLOW_CONTROL_HOST(its public virtual host). Do not expose Odoo's internal endpoint outside the team network. - Read
/data/home/service-public-key.pemfrom the service and register it in Odoo asoduflow.ide_service_public_key. This file is public key material. - Wait for
/healthto reportready: true, then verify actual dashboard navigation and both project names in the IDE browser interface.
Pinned image:
The container installs Salt 3006.27 with the resolved dependency versions in
docker/control-ide/salt-requirements.txt. The control_ide Salt state manages
runtime files, builds the pinned source and its workspace packages using the source
lockfile, and pins GitHub SSH host keys. Salt's job and pillar caches are disabled. The daemon listens only on loopback and has
relay connectivity disabled; all browser HTTP and WebSocket traffic passes
through the authenticated gateway. It runs as the unprivileged node user.
For updates, deliver the committed configuration tree and restart control-ide.
The bootstrap reapplies Salt and installs changed dependency locks. The source
build lives in /data/releases/<version>-<commit>; /data/current selects the
release only after the build succeeds. Its build.json records the full commit,
source lockfile checksum and Node version. Existing releases are retained.
To build ahead of a restart, run python3 /config/docker/control-ide/build.py
inside the service. This builds alongside the running release. Then deliver the
updated Salt/gateway files and restart the service to select the completed build.
Keep the data volume: it contains working copies, daemon state and the trusted service identity.
Recreating that volume requires registering a new service public key.
Verification¶
ruff check addons salt scripts testsruff format --check addons salt scripts testsnode --test tests/test_control_ide.cjs- Odoo tests:
/oduflow:TestOduflowDashboard(post-install). - Browser: all three tiles, desktop/mobile layout, SSO and project navigation.
- Service: unsigned HTTP/WebSocket denial, signed inventory, project registration, idempotent Salt application, and preservation of uncommitted files after restart.