Skip to content

grafvonb/c8volt

Repository files navigation

c8volt logo

c8volt

Camunda 8 Operations CLI for workflows that must actually finish.

done is done

If an action needs retries, waiting, tree traversal, state checks, or cleanup before it is truly finished, c8volt should do that work for you instead of making you script the last mile yourself.

c8volt is not just a CRUD shell around Camunda 8 APIs. It is a CLI shaped around operational intent:

  • start a process and confirm it is really active
  • cancel a child process by finding the root that must actually be cancelled
  • delete a process instance family thoroughly, not partially
  • deploy BPMN models and use them immediately

Standard read/list/get commands still matter, but they are not the headline. The headline is operational confidence.

At A Glance

best for:
  deploy + run + verify
  inspect process trees
  cancel safely
  delete thoroughly
  wait for the state you actually need

also includes:
  cluster topology and license inspection
  effective config rendering and validation
  embedded BPMN fixture export
  process definition XML retrieval
  resource lookup by id
  tenant-aware operations

Why It Feels Different

Many CLIs stop at "request accepted."

c8volt is designed for the moments after that:

  • Did the process instance actually reach ACTIVE?
  • Did the cancellation propagate through the whole family?
  • Did deletion remove the tree, not just one visible node?
  • Is the deployment already usable for the next command?

That is the gap c8volt closes.

Signature Workflows

1. Bootstrap a local environment fast

Deploy bundled BPMN fixtures directly from the binary:

./c8volt embed list
./c8volt embed deploy --all
./c8volt embed deploy --all --run

This is the quickest path from "clean environment" to "real process instances to inspect and operate on."

2. Start and confirm, not just start

./c8volt get pd --latest
./c8volt run pi -b C88_SimpleUserTask_Process

By default, c8volt waits until the process instance is actually active. If you explicitly want asynchronous behavior:

./c8volt run pi -b C88_SimpleUserTask_Process --no-wait

For batch execution:

./c8volt run pi -b C88_SimpleUserTask_Process -n 100 --workers 8

3. Understand the tree before you change it

./c8volt walk pi --key 2251799813711967 --family
./c8volt walk pi --key 2251799813711967 --family --tree

This is where c8volt becomes an operations tool instead of just a resource browser: it helps you see the structure that explains why a cancellation or deletion may behave the way it does.

4. Cancel the thing that actually needs cancelling

Camunda may reject a direct cancellation of a child instance when the real action must happen at the root.

./c8volt cancel pi --key 2251799813711977
./c8volt cancel pi --key 2251799813711977 --force

With --force, c8volt escalates from the selected child to the root process instance and waits for the family-level outcome.

5. Delete thoroughly

./c8volt delete pi --key 2251799813711967 --force
./c8volt get pi --state completed --keys-only | ./c8volt delete pi - --auto-confirm

Deletion in real environments often means cancel-first, then remove, then verify. c8volt is built for that operational sequence.

Precision Tools

The project also includes a strong set of supporting commands that are fully implemented and useful in day-to-day operator work.

Wait for a known-good state

Use expect when a script or operator workflow needs a concrete state transition before moving on:

./c8volt expect pi --key 2251799813685255 --state active
./c8volt expect pi --key 2251799813685255 --state completed --state absent

Inspect the environment before acting

./c8volt get cluster topology
./c8volt get cluster license
./c8volt config show
./c8volt config show --validate
./c8volt config show --template

This makes c8volt useful not only for action commands, but also for environment checks, support flows, and CI diagnostics. The config command family is about c8volt itself: how the CLI connects, authenticates, renders logs, and selects profiles.

Pull exact artifacts and metadata

./c8volt get pd --key 2251799813686017 --xml
./c8volt get resource --id resource-id-123

Export bundled fixtures for editing or custom deployment

./c8volt embed export --all --out ./fixtures
./c8volt embed export --file 'processdefinitions/*.bpmn' --out ./fixtures

Command Map

c8volt
├── embed                     Work with bundled BPMN fixtures
│   ├── list                  List bundled BPMN assets available in the binary
│   ├── deploy                Deploy bundled fixtures directly to Camunda
│   └── export                Export bundled fixtures for editing or custom deployment
├── deploy                    Deploy resources from local files or stdin
│   └── pd                    Deploy BPMN process definitions
├── run                       Start runnable resources
│   └── pi                    Start process instances and confirm activation by default
├── walk                      Inspect parent/child relationships
│   └── pi                    Walk ancestors, descendants, or full family trees
├── cancel                    Cancel resources and wait for a confirmed state change
│   └── pi                    Cancel process instances, including root escalation with --force
├── delete                    Delete resources, optionally forcing cleanup first
│   ├── pi                    Delete process instance trees
│   └── pd                    Delete process definitions with safety warnings
├── expect                    Wait until resources reach a target state
│   └── pi                    Wait for active, completed, canceled, terminated, or absent
├── get                       Read state, metadata, and resources
│   ├── cluster topology      Show connected Camunda cluster topology
│   ├── cluster license       Show cluster license details
│   ├── process-definition    List definitions, fetch latest versions, or retrieve XML
│   ├── process-instance      List or fetch process instances
│   └── resource              Fetch a single resource by id
└── config                    Inspect and validate c8volt configuration
    └── show                  Render, validate, or template c8volt config

Quick Start

Run Camunda 8 locally

Download Camunda 8 Run, unpack it, and start it:

./start.sh

For local c8run on Camunda 8.8, a minimal config.yaml for c8volt looks like this:

apis:
  version: "88"
  camunda_api:
    base_url: "http://localhost:8080/v2"
auth:
  mode: none
log:
  level: info

Common config locations:

  • ./config.yaml
  • $HOME/.c8volt/config.yaml
  • $HOME/.config/c8volt/config.yaml

