Chapter 15Lesson 01~120 minutes

Credentials Store, Secret Text, Files, SSH Keys, Username/Password, Binding, and Secret Hygiene: Concepts, Architecture, and Mental Model

Use Jenkins Credentials as scoped sensitive configuration while minimizing exposure through bindings, processes, workspaces, logs, plugins, agents, and job permissions.

CredentialsSecret hygieneScopesDomainsBindingsLeast privilege

Learning objectives

  • Model a Jenkins credential as sensitive controller configuration whose value is separated from its stable non-secret credential ID.
  • Distinguish credentials providers/stores, System versus Global scope, folder context, and credentials domains without treating domains as access-control boundaries.
  • Explain how withCredentials and Declarative credential helpers expose secrets temporarily through environment variables or files on an agent.
  • Explain masking limits, process/workspace exposure, and why secret-bearing jobs require trusted agents and trusted Pipeline code.
  • Define auditable evidence that proves credential use and cleanup without recording the credential value.

1. The practical problem: a secret must be usable without becoming ordinary build data

Previous chapters established that Jenkins configuration, Pipeline state, agent workspaces, artifacts, and external systems are different state domains. Credentials add a more sensitive state domain. A build may need an API token, an SSH key, a username/password pair, or a configuration file, but the value must not be committed to SCM, copied into a Jenkinsfile, archived as an artifact, or treated like a harmless environment variable.

Jenkins solves the indirection problem by storing credential material in a credentials store and letting jobs refer to a stable credential ID. An authorized binding resolves that ID only while a step needs it. This reduces accidental exposure, but it does not make untrusted Pipeline code safe: code that legitimately receives a secret may still write, transform, or transmit it.

Core rule: a credential binding grants the running code an opportunity to use the credential. Therefore the Jenkinsfile revision, job permissions, agent, plugins, and external destination are part of the credential trust boundary.

2. Mental model: encrypted value → scoped ID → bounded agent use → cleanup

Start with the secret at rest on the controller or an external provider. Jenkins exposes metadata such as an ID, type, description, provider/store, scope, and domain. A job that is allowed to resolve the ID creates a short-lived binding. The binding may become an environment variable, a username/password pair, an SSH private-key file, or a secret file. The build tool consumes it on an agent, Jenkins attempts to mask recognizable console representations, and the temporary binding is removed when the block ends.

Credential lifecycle and trust boundary
flowchart TD
 A[Credential value at rest] --> B[Provider / store / folder context]
 B --> C[Scope + domain metadata]
 C --> D[Stable credential ID]
 D --> E{Authorized job / Pipeline?}
 E -->|no| F[Denied / unavailable evidence]
 E -->|yes| G[Bounded credential binding]
 G --> H[Env var or temporary secret file]
 H --> I[Trusted agent process / tool]
 I --> J[External service authentication]
 H --> K[Console masking is best-effort]
 I --> L[Binding cleanup]
 J --> M[External audit / response evidence]
 L --> N[No secret in artifact / stash / workspace]

The arrows matter: storage does not imply job access; job access does not imply safe use; masking does not imply non-exfiltration; successful authentication does not imply authorization to the requested external operation.

3. Define the credential states before changing them

State What it means Safe evidence Do not record
Type + ID Non-secret selector such as secret text, user/password, SSH key, or file ID, type, description, owner The value itself
Store/context Root System store, user store, or folder store Store path/context name Encrypted XML blobs
Scope Whether a root credential is intended for system use or item use System / Global Assumption that scope alone is all authorization
Domain Service-matching metadata such as host/scheme requirements Domain name and requirements Claim that domain blocks misuse
Binding Temporary exposure to a build step Variable/file name, start/end, job/build Bound secret value
Agent trust Host/process boundary that can receive the secret Node name, label, OS account, workspace Secrets in diagnostics
Rotation Ownership and replacement of secret material behind a stable ID Owner, rotation timestamp/policy Old/new secret contents

4. Credential types encode how a consumer should receive sensitive material

Secret text fits an opaque token. Username/password preserves two related fields. SSH Username with private key gives SSH-aware consumers a username and private-key file. Secret file fits a configuration, certificate, kubeconfig-like test file, or other file-native input. Choosing the type that matches the target tool reduces conversion and accidental logging.

The type is not merely UI decoration. Binding steps expose different variables and files, plugins advertise which kinds they can consume, and rotation procedures differ. A secret text token should not be turned into a workspace file merely because a shell command is convenient.

5. Store, scope, folder context, and domain solve different problems

