bus integration podman
Overview
bus integration podman is the Podman runtime integration worker. It handles the
bus.podman.* Events namespace and is normally used behind
bus integration containers, which translates the
public bus.containers.* contract to a selected backend such as bus.podman.*.
The module also provides Go helpers for rootless Podman bootstrap and run scripts. Cloud modules that need Podman on remote nodes should reuse those helpers instead of constructing Podman shell scripts themselves.
Usage
Before starting this worker, run a Bus Events API and export BUS_API_TOKEN
for every process that publishes or listens on the event path. With the
default bus.podman.* backend prefix, the Podman worker listens for request
events and publishes response events, so the token must include events:send
and events:listen. If the same token is reused for the provider-neutral
router, the containers API provider, or bus containers, include
container:read, container:run, container:delete, and container:admin
for the protected public bus.containers.* events.
Podman must be installed locally, or --podman-bin/PODMAN_BIN must point to
the executable.
For a local memory-backed Events API, start:
BUS_EVENTS_JWT_SECRET=not-a-secret-local-development-hs256-key \
bus-api-provider-events --addr 127.0.0.1:8081 --events-backend memory
Mint BUS_API_TOKEN with the same HS256 secret plus Events scopes. The
container scopes in this example let the same token exercise the full router
and API-provider path; a standalone Podman backend on the default unprotected
prefix only needs the Events scopes unless the deployment protects
bus.podman.* with a custom ACL:
mkdir -p ./local
BUS_AUTH_HS256_SECRET=not-a-secret-local-development-hs256-key \
bus operator token issue --local \
--subject podman-worker-local \
--audience ai.hg.fi/api \
--scope 'events:send events:listen container:read container:run container:delete container:admin' \
--ttl 12h \
--format token > ./local/podman-worker.token
Run a local Podman worker:
export BUS_API_TOKEN="$(cat ./local/podman-worker.token)"
bus-integration-podman \
--provider podman \
--events-url http://127.0.0.1:8081 \
--event-prefix bus.podman
Run the provider-neutral router in a separate terminal or service with the same
BUS_API_TOKEN, Events URL, and backend prefix:
export BUS_API_TOKEN="$(cat ./local/podman-worker.token)"
bus-integration-containers \
--provider events \
--events-url http://127.0.0.1:8081 \
--backend-event-prefix bus.podman
To verify through the public CLI, run the containers API provider in a third terminal against the same Events API:
export BUS_API_TOKEN="$(cat ./local/podman-worker.token)"
bus-api-provider-containers \
--addr 127.0.0.1:8080 \
--backend events \
--events-url http://127.0.0.1:8081
Use --provider static only for deterministic help/self-test checks. Use
--provider podman for real container runs; it calls the executable selected
by --podman-bin or PODMAN_BIN, defaulting to podman.
Verify local behavior without a real Podman host:
bus-integration-podman --self-test
bus-integration-podman --events --format json
The self-test prints bus-integration-podman self-test OK, and the event
metadata includes bus.podman.run.request.
For the full router path, start both long-running workers and then send a public container run through the containers API:
export BUS_AI_API_URL=http://127.0.0.1:8080
export BUS_API_TOKEN="$(cat ./local/podman-worker.token)"
bus containers run --profile codex -- sh -lc 'printf OK'
The codex profile is resolved by the Podman worker from
--container-codex-image or PODMAN_CONTAINER_CODEX_IMAGE, defaulting to
docker.io/library/alpine:3.20. A working router plus Podman backend returns a
successful run response containing OK; the router maps the public
bus.containers.run.request to bus.podman.run.request.
Events
The default Events API ACL protects public bus.containers.* events with
container domain scopes and leaves the backend bus.podman.* prefix as a
deployment-local integration prefix. For the default backend prefix, listening
uses events:listen and publishing uses events:send. If an operator adds a
specific ACL for bus.podman.*, grant the domain scopes mapped by that
deployment instead.
| Direction | Event | Default Events scope |
|---|---|---|
| listens | bus.podman.status.request |
events:listen |
| sends | bus.podman.status.response |
events:send |
| listens | bus.podman.run.request |
events:listen |
| sends | bus.podman.run.response |
events:send |
| listens | bus.podman.delete.request |
events:listen |
| sends | bus.podman.delete.response |
events:send |
| listens | bus.podman.runner.status.request |
events:listen |
| sends | bus.podman.runner.status.response |
events:send |
| listens | bus.podman.runner.start.request |
events:listen |
| sends | bus.podman.runner.start.response |
events:send |
| listens | bus.podman.runner.delete.request |
events:listen |
| sends | bus.podman.runner.delete.response |
events:send |
Safety
Podman can still mutate local host state and pull/run arbitrary images. Deploy this worker only in trusted runtime environments and rely on Bus API/Event authorization to restrict who may publish run and runner lifecycle requests.
Using from .bus files
Inside a .bus file, write the module target without the bus prefix:
# same as: bus integration podman --provider podman --events-url "$BUS_EVENTS_API_URL" --event-prefix bus.podman
integration podman --provider podman --events-url "$BUS_EVENTS_API_URL" --event-prefix bus.podman
The shell or service that runs the .bus file still needs BUS_API_TOKEN with
the same Events permissions as the equivalent CLI command.