Configure Isolated Namespaces with Secrets and Plugin Defaults

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.

Namespaces provide an additional layer of isolation for secrets, variables, and plugin defaults within a tenant.

Namespace management — secure configuration

Kestra is a multi-tenant platform. Each tenant can have multiple Namespaces, and each Namespace provides additional isolation and security.

Namespaces provide:

  • Logical isolation of resources on top of instance- or tenant-level isolation
  • Fine-grained access control for secrets, variables, and task configurations

Namespaces are particularly useful in environments with many users, teams, projects, and applications.

Namespace-level features

The Namespace page allows you to configure secrets, plugin defaults, and variables that can be used within any flow in that Namespace.

It allows your organization to centrally manage your secrets, variables, and task configuration while providing fine-grained access-control to those resources.

Since Kestra supports everything as code and from the UI, you can manage Namespaces from the UI or programmatically (e.g., via our Terraform provider).

Secrets

On the namespace page, go to the Secrets tab, click Add a secret, enter a key and value, and save.

The secret key now appears on the Secrets tab. Edit or delete it using the action buttons on the right. Reference the secret in flows using its key, for example, "{{ secret('MYSQL_PASSWORD') }}".

For APIs that issue short-lived access tokens (e.g., OAuth2), create a Credential that relies on these secrets and fetch the token in flows with {{ credential('your_credential_key') }}.

Here is how you can use it in a flow:

id: query-mysql
namespace: company.team
tasks:
- id: query
type: io.kestra.plugin.jdbc.mysql.Query
url: jdbc:mysql://localhost:3306/test
username: root
password: "{{ secret('MYSQL_PASSWORD') }}"
sql: select * from employees
fetchOne: true

When building new flows in a Namespace, Namespace secrets are accessible from the Secrets tab. Open the tab to view all available Namespace secret key names.

Policies

Policies can be defined at the Namespace level to inject, restrict, or validate configuration for all flows in the Namespace. On the namespace page, open the Policies tab to create and manage Policies.

Policies can reference secrets and variables defined in the same Namespace.

For example, a namespace-scoped Policy can inject database credentials into every MySQL task so flows don’t need to declare them individually:

id: mysql-credentials
description: "Inject MySQL credentials for all MySQL tasks in this namespace."
enforcement: ACTIVE
rules:
- type: io.kestra.plugin.ee.rules.Add
on: PLUGIN
where:
- field: type
operator: STARTS_WITH
value: io.kestra.plugin.jdbc.mysql
values:
url: jdbc:mysql://localhost:3306/test
username: root
password: "{{ secret('MYSQL_PASSWORD') }}"

With this Policy applied, flows in the Namespace need no credentials on the task:

id: query-mysql
namespace: company.team
tasks:
- id: query
type: io.kestra.plugin.jdbc.mysql.Query
sql: select * from employees
fetchOne: true

Namespace-level Policies are inherited by child Namespaces. A Policy created in a parent Namespace applies to all flows in the parent and every child Namespace under it. See Policies for the full DSL reference, enforcement modes, and inheritance behavior.

Default service account for SDK plugins

Namespaces can now provide default authentication credentials that SDK-based plugins use to run tasks such as List all Namespaces. This allows tasks relying on the Kestra SDK to call the API without hard-coding credentials inside the flow.

On the Namespace Edit page, open the Default authentication section and choose either:

  • API token (recommended), or
  • Basic auth (username/password)

Variables

Variables defined at the Namespace level can be used in any flow defined under the same Namespace using the syntax: {{ namespace.variable_name }}.

On the namespace page, go to the Variables tab, define the variables, and save.

Here is an example flow where the Namespace variable is used:

id: query-mysql
namespace: company.team
tasks:
- id: query
type: io.kestra.plugin.jdbc.mysql.Query
url: jdbc:mysql://localhost:3306/test
username: "{{ namespace.mysql_user }}"
sql: select * from employees
fetchOne: true

When building new flows in a Namespace, Namespace variables are accessible from the Variables tab.

