Jenkins credential add/create, obfuscate in logs and clean/remove within build pipeline run

How can I compute a credential at run time and add it to Jenkins credentials store (to be used later in the code with credentialsId reference)? How can I clean it from within pipeline workflow once no longer needed? This is specifically for a use-case of:

  1. have centrally-managed authentication solution with OIDC, such as Keycloak,
  2. use Keycloak service account credentials stored in Jenkins at folder level,
  3. use artifact storage solution that exchanges temporary identity token from Keycloak for an access token to such storage solution (this can be managed with cURL calls in shell script or HttpURLConnection class in direct Java/Groovy code implementation - that’s kind of easy to implement),
  4. configure a new temporary credential on folder level (or better yet this build only) scope into Jenkins credential store from within pipeline code to be used interchangeably with older/hard-coded credentials logic to access artifact storage,
  5. guarantee that newly created access token is not exposed by Jenkins build/run logs same as for credentials processed with withCredentials() block,
  6. clean/remove such credential after the operations for which the token was retrieved are complete.

Using: linux docker container of index.docker.io/jenkins/jenkins:2.504.2-lts

Jenkins setup:
Jenkins: 2.504.2
OS: Linux - 5.14.0-427.28.1.el9_4.x86_64
Java: 21.0.7 - Eclipse Adoptium (OpenJDK 64-Bit Server VM)
Plugins:

  • Office-365-Connector:5.1.0
  • analysis-model-api:13.2.0
  • ansicolor:1.0.6
  • ant:513.vde9e7b_a_0da_0f
  • antisamy-markup-formatter:173.v680e3a_b_69ff3
  • apache-httpcomponents-client-4-api:4.5.14-269.vfa_2321039a_83
  • apache-httpcomponents-client-5-api:5.5-150.veb_76e719855b_
  • artifactory:4.0.8
  • asm-api:9.8-135.vb_2239d08ee90
  • audit-trail:395.vce180b_359a_b_5
  • authentication-tokens:1.131.v7199556c3004
  • badge:2.8
  • basic-branch-build-strategies:228.v68c089762a_db_
  • bitbucket-filter-project-trait:1.0
  • bitbucket-oauth:0.14
  • bitbucket-scm-filter-aged-refs:59.vc6b_39c26988c
  • bitbucket-scm-filter-jira-validator:0.1.0
  • bitbucket-scm-trait-commit-skip:0.4.0
  • blueocean:1.27.20
  • blueocean-autofavorite:1.2.5
  • blueocean-bitbucket-pipeline:1.27.20
  • blueocean-commons:1.27.20
  • blueocean-config:1.27.20
  • blueocean-core-js:1.27.20
  • blueocean-dashboard:1.27.20
  • blueocean-display-url:2.4.4
  • blueocean-events:1.27.20
  • blueocean-git-pipeline:1.27.20
  • blueocean-github-pipeline:1.27.20
  • blueocean-i18n:1.27.20
  • blueocean-jira:1.27.20
  • blueocean-jwt:1.27.20
  • blueocean-personalization:1.27.20
  • blueocean-pipeline-api-impl:1.27.20
  • blueocean-pipeline-editor:1.27.20
  • blueocean-pipeline-scm-api:1.27.20
  • blueocean-rest:1.27.20
  • blueocean-rest-impl:1.27.20
  • blueocean-web:1.27.20
  • bootstrap5-api:5.3.5-1
  • bouncycastle-api:2.30.1.80-261.v00c0e2618ec3
  • branch-api:2.1217.v43d8b_b_d8b_2c7
  • build-timestamp:1.1.0
  • caffeine-api:3.2.0-166.v72a_6d74b_870f
  • checks-api:370.vb_61a_c57328f3
  • cloudbees-bitbucket-branch-source:936.4.0
  • cloudbees-disk-usage-simple:241.v0ea_d9a_a_96ee8
  • cloudbees-folder:6.1023.v4fcb_72152519
  • command-launcher:123.v37cfdc92ef67
  • commons-collections4-api:4.5.0-8.va_d5448ef9011
  • commons-compress-api:1.27.1-3
  • commons-lang3-api:3.17.0-87.v5cf526e63b_8b_
  • commons-text-api:1.13.1-176.v74d88f22034b_
  • config-file-provider:988.v0461fcc2b_9d1
  • configuration-as-code:1971.vf9280461ea_89
  • conventional-commits:0.11.2
  • credentials:1415.v831096eb_5534
  • credentials-binding:687.v619cb_15e923f
  • data-tables-api:2.2.2-1
  • dependency-track:6.0.1
  • display-url-api:2.209.v582ed814ff2f
  • docker-commons:457.v0f62a_94f11a_3
  • docker-workflow:621.va_73f881d9232
  • dtkit-api:3.0.3
  • durable-task:587.v84b_877235b_45
  • echarts-api:5.6.0-4
  • eddsa-api:0.3.0.1-19.vc432d923e5ee
  • emoji-symbols-api:16.0-26.v9818ff7423f0
  • extended-read-permission:61.vf24570ff3b_e9
  • favorite:2.237.v79163ca_8b_892
  • flatpickr-api:4.6.13-18.vcf5f6a_5b_8468
  • font-awesome-api:6.7.2-1
  • forensics-api:3.1.0
  • git:5.7.0
  • git-changelog:3.45
  • git-client:6.1.3
  • github:1.43.0
  • github-api:1.321-488.v9b_c0da_9533f8
  • github-branch-source:1822.v9eec8e5e69e3
  • google-compute-engine:4.683.v0ce26579a_ee7
  • google-login:109.v022b_cf87b_e5b_
  • google-metadata-plugin:0.6.70.v87a_e90994a_32
  • google-oauth-plugin:1.335.ve6de40e2db_18
  • google-source-plugin:0.4
  • gradle:2.15
  • groovy-postbuild:272.v52a_03efb_8653
  • gson-api:2.13.1-139.v4569c2ef303f
  • handy-uri-templates-2-api:2.1.8-36.v85e4cb_234a_13
  • htmlpublisher:425
  • influxdb:5.0
  • instance-identity:203.v15e81a_1b_7a_38
  • ionicons-api:88.va_4187cb_eddf1
  • jackson2-api:2.18.3-402.v74c4eb_f122b_2
  • jakarta-activation-api:2.1.3-2
  • jakarta-mail-api:2.1.3-2
  • javadoc:327.vdfe586651ee0
  • javax-activation-api:1.2.0-8
  • javax-mail-api:1.6.2-11
  • jaxb:2.3.9-133.vb_ec76a_73f706
  • jdk-tool:83.v417146707a_3d
  • jenkins-design-language:1.27.20
  • jersey2-api:2.45-154.v4ded3dc34f81
  • jfrog:1.5.8
  • jira:3.17
  • jjwt-api:0.11.5-120.v0268cf544b_89
  • job-dsl:1.93
  • joda-time-api:2.14.0-127.v7d9da_295a_d51
  • jquery3-api:3.7.1-3
  • jsch:0.2.16-95.v3eecb_55fa_b_78
  • json-api:20250517-153.vc8a_a_d87c0ce3
  • json-path-api:2.9.0-148.v22a_7ffe323ce
  • jsoup:1.20.1-46.ve5f1416988c2
  • junit:1335.v6b_a_a_e18534e1
  • kafkalogs:0.1.8
  • kerberos-sso:247.v5b_3c2105a_9e3
  • kubernetes:4353.vb_47977da_9417
  • kubernetes-client-api:6.10.0-251.v556f5f100500
  • kubernetes-credentials:192.v4d5b_1c429d17
  • lockable-resources:1349.v8b_ccb_c5487f7
  • mailer:489.vd4b_25144138f
  • matrix-auth:3.2.6
  • matrix-project:849.v0cd64ed7e531
  • maven-plugin:3.26
  • mercurial:1309.v6802b_f0efb_b_9
  • metrics:4.2.32-476.v5042e1c1edd7
  • mina-sshd-api-common:2.15.0-161.vb_200831a_c15b_
  • mina-sshd-api-core:2.15.0-161.vb_200831a_c15b_
  • multibranch-action-triggers:1.8.10
  • oauth-credentials:0.657.v7d8dd90b_0382
  • okhttp-api:4.11.0-189.v976fa_d3379d6
  • oss-symbols-api:324.v432cce4172ca_
  • parameter-separator:276.v7b_5328f5c7a_d
  • people-view:1.2
  • pipeline-build-step:567.vea_ce550ece97
  • pipeline-graph-analysis:241.vc3d48fb_b_2582
  • pipeline-groovy-lib:752.vdddedf804e72
  • pipeline-input-step:527.vd61b_1d3c5078
  • pipeline-milestone-step:138.v78ca_76831a_43
  • pipeline-model-api:2.2255.v56a_15e805f12
  • pipeline-model-definition:2.2255.v56a_15e805f12
  • pipeline-model-extensions:2.2255.v56a_15e805f12
  • pipeline-multibranch-defaults:2.1
  • pipeline-rest-api:2.38
  • pipeline-stage-step:322.vecffa_99f371c
  • pipeline-stage-tags-metadata:2.2255.v56a_15e805f12
  • pipeline-stage-view:2.38
  • pipeline-utility-steps:2.19.0
  • plain-credentials:195.vb_906e9073dee
  • plugin-util-api:6.1.0
  • prism-api:1.30.0-1
  • prometheus:819.v50953a_c560dd
  • pubsub-light:1.19
  • robot:6.0.0
  • role-strategy:777.v4fe2599cb_f48
  • run-condition:243.v3c3f94e46a_8b_
  • schedule-build:667.vda_a_fe31e1659
  • scm-api:704.v3ce5c542825a_
  • script-security:1373.vb_b_4a_a_c26fa_00
  • simple-theme-plugin:211.v5424a_5510e47
  • snakeyaml-api:2.3-125.v4d77857a_b_402
  • sonar:2.18
  • sse-gateway:1.28
  • ssh-agent:386.v36cc0c7582f0
  • ssh-credentials:355.v9b_e5b_cde5003
  • ssh-slaves:3.1031.v72c6b_883b_869
  • sshd:3.353.v2b_d33c46e970
  • stash-pullrequest-builder:1.17
  • structs:350.v3b_30f09f2363
  • support-core:1725.va_2a_9f06eed61
  • tap:2.4.4
  • token-macro:444.v52de7e9c573d
  • trilead-api:2.209.v0e69b_c43c245
  • variant:70.va_d9f17f859e0
  • warnings-ng:12.6.0
  • workflow-aggregator:608.v67378e9d3db_1
  • workflow-api:1373.v7b_813f10efa_b_
  • workflow-basic-steps:1079.vce64b_a_929c5a_
  • workflow-cps:4106.v7a_8a_8176d450
  • workflow-durable-task-step:1405.v1fcd4a_d00096
  • workflow-job:1532.va_9a_d244074a_3
  • workflow-multibranch:806.vb_b_688f609ee9
  • workflow-scm-step:437.v05a_f66b_e5ef8
  • workflow-step-api:700.v6e45cb_a_5a_a_21
  • workflow-support:968.v8f17397e87b_8
  • xunit:3.1.5

Technically possible. You would need to write a pipeline library that is then added as a globally trusted library. That is not straightforward, you need to look at the code of the credentials plugin how to add a new credential programmatically.
Ideally you write a step that allows to execute a block (Extending with Shared Libraries) so that you have automatic cleanup. In the end you would call it like this, where you defined a new step with name withTemporaryToken. The step will set an env variable with name TEMPORARY_CREDENTIALSID. Assumption is that you create a credential of type Secret text

def token = createNewToken(...)  // this will create the new token value
withTemporaryToken(token) {
  withCredentials([string(credentialsId: TEMPORARY_CREDENTIALSID, variable: 'SECRET')]) {
    // do something with the secret
  }
  // or call another step that has a credentialsID as parameter
}

The new step would need to call that block in a try finally block where in the finally you remove the credential from the store. Something like this in a file vars/withTemporaryToken.groovy

def call(storeLocation, tokenValue, Closure body)
  def credentialId = createCredentials(storeLocation, tokenValue)
  try {
    withEnv(['TEMPORARY_CREDENTIALSID=' + credentialId]) {
      body()
    }
  } finally {
    removeCredential(storeLocation, credentialId)
  }
}