Harden your deployment with isolation and network controls

For the complete documentation index, see llms.txt. For a full content snapshot, see llms-full.txt. Append .md to any kestra.io/docs/* URL for plain Markdown.

Configure network isolation, endpoint authentication, and upload protection to harden a Kestra deployment.

By design, Kestra allows arbitrary HTTP calls and script execution. To prevent misuse of link-local metadata services (IMDS), isolate and block access at the network layer:

  • Network ACLs or security groups: configure your VPC or firewall to deny all requests to link-local ranges (e.g., 169.254.169.254/32).
  • Dedicated orchestration subnet: place Kestra workers in a private subnet with no route to management or metadata services.
  • Egress proxy or NAT gateway filtering: route all outbound traffic through a proxy or gateway that can enforce allow-lists and block link-local IPs.

Host-level isolation

Running workflows in isolated environments reduces the impact of potentially malicious flows:

  • Container sandboxes: launch each flow execution in its own container (for example, Docker or Kubernetes Pod) with minimal privileges.
  • Ephemeral compute: use Kestra’s native Task Runners to auto-scale ephemeral compute nodes that are destroyed after each run, leaving no residual state.
  • Minimum host permissions: grant only the OS-level rights required for the runtime; avoid mounting cloud credential files or granting host-level IAM roles directly.

Transport security

In distributed deployments, Worker Controllers communicate with Workers over gRPC. By default this channel is plaintext. TLS and mTLS are available in all editions; JWT-based worker authentication is an Enterprise Edition feature.

  • One-way TLS — the controller presents a certificate; workers verify it. Encrypts the channel without requiring worker certificates.
  • Mutual TLS (mTLS) — both controller and worker present certificates. Use this when you need strong identity verification between components, not just encryption.

See gRPC TLS/mTLS configuration for setup instructions and a full property reference.

HTTP task URL filtering

HTTP plugin tasks (Request, Download, SseRequest, and Trigger) make server-side HTTP calls to URIs controlled by flow authors. Without restrictions, a flow author can reach cloud metadata endpoints (such as 169.254.169.254 on AWS, GCP, and Azure), internal management APIs, or private services not reachable from the internet.

Configure an allow-list, a deny-list, or both under kestra.tasks.http:

kestra:
tasks:
http:
allowed-list:
- https://api.example.com
- https://data.partner.io
denied-list:
- http://169.254.169.254
- http://localhost
- http://127.0.0.1
PropertyDefaultDescription
kestra.tasks.http.allowed-list[]When non-empty, a request URI must start with at least one entry or the task fails.
kestra.tasks.http.denied-list[]A request URI that starts with any entry causes the task to fail. Evaluated after the allowed-list.

Both lists are empty by default — no filtering is applied unless you configure them.

When both lists are set, the allowed-list is checked first. A URI that matches an allowed-list entry but also matches a denied-list entry is still blocked.

Matching is prefix-based, not glob or CIDR. Each entry is a literal string prefix, so:

  • http://169.254.169.254 blocks http://169.254.169.254/latest/meta-data/...
  • http://10. blocks http://10.0.0.1/admin but not https://10.0.0.1/admin because the scheme differs

When a URI is blocked, the task fails with an error that identifies the matching config key:

The URI http://169.254.169.254/... is in the configured denied list (kestra.tasks.http.denied-list).

Encryption key

Configure an encryption key so that SECRET inputs and outputs can be stored safely at rest. Without it, any flow that uses SECRET-typed inputs or outputs fails at runtime.

kestra:
encryption:
secret-key: BASE64_ENCODED_STRING_OF_32_CHARACTERS

Generate a key with:

openssl rand -base64 32

See Encryption configuration for full details.

Plugin restrictions (EE)

Restrict which task runners and plugins flow authors can use. At minimum, restrict access to the Process task runner in multi-tenant or untrusted environments — the Process runner executes directly on the worker host with no container isolation.

Configure plugin restrictions and worker isolation under Worker Isolation. For finer-grained policy enforcement across namespaces and tenants, use Policies to inject, validate, or reject plugin and flow configuration at save or execution time.

Plugin and code validation

Credential initialization

On Enterprise Edition, use OIDC/SSO or LDAP instead of Basic Authentication. These integrate with your existing identity provider, support MFA, and remove the risk of locally managed credentials. One-Time-Password (OTP) is also supported, though it provides less protection than SSO with MFA.

If you use Basic Authentication on OSS or EE:

Management endpoint access

Kestra exposes internal endpoints on a separate management port (default 8081). These include health checks, metrics (/metrics), and runtime log level inspection (/loggers). This port is unauthenticated by default.

The primary protection is network isolation: do not expose port 8081 outside the internal network. Firewall or security-group rules should restrict access to the management port to trusted internal hosts only (monitoring agents, load balancer health checkers, operations tooling).

If network isolation is not sufficient, you can add Basic Auth to the management port and optionally move it to a non-default port by configuring endpoints.all in your application.yml:

endpoints:
all:
port: 8084 # move away from the default 8081
basic-auth:
username: <management-username>
password: <strong-password>

When basic-auth credentials are present, Kestra’s management endpoint filter requires Basic Auth on every request to that port.

See Kestra endpoints for the full list of what is exposed on the management port.

ZIP bomb protection

Kestra guards against ZIP bomb attacks on the two endpoints that accept user-uploaded ZIP archives: flow import and namespace file upload. The protection is opt-in and disabled by default.

Enable it under kestra.security.zip-bomb-protection in your application.yml:

kestra:
security:
zip-bomb-protection:
enabled: true
max-number-of-entries: <integer> # maximum number of entries in the archive
max-entry-size: <bytes> # maximum uncompressed size of a single entry

Both max-number-of-entries and max-entry-size are required when enabled: true. Set them based on the largest legitimate ZIP archives your users are expected to upload. When a ZIP exceeds either limit, the request is rejected with an HTTP 422 error.

  • Encryption and secrets configuration — encryption key setup, secret backend configuration, and auth security settings.
  • External Secrets Manager — integrate with AWS Secrets Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, and others to avoid storing credentials in Kestra directly.
  • Policies — enforce governance rules that inject, validate, or reject plugin and flow configuration across namespaces and tenants.

Was this page helpful?