Manage Kestra Flows, IAM, and Plugins with kestractl
For the complete documentation index, see llms.txt. For a full content snapshot, see llms-full.txt. Append.mdto anykestra.io/docs/*URL for plain Markdown.
Use kestractl to manage flows, executions, namespaces, namespace files, key-value pairs, plugins, and IAM resources. Most commands interact with the Kestra host API; workers registration-tokens generate runs entirely offline.
For server components and system maintenance commands (starting standalone servers, server-side plugin installation), see the Kestra Server CLI.
Installation
curl -fsSL https://raw.githubusercontent.com/kestra-io/kestractl/main/install-scripts/install.sh | bashQuick Setup
Open Source (basic auth)
kestractl config add default http://localhost:8080 main --username YOUR_USERNAME --password YOUR_PASSWORD --defaultEnterprise (API token)
kestractl config add default https://kestra.example.com production --token YOUR_TOKEN --defaultYour configuration is saved at ~/.kestractl/config.yaml and the default context is used automatically.
contexts: default: host: https://kestra.example.com tenant: production auth_method: token token: YOUR_TOKENdefault_context: defaultFor basic auth contexts, auth_method is basicAuth and the file stores username and password instead of a token.
Usage
Examples
# Deploy flows, then run one and wait for completionkestractl flows deploy ./flows --namespace prod --override --fail-fastkestractl executions run prod nightly-refresh --wait --output json# Sync namespace files for a releasekestractl nsfiles upload prod ./assets --path resources --override --fail-fast# List flows as JSONkestractl flows list my.namespace --output jsonCommand groups
config: manage authentication contexts.flows: list, get, deploy, and validate flows.executions: run and inspect executions.namespaces: list and filter namespaces.nsfiles: list, get, upload, and delete namespace files.kv: list, set, update, get, and delete key-value pairs. Note:kv listrequires token auth and returns 401 with basic auth.users: list, get, create, update, delete, set group membership, set passwords, and manage API tokens for users. Requires Kestra EE; operates at the instance level (not tenant-scoped).groups: list, get, create, update, delete groups and manage their members. Requires Kestra EE; tenant-scoped.roles: list, get, create, update, and delete roles with resource-level permissions. Requires Kestra EE; tenant-scoped.service-accounts(aliases:service-account,sa): list, get, create, update, delete service accounts and manage their API tokens. Requires Kestra EE; instance-level (not tenant-scoped).bindings: list, get, create, and delete role bindings (the assignment of a role to a user or group). Requires Kestra EE; tenant-scoped.invitations: list, get, create, and delete user invitations. Requires Kestra EE; tenant-scoped.plugins: list compatible plugins for a Kestra version and download them to a local directory.workers: manage worker registration tokens.
Use kestractl --help or kestractl <command> --help for the full command reference.
IAM management (Enterprise Edition)
The users, groups, roles, service-accounts, bindings, and invitations command groups require Kestra Enterprise Edition. users and service-accounts operate at the instance level while groups, roles, bindings, and invitations are tenant-scoped and use the active tenant from your context.
Users
Use --user-password to set a user’s password — not --password. The --password flag authenticates the CLI itself with basic auth. Passing a user’s new password to --password sends it as your own credentials.
# List / filter userskestractl users listkestractl users list --query alice --output json
# Get user detailskestractl users get <user_id>
# Create a user (--email is required)kestractl users create --email alice@example.com --first-name Alice --last-name Smith --user-password 'S3cret!'kestractl users create --email bob@example.com --superadminkestractl users create --email bot@example.com --restricted # restricted users have limited access
# Grant a user access to specific tenants (--tenant-grant is repeatable)kestractl users create --email ops@example.com --tenant-grant main --tenant-grant staging
# Update a user — only the flags you pass change; other attributes are preservedkestractl users update <user_id> --first-name Alicia --last-name Joneskestractl users update <user_id> --superadmin=falsekestractl users update <user_id> --tenant-grant main
# Set a user's passwordkestractl users set-password <user_id> --user-password 'N3wPass!'
# Assign a user to groups in the active tenant# Passing no --group clears all group memberships for that tenantkestractl users set-groups <user_id> --group <group_id>
# Delete a user — prompts for confirmation; skip with --yeskestractl users delete <user_id>kestractl users delete <user_id> --yes
# Manage a user's API tokens (the full token value is shown only once, at creation)kestractl users tokens create <user_id> --name ci-token --description "CI pipeline token"kestractl users tokens list <user_id>kestractl users tokens delete <user_id> <token_id>Groups
# List / filter groupskestractl groups listkestractl groups list --query admins --output json
# Get group detailskestractl groups get <group_id>
# Create a group (--name is required; --member is repeatable for initial members)kestractl groups create --name admins --description 'Platform admins'kestractl groups create --name admins --member <user_id> --member <user_id>
# Update a group — only the flags you pass change; other attributes are preservedkestractl groups update <group_id> --name platform-adminskestractl groups update <group_id> --description 'Updated description'
# Delete a group — prompts for confirmation; skip with --yeskestractl groups delete <group_id>kestractl groups delete <group_id> --yes
# Manage group memberskestractl groups members list <group_id>kestractl groups members add <group_id> <user_id>kestractl groups members remove <group_id> <user_id>Roles
A role carries a permissions payload: a map of resource (e.g. FLOW, EXECUTION, NAMESPACE) to a list of actions (e.g. VIEW, LIST, EXECUTE). Provide permissions either inline with the repeatable --permission TYPE:ACTION[,ACTION] flag or from a YAML/JSON file with --permissions-file — not both at once.
For the full list of resources and their valid actions, see the RBAC permissions reference.
Passing --permission or --permissions-file on roles update replaces the entire permissions block — it does not merge with the existing permissions. Omit both flags on update if you only want to change the name or description.
# List / filter roleskestractl roles listkestractl roles list --query editor --output jsonkestractl roles list --page 1 --size 50 --sort name:asc
# Get role details, including its permissionskestractl roles get <role_id>
# Create a role (--name required; at least one --permission or --permissions-file required)kestractl roles create --name operator \ --description "Can edit and execute flows, monitor executions" \ --permission FLOW:VIEW,LIST,CREATE,UPDATE,DELETE,EXECUTE,DISABLE,ENABLE \ --permission EXECUTION:VIEW,LIST,ACCESS_LOGS,ACCESS_FILES,FOLLOW
# Create a role from a permissions file (YAML or JSON)kestractl roles create --name viewer --permissions-file perms.yaml# perms.yamlFLOW: - VIEW - LISTEXECUTION: - VIEW - LIST - ACCESS_LOGS - FOLLOW# Update a role — only the flags you pass change; other attributes are preserved# Exception: --permission replaces the entire permissions blockkestractl roles update <role_id> --description "Updated description"kestractl roles update <role_id> --permission FLOW:VIEW,LIST,CREATE,UPDATE,DELETEkestractl roles update <role_id> --default
# Delete a role — prompts for confirmation; skip with --yeskestractl roles delete <role_id>kestractl roles delete <role_id> --yesService accounts
Service accounts are instance-level resources. The command can be shortened to service-account or sa.
update is a partial update — only --name and --description are accepted. Super-admin status, tenant grants, and group membership cannot be changed with update. Pass at least one of --name or --description; passing neither returns an error.
# List service accountskestractl service-accounts listkestractl service-accounts list --output jsonkestractl service-accounts list --page 1 --size 50 --sort name:asc
# Get service account detailskestractl service-accounts get <service_account_id>
# Create a service account (--name is required; lowercase alphanumeric and dashes)kestractl service-accounts create --name ci-bot --description "CI pipeline"
# Create a super-admin service account with tenant access (--tenant-grant is repeatable)kestractl service-accounts create --name ops-bot --superadmin --tenant-grant main
# Update name or description only (at least one flag required)kestractl service-accounts update <service_account_id> --description "Updated description"kestractl service-accounts update <service_account_id> --name new-bot-name
# Delete a service account — prompts for confirmation; skip with --yeskestractl service-accounts delete <service_account_id>kestractl service-accounts delete <service_account_id> --yes
# Manage API tokens (the full token value is shown only once, at creation)kestractl service-accounts tokens create <service_account_id> --name deploy-token --description "CD pipeline token"kestractl service-accounts tokens create <service_account_id> --name short-lived --max-age P30D --extendedkestractl service-accounts tokens list <service_account_id>kestractl service-accounts tokens delete <service_account_id> <token_id>Bindings
A binding assigns a role to a user or group, optionally scoped to a namespace. Bindings are tenant-scoped.
# List all bindingskestractl bindings list
# Filter by subject type or IDkestractl bindings list --type USER --external-id <user_id>kestractl bindings list --type GROUP --external-id <group_id>
# Filter by namespacekestractl bindings list --namespace company.team
# Get binding detailskestractl bindings get <binding_id>
# Assign a role to a user tenant-widekestractl bindings create --type USER --external-id <user_id> --role <role_id>
# Assign a role to a group scoped to a namespacekestractl bindings create --type GROUP --external-id <group_id> --role <role_id> \ --namespace company.team
# Delete a binding — prompts for confirmation; skip with --yeskestractl bindings delete <binding_id>kestractl bindings delete <binding_id> --yesInvitations
Invitations let you grant users access to a tenant. Pre-assign roles and groups so the invitee receives them upon acceptance.
If the invitee already has a Kestra user account, or if you pass --create-user-if-not-exist, the server grants tenant access directly and no invitation email is sent.
# List all invitationskestractl invitations list
# Filter by status or emailkestractl invitations list --status PENDINGkestractl invitations list --email jane@example.com
# Get invitation detailskestractl invitations get <invitation_id>
# Invite a user and pre-assign a rolekestractl invitations create --email jane@example.com --role <role_id>
# Invite a user into one or more groups (--group is repeatable)kestractl invitations create --email jane@example.com --group <group_id> --group <group_id>
# Grant superadmin on acceptancekestractl invitations create --email jane@example.com --superadmin
# Grant access directly, creating the user account if it does not existkestractl invitations create --email jane@example.com --create-user-if-not-exist
# Delete (revoke) an invitation — prompts for confirmation; skip with --yeskestractl invitations delete <invitation_id>kestractl invitations delete <invitation_id> --yesPlugin management
The plugins command group manages the plugins a Kestra worker needs to start. Use it when deploying standalone or remote workers without Docker, where plugins must be pre-installed as JAR files.
kestractl plugins list <version>
List all compatible plugins for a given Kestra version. Output is a single space-separated line of groupId:artifactId:version coordinates.
kestractl plugins list 2.0.0Use --output json for full plugin metadata (groupId, artifactId, license, version).
| Flag | Default | Description |
|---|---|---|
--edition | ALL | Filter by edition: ALL, OSS, or EE |
--from-config | — | Derive required core plugins from one or more config files (see below) |
--output | table | Output format: table (space-separated coordinates) or json |
kestractl plugins download [version]
Download plugins to a local directory. By default, all compatible plugins for the given version are downloaded from Maven Central.
kestractl plugins download 2.0.0The version argument is required unless --plugins is set.
| Flag | Default | Description |
|---|---|---|
--plugins-dir | ./plugins | Directory to write downloaded JARs into |
--edition | ALL | Filter by edition: ALL, OSS, or EE |
--plugins | — | Explicit coordinates to download (groupId:artifactId:version, space-separated or repeated); bypasses API lookup and makes version optional |
--from-config | — | Download only the core plugins required by one or more config files; requires a version argument (see below) |
--concurrency | 1 | Number of parallel downloads |
--keep-only-last-version | true | Remove older versions of each plugin from the plugins directory after downloading |
--force-redownload | false | Re-download plugins even if they already exist |
--global-timeout | 5m | Maximum total time for all downloads |
--maven-repository | Maven Central | Custom Maven repository base URL |
--maven-username | — | Username for Maven basic authentication |
--maven-password | — | Password for Maven basic authentication |
The global --header flag (see Global flags) adds arbitrary HTTP headers to all requests, including Maven downloads — use it for bearer token authentication against a private registry.
Custom Maven registry authentication
# Basic authkestractl plugins download 2.0.0 \ --maven-repository https://nexus.example.com/repository/maven-central \ --maven-username myuser \ --maven-password mypassword
# Bearer token (--header is a global flag)kestractl plugins download 2.0.0 \ --maven-repository https://nexus.example.com/repository/maven-central \ --header "Authorization:Bearer <token>"Bootstrap core plugins with --from-config
Use --from-config when you need to determine which core infrastructure plugins a standalone worker needs before it can start. Pass one or more Kestra application.yaml files and the command reads four keys, mapping each to the plugin it requires:
kestra.storage.typekestra.secret.typekestra.queue.typekestra.repository.type
Bundled backends produce no output. Only backends that ship as a separate plugin appear in the output.
| Category | Bundled (no plugin needed) | Requires a plugin |
|---|---|---|
Storage (kestra.storage.type) | local | s3, gcs, azure, minio, seaweedfs, cloudflare |
Secret (kestra.secret.type) | jdbc, elasticsearch | vault, aws-secret-manager, azure-key-vault, google-secret-manager, cyberark, doppler, 1password, beyondtrust, delinea |
Queue (kestra.queue.type) | memory, h2, postgres, mysql, kafka | — |
Repository (kestra.repository.type) | memory, h2, postgres, mysql | elasticsearch, opensearch |
Example: a worker using S3 storage and AWS Secrets Manager needs two plugins:
kestractl plugins list 2.0.0 --from-config /etc/kestra/application.yaml# → io.kestra.storage:storage-s3:1.4.1If all configured backends are bundled, the command exits cleanly with:
No core plugins required by the provided configuration (all configured backends are bundled in Kestra).If a config key contains an unrecognized type, the command fails and lists supported values:
Error: unknown kestra.storage.type "unknownbackend" — no known core plugin mapping (supported: azure, cloudflare, gcs, local, minio, s3, seaweedfs)Multiple config files
Pass --from-config multiple times to merge configs. The last non-empty value per category wins — later files override earlier ones:
kestractl plugins download 2.0.0 \ --from-config /etc/kestra/application.yaml \ --from-config /etc/kestra/application-prod.yamlPipe pattern
--from-config and --plugins are mutually exclusive on download. Use the pipe pattern to preview the required plugins before downloading:
kestractl plugins download 2.0.0 \ --plugins "$(kestractl plugins list 2.0.0 --from-config /etc/kestra/application.yaml)"Enterprise plugin registry
External secret managers (aws-secret-manager, azure-key-vault, google-secret-manager, and others) and the Elasticsearch/OpenSearch repository backends are not published to Maven Central. Use --maven-repository with your Kestra plugin registry credentials to download them.
Worker management
kestractl workers registration-tokens generate
Generate a worker registration token. This command runs entirely offline — no running Kestra instance is required.
kestractl workers registration-tokens generateThe token is printed to stdout in the format kwreg_<random>_<checksum>.
When deploying a standalone worker, you also need to download the core infrastructure plugins it requires. See Bootstrap core plugins with --from-config.
Configuration
Global flags
--host- Kestra host URL--tenant- Tenant name--token/-t- API token (Enterprise)--username- Basic auth username (Open Source)--password- Basic auth password (Open Source)--output/-o- Output format (tableorjson)--config- Custom config file path (default:~/.kestractl/config.yaml)--verbose/-v- Verbose output (warning: prints credentials in HTTP requests)
Config file and contexts
Manage contexts with kestractl config add, kestractl config show, kestractl config use, and kestractl config remove.
Environment variables
Environment variables override config file settings. Use either KESTRACTL_TOKEN or KESTRACTL_USERNAME and KESTRACTL_PASSWORD.
export KESTRACTL_HOST=http://localhost:8080export KESTRACTL_TENANT=mainexport KESTRACTL_TOKEN=YOUR_TOKENexport KESTRACTL_USERNAME=adminexport KESTRACTL_PASSWORD=adminexport KESTRACTL_OUTPUT=jsonConfiguration precedence
- Command-line flags (
--host,--token, etc.) - Environment variables (
KESTRACTL_HOST,KESTRACTL_TOKEN, etc.) - Config file (
~/.kestractl/config.yamlor custom via--config) - Default values
Override per command
kestractl flows get my.namespace my-flow \ --host https://kestra.example.com \ --tenant production \ --token YOUR_TOKENWas this page helpful?