At the Jenkins root, System scope is intended for Jenkins system functions such as agent launch or controller-level integrations, while Global scope is available to item contexts where visibility and permissions allow it. The Folders plugin adds a per-folder credentials store; credentials in that store use global scope relative to the folder and are available to descendant items. This is a practical least-privilege boundary for team or environment-specific jobs.

Do not confuse domain with authorization. A credentials domain helps a consumer filter candidates based on requirements such as hostname or scheme. The Credentials plugin documentation explicitly treats domains as selection assistance, not as a mechanism that prevents a credential from being used against the wrong service. Restrict access through context, folder structure, permissions, and trusted code.

6. Binding creates a temporary exposure window

withCredentials binds only inside its body and is usually preferable to a Pipeline-wide environment variable because the lifetime is obvious. Declarative environment { NAME = credentials('id') } is convenient, but pipeline-level scope can keep the secret visible to more stages and child processes than necessary. Prefer the narrowest stage/step scope that the tool supports.

withCredentials([string(credentialsId: 'service-token', variable: 'SERVICE_TOKEN')]) {
    sh '''
      set +x
      curl --fail --silent --show-error \
        -H "Authorization: Bearer $SERVICE_TOKEN" \
        https://service.example.invalid/health >/dev/null
    '''
}

Groovy double-quoted interpolation of a secret can place it in the process arguments before the shell sees it. Passing a single-quoted Groovy string lets the shell expand the environment variable later, reducing one exposure path. Still, the agent process receives the value, so the agent must be trusted.

7. Masking is a log-safety aid, not data-loss prevention

The Credentials Binding plugin recognizes common literal and shell-mangled forms and replaces them in console output. That helps with accidental echo or tracing. It cannot reliably mask every transformed representation: encoding, hashing, substring operations, custom tools, files, network requests, crash dumps, or malicious exfiltration can bypass masking.

Masking can help

Accidental literal output and some common shell representations.

Masking cannot authorize

It does not stop a job from reading a bound value.

Masking cannot retract

It cannot remove a secret already archived, stashed, uploaded, or sent over the network.

Masking needs hygiene

Disable shell tracing around secret use and avoid Groovy interpolation.

8. Agent and workspace trust are credential-security state

Environment variables can be visible to other sufficiently privileged processes on the same machine. Secret-file bindings create temporary files on the agent. Workspace browsers, caches, diagnostic bundles, container mounts, and co-located jobs can become exposure paths. Therefore a job that uses production-grade credentials should run only on an appropriately isolated trusted agent pool.

For secret files, placement matters. Binding inside a nested dir('subdir') can cause the temporary secret file to live under that workspace subtree's @tmp/secretFiles. Bind outside the nested directory, use a dedicated isolated workspace when appropriate, and never archive/stash broad workspace globs after secret use.

9. Read-only inspection checklist

  • Record Jenkins core/Java and Credentials/Credentials Binding/SSH Credentials/Folders plugin versions.
  • Record credential IDs, kinds, descriptions, store/folder context, scope, and domain names—never values.
  • Record which job full names are expected to resolve each ID and which should be denied.
  • Record the agent name/label, OS identity, workspace path, and whether other untrusted workloads share that host.
  • Review Jenkinsfile source revision for secret printing, encoding, file copies, broad archives/stashes, and unvalidated network destinations.
  • Record rotation owner and external service identity so revocation is possible after suspected exposure.

10. Common wrong approaches

Wrong approach Why it fails Safer pattern
Put token in Jenkinsfile or parameter Source/history/build metadata may retain it Store credential; reference stable ID
Root-global credential for one team Expands possible consumers Folder/context-scoped store where practical
Domain equals access control Domains are matching hints, not enforcement Folder/context permissions + trusted code
“It is masked, so it is safe” Transforms/files/network can bypass masking Minimize exposure and trust the execution boundary
Run secret job on generic shared agent Local co-tenants may inspect process/file state Dedicated or appropriately isolated trusted agents
Archive **/* after secret use May retain temporary/copy/debug secret material Allowlist exact non-sensitive outputs
Next lesson

Guided Hands-On Workflow and Core Operations

Create four fake credential types in a disposable folder, bind them safely on a trusted lab agent, inspect only metadata, prove cleanup, and verify that a job outside the folder cannot resolve them.

Knowledge check

Why should a Pipeline reference a credential ID instead of embedding the secret value?

Does a credentials domain prevent a job from using a credential against the wrong host?

What is the difference between System and Global credential scope at the Jenkins root?

Why is console masking not sufficient protection from malicious Pipeline code?

What must be trusted before binding a production credential on an agent?

Official references and version notes

Assumption timestamp: 2026-09-17. Recheck core/plugin security advisories and minimum-core requirements before reproducing this lab later.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this address.