Configure c8volt

The c8volt config command family is for the CLI itself, not for configuring Camunda.

Use it to:

  • inspect the effective c8volt configuration
  • validate connection and auth settings before running operational commands
  • generate a template file to start from
  • switch between connection profiles such as local, staging, and prod
  • set the default tenant for tenant-aware operations

The most useful starting commands are:

./c8volt config show
./c8volt config show --validate
./c8volt config show --template
./c8volt --profile prod config show

Tenant support

c8volt supports tenant-aware operations through:

  • app.tenant in the config file
  • the global --tenant flag for per-command override

This tenant value is used by commands such as deploy and run, and tenant IDs are also visible in process-definition and process-instance output where the API returns them.

Set a default tenant in config:

app:
  tenant: "tenant-a"

Or override it for one command:

./c8volt --tenant tenant-a run pi -b order-process
./c8volt --tenant tenant-a deploy pd --file ./order-process.bpmn
./c8volt --tenant tenant-a get pd --latest

This makes it practical to keep one base config while switching tenant context explicitly in scripts, CI jobs, or operator sessions.

Common OAuth connection scenarios

1. Local or simple cluster, no auth

This is the smallest setup and works well for local c8run or unsecured development environments:

apis:
  version: "88"
  camunda_api:
    base_url: "http://localhost:8080/v2"
auth:
  mode: none
log:
  level: info

2. One OAuth-protected Camunda API endpoint

Use this when the cluster API is the main entry point and one token is enough for the operations you run:

apis:
  camunda_api:
    base_url: "https://camunda.example.com/v2"
auth:
  mode: oauth2
  oauth2:
    token_url: "https://login.example.com/oauth/token"
    client_id: "c8volt"
    client_secret: "${set via env}"
log:
  level: info

This is the best default mental model for c8volt: connect the CLI to one cluster API, authenticate with client credentials, then operate through the CLI.

If your cluster is tenant-aware and you usually operate in one tenant, add:

app:
  tenant: "tenant-a"

3. OAuth with explicit scopes per API

Use this when your identity provider or platform setup requires scopes for specific APIs:

apis:
  camunda_api:
    base_url: "https://camunda.example.com"
    require_scope: true
  operate_api:
    base_url: "https://operate.example.com"
    require_scope: true
  tasklist_api:
    base_url: "https://tasklist.example.com"
    require_scope: true
auth:
  mode: oauth2
  oauth2:
    token_url: "https://login.example.com/oauth/token"
    client_id: "c8volt"
    client_secret: "${set via env}"
    scopes:
      camunda_api: "camunda-api.read"
      operate_api: "operate-api.read"
      tasklist_api: "tasklist-api.read"

This is the most common "real cluster" scenario when different endpoints or policies exist behind one identity provider.

4. One file, multiple profiles

Use profiles when the same operator needs to switch between environments without copying files:

active_profile: local

auth:
  oauth2:
    client_secret: "${set via env}"

profiles:
  local:
    app:
      tenant: ""
    apis:
      camunda_api:
        base_url: "http://localhost:8080/v2"
    auth:
      mode: none

  prod:
    app:
      tenant: "tenant-a"
    apis:
      camunda_api:
        base_url: "https://camunda.example.com"
        require_scope: true
    auth:
      mode: oauth2
      oauth2:
        token_url: "https://login.example.com/oauth/token"
        client_id: "c8volt"
        scopes:
          camunda_api: "camunda-api.read"

Switch profiles with:

./c8volt --profile local get cluster topology
./c8volt --profile prod get cluster topology

Recommended workflow for OAuth setups

  1. Generate a starting point with ./c8volt config show --template.
  2. Fill in apis.camunda_api.base_url, auth.mode, and the OAuth credentials.
  3. If you usually operate in a specific tenant, set app.tenant.
  4. Keep client_secret out of the YAML file when possible and inject it through environment variables.
  5. Run ./c8volt config show --validate.
  6. Confirm connectivity with ./c8volt get cluster topology.
  7. Confirm tenant-aware behavior with a command such as ./c8volt get pd --latest or an explicit --tenant override.
  8. Only then move on to deploy/run/cancel/delete workflows.

Environment variables for secrets

Sensitive values are safer in environment variables than in committed config files. The config system supports C8VOLT_... environment variables, so a common pattern is:

export C8VOLT_AUTH_OAUTH2_CLIENT_SECRET='super-secret'
export C8VOLT_AUTH_OAUTH2_CLIENT_ID='c8volt'
./c8volt --profile prod config show --validate

Install c8volt

Download the appropriate archive from c8volt Releases, unpack it, then verify the binary:

./c8volt version

Verify connectivity

./c8volt get cluster topology
./c8volt get cluster license

Or point to an explicit config file:

./c8volt get cluster topology --config ./config.yaml

Everyday Commands

The supporting read and deployment commands are still part of the core toolbox:

./c8volt deploy pd --file ./order-process.bpmn
./c8volt --tenant tenant-a deploy pd --file ./order-process.bpmn
./c8volt get pd --bpmn-process-id order-process --latest
./c8volt get pi --state active
./c8volt get cluster topology
./c8volt get resource
./c8volt config show

Good in Pipelines

c8volt is built to behave well in scripts, CI jobs, and operator toolchains:

  • --json for structured output
  • --keys-only for command chaining
  • --auto-confirm for non-interactive runs
  • --workers for controlled concurrency
  • --quiet and --verbose for different execution contexts
  • stable operational error handling and exit behavior

Example:

./c8volt get pi --bpmn-process-id C88_SimpleUserTask_Process --state active --keys-only

Documentation

Regenerate the CLI reference with:

make docs

Copyright

(c) 2026 Adam Bogdan Boczek | boczek.info