Skip to content
DocsAll docs
Console

Secrets, registries and environments

Give jobs secrets with masked logs, push images to a container registry, and run jobs against an environment.

Last updated

On this page

Description and operation

General

A job gets credentials and services only from its owner and its definition. It reads the secrets of the owner of the pipeline. It logs in to the container registries of that owner when its definition asks. It reaches an environment through a session that the platform makes for the run.

ItemWhere it comes fromSee
SecretsThe secrets of the owner of the pipeline. For a team, the secrets of the team.Secrets
HF_TOKENThe HF_TOKEN secret of the owner, for example from a Hugging Face connector.Hugging Face token
Registry loginThe container registry connectors of the owner.Registry push
Git readThe GitHub and GitLab connectors of the owner, when the job asks for permissions.git: read.Code in a job
ServicesA shared environment, or a copy of it for the run.Environments

To do these tasks with an AI agent, see Agentic workflows – General.

Secrets

A job reads a secret only by reference. The pipeline reads the secrets of its owner: your own secrets for a personal pipeline, the secrets of the team for a team pipeline. A pipeline never reads the personal secrets that a member keeps in a team. The secret stores are described in Secrets.

FormResult
"secrets": ["DB_URL"] on a jobEvery step gets the variable DB_URL with the value of the secret.
"env": {"TOKEN": "${{ secrets.API_TOKEN }}"} on a job or a stepThat job or step gets TOKEN with the value of API_TOKEN.

The reference must be the whole value. Each start of a run checks the secrets again, and a secret that was deleted after the save refuses the run with 422. A save checks that each secret exists, and fails with secret NAME does not exist when one does not. A secret that the newest version names, or that a queued or running run took, cannot be deleted.

Masking

The log of a job shows *** in place of each value that the job holds: its secrets, HF_TOKEN and the credentials that the platform gives it. A value shorter than 4 bytes is not masked, because a short value matches too much ordinary text. Do not use short secret values. The Git credential KL_GIT_TOKEN of a job with permissions.git: read is masked in the same way.

Hugging Face token

When the owner of the pipeline has the secret HF_TOKEN, every job gets it as the variable HF_TOKEN. Hugging Face tools read this variable. A job that sets HF_TOKEN in its own env or secrets uses its own value. See Connectors.

Registry push

"permissions": {"registry": "push"} on a job logs it in to each container registry of the owner, before the first step. A pull from those registries needs no grant.

VariableValue
KL_REGISTRYThe first registry and its namespace, for example ghcr.io/acme. Name images under it.
KL_REGISTRY_USERThe user name of that registry.

The login uses docker, so the image of the job must contain the docker command. A job without it fails with registry: push needs docker in the job's image.

Environments

A job can run against the services of an environment. The platform connects the jobs of the run to the environment through a session that it makes for the run.

ValueMeaning
"environment": "staging"The shared environment staging, as it is.
"environment": {"clone": "staging"}A copy of staging, made for this run and deleted when the run ends. Jobs with the same target share one copy.

Set environment on the pipeline, on a job, or in the start request. The value of a job wins over the start request, and the start request wins over the pipeline. A copy counts against the quota of the owner while it exists. If the run does not delete a copy, the platform deletes it after one hour of non-use.

CAUTION

Jobs that use a shared environment change its data. Use a copy for work that writes test data.

Tasks

Give a secret to a job

Reason for the task: Let a job use a credential, such as a database URL, without writing it in the definition.

Job set-up

Procedure

  1. Add the secrets to the definition. DB_URL reaches every step, and TOKEN reaches one step.

    json
    {  "name": "load-orders",  "jobs": {    "load": {      "packages": ["postgresql", "curl"],      "secrets": ["DB_URL"],      "steps": [        { "name": "check", "run": "psql \"$DB_URL\" -c 'select 1'" },        {          "name": "fetch",          "run": "curl -fsS -H \"Authorization: Bearer $TOKEN\" -o orders.json https://api.example.com/orders",          "env": { "TOKEN": "${{ secrets.API_TOKEN }}" }        }      ]    }  }}
  2. Create the pipeline, or send the definition as a new version. See Definitions and versions.

  3. Start a run and read the log of load. See Start a run and follow it.

