Platform
ScaiWave ScaiGrid ScaiCore ScaiBot ScaiDrive ScaiKey Modellen Tools & Services
Oplossingen
Organisaties Ontwikkelaars Internet Service Providers Managed Service Providers AI-in-a-Box
Kenniscentrum
Ondersteuning Documentation Blog Downloads
Bedrijf
Over ons Onderzoek Vacatures Investeren Contact
Inloggen

CLI reference

The scaicontrol CLI is installed alongside the backend Python package (pip install -e . inside backend/ exposes it as a console script). It wraps three command groups: setup, sync, and admin.

bash
1
2
scaicontrol --help
scaicontrol --version

All commands read configuration from the same .env / environment variables that the backend reads — see Configuration. The CLI uses a synchronous DB connection (via pymysql), so DATABASE_URL is rewritten internally from mysql+asyncmy://… to mysql+pymysql://….


scaicontrol setup#

First-run bootstrap against ScaiKey. Registers ScaiControl as a ScaiKey application, polls until approval, and writes the resulting OAuth credentials back to .env.

setup register#

Submit a registration request to ScaiKey.

bash
1
2
3
4
5
6
scaicontrol setup register \
  --scaikey-url https://scaikey.scailabs.ai \
  --url https://scaicontrol.scailabs.ai \
  --email ops@example.com \
  --scope GLOBAL \
  --name ScaiControl
Flag Required Notes
--scaikey-url, -k yes Base URL of the ScaiKey instance
--url, -u yes Public base URL of this ScaiControl deployment (used as OAuth redirect_uri)
--email, -e yes Contact email for the registration
--scope, -s no (default GLOBAL) One of GLOBAL, PARTNER, TENANT
--partner, -p when scope=PARTNER Partner slug
--tenant, -t when scope=TENANT Tenant slug
--name, -n no (default ScaiControl) Application display name

Writes a status token to ~/.config/scaicontrol/registration.json (mode 0600). The token is printed once — save it.

setup status#

Poll ScaiKey for the registration's approval state. On APPROVED, writes SCAIKEY_CLIENT_ID, SCAIKEY_CLIENT_SECRET, SCAIKEY_APP_ID, and SCAIKEY_ISSUER to the project .env file.

bash
1
scaicontrol setup status

States: PENDING, APPROVED, REJECTED. Run repeatedly until approved.

setup show#

Display current ScaiKey configuration (secrets masked).

bash
1
scaicontrol setup show

scaicontrol sync#

Pull users and groups from ScaiKey into the local database. Used to populate the users and groups tables for tenant-isolated query auto-filters and role assignments.

bash
1
2
3
scaicontrol sync                # apply
scaicontrol sync --dry-run      # show changes without applying
scaicontrol sync --verbose      # per-user detail

Run this after setup status completes, then again whenever ScaiKey's user list changes materially (or schedule via cron). Idempotent — re-runs converge on the ScaiKey-side state.


scaicontrol admin#

User and role management on the local database. All admin operations are local-DB-only — they don't propagate back to ScaiKey. ScaiKey is the source of truth for identity; admin here manages ScaiControl-side role bindings on already-synced users.

admin list#

List active users in the local DB.

bash
1
2
3
scaicontrol admin list
scaicontrol admin list --role super_admin
scaicontrol admin list --role tenant_admin

--role filters by role; valid values: super_admin, partner_admin, tenant_admin.

admin grant#

Assign a role to a user.

bash
1
2
scaicontrol admin grant <user_id> --role super_admin
scaicontrol admin grant --email alice@example.com --role partner_admin

User can be identified by ID (positional) or --email. The role replaces any existing role on the user (single-role-per-user model).

admin revoke#

Remove a user's role. Errors if the user doesn't currently hold the named role.

bash
1
2
scaicontrol admin revoke <user_id> --role super_admin
scaicontrol admin revoke --email alice@example.com --role partner_admin

admin show#

Print a user's full local record (ID, email, name, tenant, partner, role, sync timestamp).

bash
1
2
scaicontrol admin show <user_id>
scaicontrol admin show --email alice@example.com

admin find#

