Jacamar CI v0.30.0
Release: v0.30.0
Date: October 1, 2026
Important
This release contains a fix for CVE-2026-107589 and it is highly
recommended that you update your deployments as soon as possible.
Security Fixes
Improve GitLab bot check and associated warnings (!701)
Any version of Jacamar CI before v0.30.0 is affected when used with GitLab Server v13.11 or later, or with v13.10 when the allow_projects_to_create_service_accounts feature flag is enabled. Authenticated users can create and leverage Service Accounts to trigger CI/CD jobs. Before this release, Jacamar CI did not adequately check for arbitrarily named bot accounts, a newer server-side feature. GitLab does not provide a server-side mechanism to limit these accounts. This release provides a more reliable way to identify and prevent these accounts from being used.
Preparing the "custom" executor Bot account token used for job, unsupported by runner Error encountered during job: you are currently unauthorized to use this runner (refer to system logs for additional details) ERROR: Preparation failed: exit status 2
If you are unable to upgrade and apply this fix, you can achieve a similar workflow with a RunAs validation script. This lets your validation script reject jobs triggered by bot accounts.
#!/bin/bash # RunAs Validation Script # https://ecp-ci.gitlab.io/docs/admin/jacamar/auth.html#runas-user set -euo pipefail json_error() { local msg="$1" jq -cn --arg error_message "$msg" '{error_message: $error_message}' exit 1 } require_var() { local name="$1" if [[ -z "${!name:-}" ]]; then json_error "Required environment variable '${name}' is not set" fi } # The GitLab API token must be created by you with read_api permissions to # all potential projects that will utilize your runner. The best option would # be to inject them into the file (or load them from another). The user # responsible for Jacamar CI execution will be the run using this script. # GITLAB_API_TOKEN=??? # GITLAB_SERVER_URL=??? require_var GITLAB_API_TOKEN require_var GITLAB_SERVER_URL # These will be provided by Jacamar to the validation script. require_var JWT_PROJECT_ID require_var JWT_JOB_ID require_var JWT_USER_LOGIN command -v curl >/dev/null 2>&1 || json_error "curl is required but not installed" command -v jq >/dev/null 2>&1 || json_error "jq is required but not installed" API_URL="${GITLAB_SERVER_URL%/}/api/v4/projects/${JWT_PROJECT_ID}/jobs/${JWT_JOB_ID}" RESPONSE="$( curl --silent --show-error \ --write-out $'\n%{http_code}' \ --header "PRIVATE-TOKEN: ${GITLAB_API_TOKEN}" \ "${API_URL}" )" || json_error "Failed to contact GitLab API at '${API_URL}'" HTTP_CODE="$(printf '%s\n' "${RESPONSE}" | tail -n1)" BODY="$(printf '%s\n' "${RESPONSE}" | sed '$d')" if [[ "${HTTP_CODE}" -lt 200 || "${HTTP_CODE}" -ge 300 ]]; then if printf '%s' "${BODY}" | jq empty >/dev/null 2>&1; then BODY="$(printf '%s' "${BODY}" | jq -c .)" fi json_error "GitLab API request failed with HTTP ${HTTP_CODE}: ${BODY}" fi printf '%s' "${BODY}" | jq empty >/dev/null 2>&1 || json_error "GitLab API returned invalid JSON" BOT_VALUE="$(printf '%s' "${BODY}" | jq -r '.user.bot')" USERNAME="$(printf '%s' "${BODY}" | jq -r '.user.username')" if [[ "${BOT_VALUE}" != "false" ]]; then json_error "GitLab job '${JWT_JOB_ID}' was triggered by a bot" fi if [[ "${USERNAME}" != "${JWT_USER_LOGIN}" ]]; then json_error "JWT_USER_LOGIN '${JWT_USER_LOGIN}' does not match GitLab username '${USERNAME}'" fi jq -cn --arg username "${USERNAME}" '{username: $username}' exit 0
User Changes
Admin Changes
GIT_ASKPASScorrections and global config override (!693)