Close-out

  1. Make sure that the log shows *** where a secret value is printed.

Push an image to a container registry

Reason for the task: Publish an image from a job, for example to copy a tested image to a release tag.

Job set-up

  • Access: you. For a team, an admin.
  • Conditions: the owner has a container registry connector. See Connectors.
  • References: Registry push.

Procedure

  1. Give the job permissions.registry and an image that contains docker.

    json
    {  "name": "release-image",  "jobs": {    "copy": {      "image": "docker:27-cli",      "permissions": { "registry": "push" },      "steps": [        { "name": "copy", "run": "docker buildx imagetools create -t \"$KL_REGISTRY/alpine:$KL_RUN_NUMBER\" alpine:3.20" }      ]    }  }}
  2. Create the pipeline from the file, and start a run. See Start a run and follow it.

Close-out

  1. Make sure that the job is success.
  2. Make sure that the registry lists the tag with the number of the run.

Run jobs against an environment

Reason for the task: Test or load data against real services, in a copy that the run deletes at its end.

Job set-up

  • Access: you. For a team, an admin to change the definition, and an active member to start the run.
  • Conditions: the environment staging exists for the owner. See Environments.
  • References: Environments.

Procedure

  1. Set environment on the job. A job reaches each service by its name.

    json
    {  "name": "smoke",  "jobs": {    "smoke": {      "environment": { "clone": "staging" },      "packages": ["curl"],      "steps": [{ "name": "health", "run": "curl -fsS http://api:8080/health" }]    }  }}
  2. Create the pipeline from the file. See Create a pipeline.

  3. Start a run. To use another environment for one run, give it in the start request.

    Python
    run = kl.pipelines.run(owner="acme", pipeline="smoke")print(run.wait())
    TypeScript
    const run = await kl.pipelines.run({ owner: "acme", pipeline: "smoke" });console.log(await run.wait());
    Go
    run, err := kl.Pipelines.Run(kloudlite.RunPipeline{Owner: "acme", Pipeline: "smoke"})if err != nil {    log.Fatal(err)}state, err := run.Wait(kloudlite.WaitRun{})if err != nil {    log.Fatal(err)}fmt.Println(state)
    Ruby
    run = kl.pipelines.run(owner: "acme", pipeline: "smoke")puts run.wait
    Java
    var run = kl.pipelines().run(new Kloudlite.RunPipeline().owner("acme").pipeline("smoke"));System.out.println(run.waitFor());
    CLI
    RUN=$(kloudlite pipelines run acme/smoke --json | jq -r .id)kloudlite pipelines wait-run acme smoke "$RUN"

Close-out

  1. Make sure that the run is success.
  2. Show the environments of the owner. Make sure that the copy of staging is gone.

Troubleshooting

SymptomPossible causeCorrective action
422 with secret DB_URL does not existThe owner has no secret with this name. For a team pipeline, the secret is not a secret of the team.Set the secret for the owner of the pipeline.
409 with DB_URL is referenced by pipeline load-ordersA pipeline uses the secret that you tried to delete.Remove the reference and save a new version, then delete the secret.
A secret value shows in a logThe value is shorter than 4 bytes.Use a longer value.
A job fails with no registry is configuredThe owner has no container registry connector.Connect a registry. See Connectors.
A job fails with registry: push needs docker in the job's imageThe image of the job has no docker command.Use an image that contains docker, for example docker:27-cli.
A run fails with cloning staging: …The copy of the environment could not be made.Read the text after the colon. Check the name and the quota of the owner.
A run fails with the clone of staging did not start within 15 minutesThe copy did not start in time.Check the services of the environment, then start the run again.
A run fails with connecting to …: …The platform could not connect the run to the environment.Read the text after the second colon, then start the run again.
A step cannot reach api:8080The job has no environment, or the service has another name or port.Set environment, and use the service name and port of the environment.