Search ScaiKey (not the local DB) for users by email or name substring. Useful for discovering a user before running sync.

bash
1
2
scaicontrol admin find --email alice
scaicontrol admin find --name "Alice"

admin templates validate#

Compile every saved designer template (invoice + email) through Jinja and report syntax failures. Exits non-zero on any failure — suitable for CI.

bash
1
2
3
scaicontrol admin templates validate
scaicontrol admin templates validate --name "Default Invoice"
scaicontrol admin templates validate --lang nl

admin workflow-defs ... — provisioning workflow definitions#

Manage the JSON recipes that drive the provisioning DAG engine. Service teams check these into their own repos under provisioning/{provision,deprovision}.json and use validate in their CI pipelines.

Subcommand Purpose DB?
validate <file> Run every validator rule against a local file. CI-friendly. No — works without DATABASE_URL set
list [--service S] [--type T] [--include-inactive] Show definitions in the DB Yes
show <id> Dump the steps_definition JSON to stdout Yes
import <file> --service S --type T [--description "..."] Validate then insert; auto-bumps version Yes
diff <file> <id> Unified diff: local file vs deployed definition Yes
deactivate <id> [--reactivate] [--force] Set is_active; safety-blocked when it'd leave a service with no active version Yes
bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# CI pipeline — no DB needed:
scaicontrol admin workflow-defs validate provisioning/provision.json --format json

# Deploy:
scaicontrol admin workflow-defs import provisioning/provision.json \
    --service scaiflow --type provision

# Audit:
scaicontrol admin workflow-defs list --include-inactive
scaicontrol admin workflow-defs diff provisioning/provision.json <id>

Validation rules (machine-readable codes for CI integration):

  • EMPTY_DEFINITION — top-level dict + non-empty steps[] required
  • STEP_MISSING_FIELD — each step needs name and handler_class
  • DUPLICATE_STEP_NAME — step names must be unique
  • UNKNOWN_STEP_TYPEtype{sync, async_callback, async_poll}
  • UNKNOWN_DEPENDENCYdepends_on references existing steps only
  • CYCLE — dependency graph must be acyclic (Kahn's algorithm)
  • HANDLER_NOT_FOUND / HANDLER_BAD_TYPE — handler resolves to a StepHandler subclass
  • HANDLER_TYPE_MISMATCHasync_callback/async_poll steps must use the matching handler base class
  • BAD_INPUT_MAPPING — input mapping sources must be context.<key> or <step>.<output>
  • NO_COMPENSATE_HANDLER (warning) — rollback will skip steps that have no compensator

Service teams that ship custom handlers register them via setuptools entry points in their package's pyproject.toml:

toml
1
2
[project.entry-points."scaicontrol.provisioning.handlers"]
BootstrapFlowWorkspace = "scaiflow.provisioning.handlers:BootstrapFlowWorkspace"

ScaiControl discovers them at startup and they're then referenceable by short name in workflow definitions, same as built-ins.

Flag Notes
--name Filter by template name (exact match)
--lang Filter by language code (e.g. nl, de)

Validates both html_content and subject fields where present.


Exit codes#

Code Meaning
0 Success
1 Validation/runtime error (ClickException) — message printed to stderr
2 Usage error (UsageError) — typically a missing required option

The admin templates validate command additionally exits 1 when any template fails to compile, regardless of whether other operations succeeded.


Common workflows#

First-run deploy:

bash
1
2
3
4
5
6
7
scaicontrol setup register -k https://scaikey.scailabs.ai \
                           -u https://scaicontrol.example.com \
                           -e ops@example.com
# operator approves in ScaiKey UI
scaicontrol setup status         # repeat until APPROVED
scaicontrol sync                 # populate local users/groups
scaicontrol admin grant --email founder@example.com --role super_admin

Promote a user to platform admin:

bash
1
2
scaicontrol sync                 # ensure their record is current
scaicontrol admin grant --email user@example.com --role super_admin

Pre-deploy template smoke check (in CI):

bash
1
scaicontrol admin templates validate || exit 1
Updated 2026-06-29 00:34:15 View source (.md) rev 9