Creating Namespaces

From the UI

The video below shows how to create a namespace and add:

  • several new secrets
  • a nested Namespace variable that references one of these secrets
  • a list of plugin defaults helping to use those pre-configured secrets and variables in all the tasks from the AWS and Git plugins.

From Terraform

The following example reproduces those steps in Terraform.

To create a Namespace from Terraform, use the kestra_namespace resource.

First, configure your Terraform backend and add Kestra as a required provider:

terraform {
backend "s3" {
bucket = "kestraio"
key = "terraform.tfstate"
region = "us-east-1"
}
required_providers {
kestra = {
source = "kestra-io/kestra"
version = "~>0.14"
}
}
}
provider "kestra" {
url = var.kestra_host
username = var.kestra_user
password = var.kestra_password
tenant_id = var.kestra_tenant_id # only if you are using multi-tenancy
}

You can add a file main.tf to your Terraform project with the following content:

resource "kestra_namespace" "marketing" {
namespace_id = "marketing"
description = "Namespace for the marketing team"
}

The only required property is the namespace_id, which is the name of the Namespace. The description and all other properties are optional.

Adding variables and plugin defaults to a Namespace Terraform resource

You can add variables and plugin defaults directly to the Namespace resource by pointing to the YAML configuration files.

First, create the variables_marketing.yml file:

github:
token: "{{ secret('GITHUB_TOKEN') }}"

Then, create another file for plugin_defaults_marketing.yml:

- type: io.kestra.plugin.aws
values:
accessKeyId: "{{ secret('AWS_ACCESS_KEY_ID') }}"
region: us-east-1
secretKeyId: "{{ secret('AWS_SECRET_ACCESS_KEY') }}"
- type: io.kestra.plugin.git
values:
password: "{{ render(namespace.github.token) }}"
username: your-github-username

Finally, reference those files in your Namespace resource definition:

resource "kestra_namespace" "marketing" {
namespace_id = "marketing"
description = "Namespace for the marketing team"
variables = file("variables_marketing.yml")
plugin_defaults = file("plugin_defaults_marketing.yml")
}

Adding secrets to a Namespace using Terraform

To programmatically add secrets to your Namespace via Terraform, you can use the kestra_namespace_secret resource. Here is an example of adding multiple secrets to the marketing Namespace:

resource "kestra_namespace_secret" "github_token" {
namespace = "marketing"
secret_key = "GITHUB_TOKEN"
secret_value = var.github_token
}
resource "kestra_namespace_secret" "aws_access_key_id" {
namespace = "marketing"
secret_key = "AWS_ACCESS_KEY_ID"
secret_value = var.aws_access_key_id
}
resource "kestra_namespace_secret" "aws_secret_access_key" {
namespace = "marketing"
secret_key = "AWS_SECRET_ACCESS_KEY"
secret_value = var.aws_secret_access_key
}

Before referencing variables in your Terraform configuration, make sure to define them in your variables.tf file:

variable "github_token" {
type = string
sensitive = true
}
variable "aws_access_key_id" {
type = string
sensitive = true
}
variable "aws_secret_access_key" {
type = string
sensitive = true
}
variable "kestra_user" {
type = string
sensitive = true
}
variable "kestra_password" {
type = string
sensitive = true
}
variable "kestra_host" {
type = string
sensitive = false
default = "http://your_kestra_host:8080" # Change this to your Kestra host URL
}
variable "kestra_tenant_id" {
type = string
sensitive = false
default = "kestra-tech"
}

And add your secrets to the terraform.tfvars file:

github_token = "your-github-token"
aws_access_key_id = "your-aws-access-key-id"
aws_secret_access_key = "your-aws-secret-access-key"
kestra_user = "your-kestra-user"
kestra_password = "your-kestra-password"

Allowed Namespaces

On the Edit tab of any namespace, configure which namespaces are allowed to access its flows and resources.

By default, all Namespaces are allowed. To restrict access, select specific Namespaces — access automatically extends to each selected namespace’s children.

Was this page helpful?