Overview
OpenClaw-env-manager is a Python CLI for defining an OpenClaw agent environment in one
declarative openclawenv.toml file and turning it into deterministic Docker
artifacts.
When run without arguments, the CLI opens an interactive terminal menu for bot management.
It is inspired by Poetry's manifest-plus-lock workflow:
openclawenv.tomldescribes intentopenclawenv.lockcaptures deterministic build inputsclawopenenv scanruns an optional preflight security scan for materialized skillsclawopenenv export dockerfilerenders a standalone Dockerfileclawopenenv export composerenders a bot-specific docker-compose fileclawopenenv buildbuilds the image and enforces a build-time skill scan gate
Table Of Contents¶
- CI And Coverage
- Releases And PyPI
- Documentation
- Host Prerequisites
- Windows
- macOS
- Linux
- Notes
- V1 Scope
- Security Notes
- Manifest Shape
- CLI
- Makefile
- Interactive Bot Menu
- Generated Image Contents
- Tests
CI And Coverage¶
GitHub Actions runs the test suite for every push to main, every pull request,
and on manual dispatch. A separate coverage job runs the tests under
coverage.py, uploads the raw reports as workflow artifacts, validates the
MkDocs build, and publishes the generated MkDocs site to GitHub Pages for
pushes to main. The same deployed Pages site also contains the HTML coverage
report plus the generated coverage badge.
Once GitHub Pages is enabled for the repository with Build and deployment
configured to GitHub Actions, the
published docs site is available at
fipciu1996.github.io/OpenClaw-env-manager/,
while the coverage report stays under
fipciu1996.github.io/OpenClaw-env-manager/coverage/.
Releases And PyPI¶
Package publication to PyPI is handled by
.github/workflows/publish-pypi.yml.
The release workflow is intentionally narrow:
- it runs only on pushed release tags matching
1.2.3orv1.2.3 - it verifies that the tag version matches
[project].versioninpyproject.toml - it builds both
sdistandwheel - it checks the generated distributions with
twine - it publishes to PyPI through Trusted Publishing with GitHub OIDC
Example release tag:
make install-hooks
make release-tag VERSION=1.0.1 TAG_MESSAGE="OpenClaw-env-manager 1.0.1"
git push origin 1.0.1
Git does not provide a native pre-tag hook, so OpenClaw-env-manager uses a practical
replacement:
python .github/scripts/create_release_tag.py <tag>ormake release-tag VERSION=<tag>updatespyproject.tomlandCHANGELOG.md, creates a release commit, and only then creates the annotated tag.githooks/pre-pushverifies that every pushed release tag still matches the package version and blocks the push when they diverge- changelog entries are managed through
changelog-cli, which is installed as part of.[dev]
To activate the repository-managed hooks locally:
make install-hooks
Useful changelog-cli commands:
changelog entry added --message "Describe a new feature"
changelog entry changed --message "Describe a behavior change"
changelog entry fixed --message "Describe a bug fix"
changelog current
Once the package is published, installation from PyPI is:
python -m pip install OpenClaw-env-manager
On Debian and Ubuntu systems with PEP 668 enabled, direct installation into
the system Python may fail with externally-managed-environment. The safest
installation options for the published CLI are:
pipxfor a standalone CLI install:
apt update
apt install -y pipx python3-venv
pipx install OpenClaw-env-manager
~/.local/bin/clawopenenv --help
virtualenvfor an isolated Python environment:
apt update
apt install -y python3-venv
python3 -m venv /opt/openclaw-env-manager
source /opt/openclaw-env-manager/bin/activate
pip install -U pip
pip install OpenClaw-env-manager
clawopenenv --help
The installed console command is:
clawopenenv
Before the first release, configure a PyPI Trusted Publisher for:
- owner:
fipciu1996 - repository:
OpenClaw-env-manager - workflow:
.github/workflows/publish-pypi.yml
Documentation¶
Project documentation is generated with MkDocs + mkdocstrings and uses the
mkdocs-shadcn theme. The docs/
directory holds narrative pages, while the API reference is generated directly
from the internal Python package implementation. The MkDocs config also uses a
small local hook so the shadcn theme does not require global Git
safe.directory changes just to build docs.
The docs also include a dedicated reference page for the generated
openclawenv.toml structure, including the top-level sections, field meanings, and
managed-bot file layout.
Install the docs toolchain:
python -m pip install -e .[docs]
Build the docs locally:
python -m mkdocs build --strict
Run the local preview server:
python -m mkdocs serve
Equivalent make shortcuts:
make install-docs
make docs-build
make docs-serve
The latest documentation is also published from GitHub Actions directly through
the repository's GitHub Pages workflow on pushes to main.
Versioned documentation publishing remains configured for GitLab Pages in
.gitlab-ci.yml. The GitLab deployment model is:
- default branch: published at the root Pages URL
- other branches: published under
branch-<ref-slug>/ - tags: published under
tag-<ref-slug>/
This setup uses GitLab Pages parallel deployments through pages.path_prefix.
According to the current GitLab documentation, that feature is available on
GitLab Premium and Ultimate. Branch previews are configured to expire after
30 days, while the default-branch and tag deployments are kept indefinitely.
Host Prerequisites¶
Before using OpenClaw-env-manager on a workstation or CI runner, install:
- Docker with
docker composesupport - Python
3.12+withpip - optionally
git - optionally
makeon Linux/macOS if you want to use the providedMakefile
Quick verification:
docker version
docker compose version
python --version
python -m pip --version
Expected result: Docker CLI is available, docker compose works, and Python is
at least 3.12.
Windows¶
- Install Docker Desktop for Windows: official Docker Desktop for Windows guide.
- Prefer the WSL 2 backend. Docker's current documentation requires WSL
2.1.5+and a supported Windows 10/11 build. - Install Python
3.12+from python.org/downloads or through the Python Install Manager described in the official Windows documentation. - Restart the terminal and verify:
wsl --version
docker version
docker compose version
python --version
macOS¶
- Install Docker Desktop for Mac: official Docker Desktop for Mac guide.
- Install Python
3.12+from python.org/downloads. The official macOS installer is auniversal2build and works on both Apple Silicon and Intel Macs. - See the official Python on macOS guide for installer details and shell path setup.
- Verify:
docker version
docker compose version
python3 --version
python3 -m pip --version
Linux¶
- Install Docker Engine from the official Docker Engine install overview and pick your distribution-specific page there. If you prefer Docker Desktop and your distro is supported, see the official Docker Desktop for Linux guide.
- For common distros, Docker maintains dedicated instructions for Ubuntu and Debian, and the install overview links the rest of the supported platforms.
- Check whether your distro already ships Python
3.12+:
python3 --version
- If your distro Python is older than
3.12, use a newer distro package or install CPython from the latest source release published on python.org/downloads, following the official Unix installation guide. - Verify:
docker version
docker compose version
python3 --version
python3 -m pip --version
Notes¶
- OpenClaw-env-manager assumes a Docker environment with Compose available as
docker compose. - On Linux, the Python executable is often
python3rather thanpython. - Docker Desktop licensing can require a paid subscription in larger commercial organizations; check Docker's current terms before rolling it out company-wide.
V1 Scope¶
OpenClaw-env-manager v1 is intentionally narrow:
- OpenClaw-first
- Python-first
- one inline manifest
- Docker image output
- secret references only
- no session or auth state snapshotting
The current locker accepts exact Python requirements only:
package==versionname @ URL
It also accepts exact Node.js requirements only:
package@version@scope/package@version
That constraint keeps the lockfile deterministic without shipping a full Python dependency resolver in v1.
OpenClaw-env-manager can also integrate with Cisco's Skill Scanner, which the upstream project describes as a best-effort scanner for agent skills with static, behavioral, and optional LLM-based analysis.
Five catalog skills are treated as always installed defaults across manifests, managed bots, and generated images:
deus-context-engineself-improving-agentskill-security-reviewfreeride(free-rideinside the workspace)agent-browser-clawdbot
Security Notes¶
OpenClaw-env-manager follows a secure-by-default model, but it does not silently override explicit operator intent. Secure defaults are applied to newly generated manifests and artifacts, while consciously weaker settings remain available and are surfaced as non-blocking security advisories.
Existing default mechanisms include:
read_only_root = truefor newly generated OpenClaw sandbox configuration- localhost-only binds for generated gateway and bridge ports
cap_drop: [ALL],no-new-privileges:true, read-only root filesystems,tmpfs,pids_limit, andulimitsin generated Compose services- sidecar
.envfiles for secrets so sensitive values are not baked into images - build-time and preflight skill scanning with
cisco-ai-skill-scanner - mandatory baseline skills that keep operational and security guardrails present
- warnings when the operator chooses riskier settings such as wildcard tool
policies,
shell_commandallowlists, unpinned base images, public host binds, or writable root filesystems
The default image/runtime baseline also includes a fixed starter set of skills and tools:
- mandatory skills:
deus-context-engine,self-improving-agent,skill-security-review,freeride, andagent-browser-clawdbot - default tooling in the image:
chromium,node,npm,npx,agent-browser, andcisco-ai-skill-scanner
That baseline is meant to make generated images immediately usable for OpenClaw execution, browser automation, and skill security checks, while still allowing the operator to add more Python, Node.js, and system dependencies through the manifest.
Important boundary:
- these defaults reduce common mistakes, but they do not replace host-level
hardening. Docker daemon access,
docker.sockmounts, firewalling, rootless Docker, user namespaces, seccomp/AppArmor/SELinux, and patch management still need to be handled operationally.
The baseline is aligned with the
OWASP Cheat Sheet Series,
especially the
Docker Security Cheat Sheet
and the
AI Agent Security Cheat Sheet.
There is also a dedicated Security Notes page in this documentation set.
Manifest Shape¶
openclawenv.toml contains five top-level sections:
projectruntimeagentskillsopenclaw
Example:
schema_version = 1
[project]
name = "ops-agent"
version = "1.2.3"
description = "Deterministic OpenClaw image for operations support"
runtime = "openclaw"
[runtime]
base_image = "python:3.12-slim"
python_version = "3.12"
system_packages = ["git", "curl", "chromium"]
python_packages = ["requests==2.32.3", "rich==13.9.4"]
node_packages = ["typescript@5.8.3"]
env = { PYTHONUNBUFFERED = "1" }
user = "agent"
workdir = "/workspace"
[[runtime.secret_refs]]
name = "OPENAI_API_KEY"
source = "env:OPENAI_API_KEY"
required = true
[agent]
agents_md = """# Agent Contract"""
soul_md = """# Soul"""
user_md = """# User"""
memory_seed = ["Remember the operating model."]
[[skills]]
name = "incident-brief"
description = "Prepare concise incident reports."
content = """
---
name: incident-brief
description: Prepare concise incident reports.
---
"""
[openclaw]
agent_id = "main"
agent_name = "Operations Agent"
[openclaw.sandbox]
mode = "workspace-write"
scope = "session"
workspace_access = "full"
network = "bridge"
read_only_root = true
The agent section supports both inline markdown content and relative .md
file references. For example, agents_md = "AGENTS.md" will load
AGENTS.md from the same directory as openclawenv.toml.
Even if they are not declared manually, OpenClaw-env-manager normalizes manifests so that
deus-context-engine, self-improving-agent, skill-security-review,
freeride, and agent-browser-clawdbot remain present in the effective skill
set. openenv init writes them explicitly into the starter manifest.
Security-sensitive defaults are also generated automatically:
- read_only_root = true for the OpenClaw sandbox by default
- explicit openclaw.tools.allow / deny lists by default, while risky
wildcard or broad tool scopes remain possible as explicit operator choices
and are surfaced as security warnings
- localhost-only host port bindings in generated Compose files
- cap_drop: [ALL], no-new-privileges, read-only root filesystems, tmpfs,
and process/file descriptor limits in generated Compose services
These defaults are intentionally aligned with the
OWASP Cheat Sheet Series,
especially the official
Docker Security Cheat Sheet
and
AI Agent Security Cheat Sheet.
OpenClaw-env-manager uses them as the baseline for generated images, Compose
stacks, tool scoping, and agent runtime guardrails. The project keeps a
secure-by-default posture without silently overriding explicit operator intent:
if a manifest or runtime override weakens the baseline, validate, export,
and build flows emit clear non-blocking security warnings instead of
preventing the change outright.
CLI¶
Create a starter manifest:
clawopenenv init
Open the interactive bot menu:
clawopenenv
Validate the manifest:
clawopenenv validate
Generate the lockfile:
clawopenenv lock
Run a skill security scan:
clawopenenv scan -- --policy strict --fail-on-severity high
Build the image with a stricter build-time scan policy:
clawopenenv build --scan-policy strict --scan-fail-on-severity medium
Export the Dockerfile:
clawopenenv export dockerfile --output Dockerfile
Export the bot compose file:
clawopenenv export compose
clawopenenv export compose also writes a sibling Dockerfile, so the generated
compose bundle can rebuild the bot image locally without any extra wiring.
Build the image:
clawopenenv build
clawopenenv build also writes a compose file named after the bot, for example
docker-compose-operations-agent.yml, next to the manifest.
When runtime.base_image is not pinned with @sha256, OpenClaw-env-manager first checks
for the image locally and automatically tries docker image pull <image> if it
is missing before failing lock generation.
Module-oriented execution is also available through:
python -m clawopenenv
Makefile¶
Common workflows are also available through Makefile targets:
make install
make install-dev
make install-scan
make test
make coverage
make coverage-html
make menu
make validate
make lock
make scan SCAN_ARGS="-- --policy strict --fail-on-severity high"
make dockerfile
make compose
make build
You can override defaults, for example:
make lock MANIFEST=examples/demo.openclawenv.toml LOCKFILE=examples/demo.openclawenv.lock
make dockerfile DOCKERFILE=build/Dockerfile
make build TAG=openclawenv/demo:dev
Interactive Bot Menu¶
Running clawopenenv without parameters opens a menu that lets you:
- choose Polish or English as the interface language on entry
- list managed bots
- from the bot selection screen, generate a shared stack at
bots/all-bots-compose.ymlwith one gateway and one bot service per managed bot - open a listed bot and generate
openclawenv.lock,Dockerfile, and bot-specificdocker-composeartifacts - open a listed bot and improve its
*.mddocuments through OpenRouter tool calling, with the resulting markdown normalized to consistent English - list running bots launched from
bots/<bot-slug>/docker-compose-*.yml - open a running bot and preview recent container logs
- open a running bot and create a skill snapshot, which inspects installed
skills in the running container and updates
openclawenv.tomlwith any new discoveries - add a new bot by answering interactive questions about role, skill sources, dependencies, secrets, sites, and databases
- the interactive skill prompt only asks for additional skills, because
deus-context-engine,self-improving-agent,skill-security-review,freeride, andagent-browser-clawdbotare always included automatically - edit an existing bot and rewrite its stored manifest data
- delete an existing bot together with its stored manifest data
Managed bots are stored under bots/<bot-slug>/openclawenv.toml.
For bots created from the interactive menu, secret refs are stored in
bots/<bot-slug>/.env instead of [[runtime.secret_refs]] blocks inside the
manifest. Agent documents are stored as sibling markdown files such as
bots/<bot-slug>/AGENTS.md, SOUL.md, USER.md, IDENTITY.md, TOOLS.md,
and memory.md, while the manifest keeps only relative references to those
files. The OpenRouter-backed document improvement action looks for
OPENROUTER_API_KEY in the system environment first and then in the project
root .env. If the key is missing and the action is selected, the menu prompts
for it and writes OPENROUTER_API_KEY=... to the project root .env.
Generated Image Contents¶
The generated image writes:
- the OpenClaw gateway/runtime itself by building on top of
alpine/openclaw:main, so the resulting image can actually runnode dist/index.js gateway - the OpenClaw workspace files such as
AGENTS.md,SOUL.md, andUSER.md - inline skills under
<workspace>/skills/<skill-name>/ - a generated
openclaw.json - copies of
openclawenv.tomlandopenclawenv.lockunder/opt/openclawenv - Python plus Node.js tooling available in the image, including
node,npm, andnpx - exact
runtime.node_packagesinstalled globally withnpm install --global - the
agent-browserCLI installed globally by default, followed byagent-browser installduring image build so the browser runtime is prepared - the
cisco-ai-skill-scanner==2.0.4CLI installed in the image for in-container skill scanning - Python packages installed into an image-local virtual environment under
/opt/openclawenv/.venv, which keeps Docker builds compatible withPEP 668system Python protections - the
freerideskill installed from ClawHub into the real OpenClaw workspace and exposed through~/.openclaw -> /opt/openclaw, sofreeride autoupdates the sameopenclaw.jsonused by the container - a build-time
skill-scanner scan-allgate against<workspace>/skills, usingbalancedpolicy and failing onhighseverity by default
runtime.base_image is still preserved and pinned in openclawenv.lock, but it is
used as the sandbox/agent image inside the generated openclaw.json, not as
the outer gateway container base.
The tool can also generate a bot-specific OpenClaw-style compose file with
openclaw-gateway and openclaw-cli services, host-mounted config/workspace
directories, and a bot-specific env file such as .operations-agent.env. The
gateway service includes a build: section that rebuilds the local image from
the adjacent generated Dockerfile, and both services use the resulting tag
through OPENCLAW_IMAGE. When a canonical sidecar bots/<bot-slug>/.env file
exists, its secret values are merged into the generated compose env file
together with OpenClaw defaults such as image tag, ports, bind mode, and
workspace paths. The generated openclaw-cli service stays alive with an idle
entrypoint by default, so docker compose up -d does not exit immediately into
the OpenClaw help screen; run interactive commands with
docker compose exec openclaw-cli openclaw ....
When clawopenenv scan is used, the CLI materializes skills to a temporary
directory and runs skill-scanner scan-all ... --recursive against that tree
as a local preflight check. During docker build, the generated Dockerfile also
runs skill-scanner scan-all <workspace>/skills --recursive --check-overlap,
so the image build fails when findings meet the configured severity threshold.
For already running bot containers, the interactive menu can also create a
skill snapshot by inspecting <workspace>/skills inside the container and
merging any newly discovered skills back into the bot manifest.
When freeride is present, the Docker build also runs
npx clawhub@latest install free-ride before the skill scan gate. For manual
local installation inside an existing OpenClaw workspace, use:
npx clawhub@latest install free-ride
cd ~/.openclaw/workspace/skills/free-ride
pip install -e .
After container start,
set OPENROUTER_API_KEY and run freeride auto followed by
openclaw gateway restart if you want FreeRide to rewrite the active
OpenClaw model configuration.
By default, Docker builds also run npm install -g agent-browser and
agent-browser install to prepare browser automation, while the mandatory
agent-browser-clawdbot skill documents how agents should use that tool.
When using the exported Dockerfile directly, you can override the defaults with
Docker build args such as OPENCLAWENV_SKILL_SCAN_POLICY=strict,
OPENCLAWENV_SKILL_SCAN_FORMAT=json, and
OPENCLAWENV_SKILL_SCAN_FAIL_ON_SEVERITY=medium. Use --keep-artifacts if you
want to inspect the materialized skill bundle in .openclawenv-scan/.
Example GitHub Actions step for the exported Dockerfile:
- name: Build OpenClaw-env-manager image with skill scan gate
run: |
docker build \
--file Dockerfile \
--tag openclawenv/agent:ci \
--build-arg OPENCLAWENV_SKILL_SCAN_POLICY=strict \
--build-arg OPENCLAWENV_SKILL_SCAN_FAIL_ON_SEVERITY=medium \
.
Secrets are never baked into the image. Sensitive values must be supplied at
runtime through the generated .<bot-name>.env file.
Tests¶
Run the built-in unittest suite:
python -m unittest discover -s tests -t . -v
Generate a terminal coverage report:
python -m coverage run -m unittest discover -s tests -t . -v
python -m coverage report -m
Generate the HTML report under htmlcov/:
make coverage-html