Bundle Workflows¶
A bundle is a versioned OCI artifact that carries a policy (Rego), optional model
weights, and a manifest.json runtime configuration. This document covers the
full lifecycle using the autonomy bundle command group.
Bundle anatomy¶
my-robot/
├── manifest.json ← schema v1.1 metadata + activation config
└── policies/
└── my_robot_safety.rego ← fail-closed OPA policy
manifest.json (schema v1.1)¶
{
"kind": "bundle",
"schema_version": "1.1",
"name": "ros2-demo",
"version": "0.1.0",
"channel": "dev",
"min_adk_version": "1.0",
"fingerprint": "",
"digest": "",
"cosign_bundle": "",
"policy_ref": "",
"model_ref": "",
"runtime_config": "{\"ros_distro\":\"humble\",\"workspace\":\"/opt/ros/humble\",\"max_velocity\":1.0,\"safety_stop_distance\":0.3}",
"activation": {
"runtime_context": "container",
"policy_ref": "policies/ros2_safety.rego",
"entrypoint": "ros2 launch demo_robot arm_demo.launch.py"
}
}
Key fields:
Field |
Description |
|---|---|
|
Bundle identifier (must be unique within a channel) |
|
Semver string |
|
|
|
Minimum ADK version required to activate this bundle |
|
|
|
Default command run when the bundle is activated |
|
Relative path to the Rego file within the bundle |
Inspect — no registry required¶
Inspect the manifest and policy of a local tarball:
# Summary view
autonomy bundle inspect demo/bundles/ros2.tar --local
# Include the full Rego policy text
autonomy bundle inspect demo/bundles/ros2.tar --local --show-policy
# JSON output (pipe to jq)
autonomy bundle inspect demo/bundles/ros2.tar --local --output json | jq .
Demo tarballs are pre-built at demo/bundles/*.tar and are checked in to the
repository so that inspect and stage work with no registry or build step.
Available demo bundles:
Tarball |
Bundle name |
Context |
Entrypoint |
|---|---|---|---|
|
|
container |
|
|
|
any |
|
|
|
sim |
|
|
|
container |
|
Stage — air-gapped local store¶
Stage a tarball to the local bundle store without any registry:
autonomy bundle stage demo/bundles/ros2.tar
The store location defaults to ~/.local/share/autonomy/bundles/. Override
with --store-dir or the AUTONOMY_BUNDLE_STORE environment variable:
autonomy bundle stage demo/bundles/ros2.tar --store-dir /opt/autonomy/bundles
After staging, list what is in the store:
ls ~/.local/share/autonomy/bundles/
The staged file is an atomic copy (temp file + rename) so partial writes never corrupt the store.
Pull — fetch from an OCI registry¶
# Pull from a registry (writes bundle.tar by default)
autonomy bundle pull registry.example.com/my-robot:stable
# Specify the output path
autonomy bundle pull registry.example.com/my-robot:stable --out ./bundles/my-robot.tar
# Pull from a local insecure registry (automatically detected for localhost)
autonomy bundle pull localhost:5000/ros2-demo:v0.1.0 \
--out ./demo.tar --allow-insecure-registry
The pull command uses the OCI Referrers API (preferred) and falls back to the
<tag>-policy sidecar tag for registries that do not support OCI 1.1.
After pulling, always verify before activating.
Verify — supply-chain integrity¶
autonomy bundle verify registry.example.com/my-robot:stable \
--pub-key demo/keys/cosign.pub
The four-step verification pipeline:
Step |
What is checked |
|---|---|
1 — Signatures |
|
2 — OCI digests |
Live manifest digest vs |
3 — Fingerprint |
BLAKE3 behavioral fingerprint recomputed and compared |
4 — Semver |
Policy bundle version tag vs |
Verification is fail-closed: any step failure exits non-zero. Never activate an unverified bundle on a production node.
Demo keys (no passphrase)¶
# Verify a demo bundle signed with the pre-committed demo key
autonomy bundle verify localhost:5000/ros2-demo:v0.1.0 \
--pub-key demo/keys/cosign.pub
Push and sign — publish a bundle¶
# Sign with the demo key (no passphrase)
autonomy bundle push demo/bundles/ros2.tar \
localhost:5000/ros2-demo:v0.1.0 \
--key demo/keys/cosign.key
bundle push runs:
ORAS attach to push the tarball as an OCI artifact
Pin the content digest into the manifest
cosign signwith the supplied key
The result is an OCI image with a cosign signature attestation attached.
Activate — deploy to edge nodes¶
Bundle activation wires a staged bundle to a running governance runtime. The
activation.entrypoint field in manifest.json defines the command the runtime
executes when the bundle is active.
# The edge daemon picks up staged bundles via AUTONOMY_BUNDLE_STORE
AUTONOMY_BUNDLE_STORE=/opt/autonomy/bundles \
autonomy bundle stage my-robot.tar
# Trigger activation via the orchestrator (requires a running autonomy-orchestrator)
autonomy rollout plan create \
--node my-edge-01 \
--bundle-ref my-robot-bundle:v1.0.0
See the rollout documentation for fleet-wide activation workflows.
Rebuild demo tarballs from source¶
After editing a manifest.json or .rego file, rebuild the tarballs:
./demo/bundles/build.sh
The script uses tar cf to produce deterministic archives from each bundle
directory. Commit the resulting .tar files so that CI and air-gapped
scenarios work without a build step.
See also¶
ROS2 Governance — how the policy gates execution
Gazebo Simulation — demo that loads
gazebo.tarNVIDIA GPU Integration —
nvidia.tarand CDIbundle/— Go package implementing the client and storecmd/autonomy/commands/bundle.go— CLI source