SecretText vs File Credentials: Binding to Environment Variables or Temporary Files in Jenkins Pipelines?
0 reputation · 24 May 2026, 12:39 UTC
0 reputation · 24 May 2026, 12:39 UTC
The goal is to run integration tests that require a secret token without pulling in production credentials. The Jenkins Credentials Binding plugin offers withCredentials blocks that can bind SecretText and File types to environment variables or temporary files.
In scripted pipelines, I need the secret token as a file for a downstream script, but the plugin only writes File credentials to disk. Binding a SecretText to a file is not documented and appears to fail with an “unsupported binding” error.
Additionally, the API does not allow multiple credentials of the same type in a single withCredentials call, which would simplify passing several tokens to different tools.
Is there a supported way to bind a SecretText credential to a temporary file in a scripted pipeline, or must I create a File credential instead? Can I bind multiple SecretText credentials simultaneously, or is the current API limited to one per type?
No built-in binding writes a SecretText value to a temporary file. secretText and string bindings expose the secret only as an environment variable inside the withCredentials block. If your downstream script strictly requires a file path, use a File credential, or manually write the SecretText variable to a private file and delete it before the block ends.
Yes. You can bind multiple SecretText credentials in one withCredentials call, provided each binding uses a distinct variable name. The one-per-type limit is not general plugin behavior.
The "unsupported binding" error you reported is consistent with passing a SecretText credential ID to file(). The plugin expects file() to reference a File credential; it does not auto-materialize text secrets to disk.
File credentials bind to a temporary file path variable scoped to the withCredentials block.SecretText bindings bind to an environment variable only.File credential when the tool needs a path:withCredentials([file(credentialsId: 'integration-token-file', variable: 'TOKEN_FILE')]) {
sh './run-integration-tests.sh --token-file "$TOKEN_FILE"'
}
SecretText credential by writing it yourself:withCredentials([string(credentialsId: 'integration-token-text', variable: 'TOKEN')]) {
def secretFile = "${env.HOME}/.jenkins-secrets/token-${env.BUILD_ID}.txt"
sh "mkdir -p \$(dirname ${secretFile}) && chmod 700 \$(dirname ${secretFile})"
writeFile(file: secretFile, text: env.TOKEN)
try {
sh "chmod 600 ${secretFile} && ./run-integration-tests.sh --token-file ${secretFile}"
} finally {
sh "rm -f ${secretFile}"
}
}
withCredentials([
string(credentialsId: 'token-a', variable: 'TOKEN_A'),
string(credentialsId: 'token-b', variable: 'TOKEN_B')
]) {
sh './run-integration-tests.sh --token-a "$TOKEN_A" --token-b "$TOKEN_B"'
}
Run this in a non-production test job:
withCredentials([
string(credentialsId: 'test-secret-text', variable: 'TOKEN'),
file(credentialsId: 'test-secret-file', variable: 'SECRET_FILE')
]) {
sh 'echo TOKEN_SET; echo "FILE=$SECRET_FILE"; test -f "$SECRET_FILE" && echo FILE_EXISTS'
}
After the block completes, confirm the temporary file path no longer exists and that console output shows masked values rather than the secret. Avoid echoing $TOKEN or passing it as a command argument where it can be logged; environment-variable masking does not protect file contents or child-process argument lists.
Does your downstream script accept the token through standard input, or does it strictly require a file path? If it accepts stdin, you can avoid writing the secret to disk entirely.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.