Docs

Documentation / Pipelines

Secrets and variables

Define the values and secrets your pipelines use; work with scopes, Kubernetes secrets, external secret stores and OIDC tokens.

Variables#

Variables are values used in step configs as {{.KEY}}. Create them with New variable on Infrastructure > Variables. You can also add repository-specific variables on the repository binding page.

  • The Key is UPPER_SNAKE_CASE, for example API_BASE_URL. It cannot be changed after creation; delete and recreate the variable instead.
  • A step config refers to it as {{.API_BASE_URL}}.
- name: Deploy
  kind: K8S_DEPLOY
  config:
    image: "{{.ImageTag}}"
    env:
      API_BASE_URL: "{{.API_BASE_URL}}"

Types#

Type Where the value lives Notes
Plain (PLAIN) In EJO, in clear text. For settings that are not secret.
Secret (SECRET) In EJO, encrypted. Masked in logs. Also available as {{.KEY_FILE}}, the path of a file that holds the value.
K8s Secret (K8S_SECRET) In a Kubernetes Secret in your cluster. Referenced by Namespace, Secret name and Secret key. The agent reads the value.
External secret (EXTERNAL_SECRET) In your own secret manager (Vault, AWS Secrets Manager, Azure Key Vault, CyberArk). The agent reads the value with its own identity; EJO never sees it.

A saved secret value is never shown again. When editing, leave the value field blank to keep the current value.

Tip: For tools that expect a file (for example a kubeconfig or a certificate), use {{.KEY_FILE}}. The value is written to a temporary file on the agent and the step gets the file's path.

Scopes and precedence#

Scope Where it applies
Global — every environment Every repository and environment.
Repository That repository binding only. Overrides a global variable with the same key.
Environment Jobs in that environment only. Overrides global and repository variables with the same key.

When the same key is defined in several scopes, the order is: global < repository < environment. The most specific scope wins.

Warning: Pull requests from forks do not receive SECRET, K8S_SECRET or EXTERNAL_SECRET values. Steps that need them may fail on such PRs.

External secret stores#

If your secrets already live in HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, CyberArk Conjur or the CyberArk Central Credential Provider, you do not have to copy them into EJO.

Prerequisites#

  • The admin role.
  • An up-to-date agent with the external_secrets capability. With an older agent the run stops with "upgrade the agent".
  • The agent must reach your secret manager with its own identity: a Kubernetes service account, an IAM role or a token file on the agent host.

Setup#

  1. On Settings > Secret stores, create a New secret store.
  2. Enter a name (for example vault-prod), a provider (VAULT, AWS_SM, AZURE_KV, CYBERARK_CONJUR, CYBERARK_CCP) and the connection settings. Connection settings are not secret: the Vault address, the AWS region, the Key Vault URL and so on. A field that looks like a credential (token, password, secret_id and similar) is rejected.
  3. Add the environments that may use the store to Allowed environments. The list starts empty; a run in an environment that is not on the list cannot use the store, and the error names the store and the environment.
  4. Use Test connection to check that the agent can reach the store.
  5. On Infrastructure > Variables, create a variable of type External secret and pick the store, path and field.

The value behaves like a SECRET: it is masked in logs and also available as {{.KEY_FILE}}. The deployment page shows which secret version each run used, never the value or a hash of it.

Pipeline identity (OIDC tokens)#

EJO can act as an OpenID Connect provider for pipelines. A SHELL step asks for a short-lived JWT that says which service, environment and deployment it belongs to. Cloud providers and secret stores that trust the token accept it instead of a stored secret.

- name: Deploy
  kind: SHELL
  image: amazon/aws-cli:2.17.0
  id_tokens:
    AWS_JWT:
      aud: sts.amazonaws.com
  config:
    command: aws sts get-caller-identity
  • The step gets the token as $AWS_JWT and as a file at $AWS_JWT_FILE; it is masked in logs. Prefer the file where you can.
  • aud must be a fixed value; templates are not allowed.
  • The token lives 10 minutes by default, at most 1 hour.
  • Pull requests from forks never get a token.
  • The token's sub claim is service:<service>:env:<environment>. PR runs add :pull_request at the end. Bind trust rules to the exact sub value.
  • The discovery document is at https://acme.ejocloud.com/.well-known/openid-configuration.

The Settings > Pipeline identity page (admin only) manages the token lifetime, the allowed audiences and the signing keys, and shows example trust policies for AWS, GCP, Azure and Vault.

Vault, Conjur, AWS Secrets Manager and Azure secret stores can sign in with this token instead of the agent's own identity: set identity to ejo_pipeline_token in the store settings and set an audience.

Next steps#

Last updated: October 16, 2026