Proxy for a Jenkins controller through the managed gateway. Routes use a
non-terminal path wildcard, so any nested job URL (/job/foo/job/bar/...) is
accepted and gated by PBAC policy.
Authentication
Jenkins does not accept IdP-issued OAuth bearer tokens on its REST API — it
authenticates with a username + API token over HTTP Basic. This connector
supports two auth modes, chosen per managed resource at install time via the
Authentication field:
- Per-user credential (
user_secret, default, recommended) — each user
links their own Jenkins username + API token once, through a PolicyArc-hosted
browser page reached by MCP URL elicitation on the first call. The credential
posts only to the AS (never through the MCP client or the model), is stored
encrypted per (subject, resource), and is sent as
Authorization: Basic base64(user:token) on that user's calls — so Jenkins
attributes every build and action to the real user. If the token later
expires, the upstream 401 triggers a re-link prompt.
- Shared service credential (
static) — every call uses one operator-held
credential from the basic_auth_env secret (value = base64(user:apitoken)),
sent verbatim as the HTTP Basic credential. Jenkins attributes all calls to
that one account.
Either way, PolicyArc enforces per-user authorization at the gateway via policy
before the request reaches Jenkins. See
Per-user upstream credentials for how the user_secret
collection flow works.
Setup
base_url — your Jenkins controller URL, e.g. https://jenkins.example.com.
upstream_auth.type — user_secret (default) or static.
basic_auth_env — static mode only — a secret whose value is
base64(user:apitoken) (e.g. printf %s 'user:APITOKEN' | base64). Hidden
when user_secret is selected.
Creating a Jenkins API token
Jenkins → your name (top-right) → Security → API Token → Add new
token. In user_secret mode each user does this for themselves on the
collection page; in static mode the operator does it once for the shared
service account.
Troubleshooting
- 401 from Jenkins — the username / API token is missing, wrong, or
revoked. In
user_secret mode the gateway re-prompts the user to reconnect;
in static mode check the basic_auth_env secret.
- 403 from the gateway — the caller lacks the scope the route requires.
- 403 from Jenkins — the authenticated user lacks permission on that job.
Manifest reference
- ID:
identos.jenkins
- Version:
1.3.0
- Resource type:
urn:connector:identos:jenkins
- Capabilities:
mcp
Supported auth modes
| Type | Details |
|---|
user_secret | — |
static | scheme basic; setup fields: basic_auth_env |
Setup fields
| ID | Label | Default | Secret? | Notes |
|---|
base_url | Jenkins base URL | — | no | placeholder: https://jenkins.example.com |
upstream_auth.type | Authentication | user_secret | no | user_secret (recommended) has each user link their own Jenkins username + API token, so builds are attributed to the real user. static uses one shared API token for everyone. |
basic_auth_env | Basic auth credentials | — | yes | Used only for the static method. A secret whose value is base64(user:apitoken) — e.g. `printf %s 'user:APITOKEN' |
Scopes
| Scope |
|---|
jenkins:read |
jenkins:execute |
Routes
| Method | Pattern | Scope | Resource template |
|---|
GET | /api/json | jenkins:read | jenkins://jobs |
POST | /{job_path:.*}/build | jenkins:execute | jenkins://jobs/{{job_path}} |
POST | /{job_path:.*}/buildWithParameters | jenkins:execute | jenkins://jobs/{{job_path}} |
GET | /{job_path:.*}/{build_number}/api/json | jenkins:read | jenkins://jobs/{{job_path}}/builds/{{build_number}} |
GET | /{job_path:.*}/{build_number}/consoleText | jenkins:read | jenkins://jobs/{{job_path}}/builds/{{build_number}} |
GET | /{job_path:.*}/{build_number}/artifact/{artifact_path:.*} | jenkins:read | jenkins://jobs/{{job_path}}/builds/{{build_number}} |
GET | /{job_path:.*}/config.xml | jenkins:read | jenkins://jobs/{{job_path}} |
| Name | Scope | Description |
|---|
list_jobs | jenkins:read | List the jobs and folders on the controller — the discovery entry point. Every other Jenkins tool needs a job_path; this is how you find one. Jobs nest in folders, so pass tree to recurse: start with jobs[name,url,jobs[name,url]]. Add a level only if you must — multibranch projects expose every branch and MR as a child job, so a third level can run to megabytes and overflow the result limit. job_path is each entry's url minus the base URL. Pair with get_job_config for a job's SCM remote. |
execute_job | jenkins:execute | Trigger a Jenkins job build. job_path is the path segment from /job/... to the job root (no trailing slash). |
execute_job_with_parameters | jenkins:execute | Trigger a build of a PARAMETERIZED Jenkins job. parameters is a flat object, e.g. {"BRANCH": "main"}. Parameter names come from the job — read them from get_job_config (<parameterDefinitions>). Jenkins silently ignores a name the job does not declare, so a typo builds with the job's defaults instead of erroring. Values are scalars. Use execute_job for a job that takes none. Returns 201 with a queue-item Location, not a build number: poll get_build_status with lastBuild. |
get_build_status | jenkins:read | Get the JSON status for a build of a Jenkins job. Use the permalink 'lastCompletedBuild' to read the most recent finished build without knowing its number; the response's 'nextBuild' / 'previousBuild' fields walk the history from there. |
get_build_console | jenkins:read | Get the console text for a build of a Jenkins job. |
get_build_artifact | jenkins:read | Fetch an archived artifact from a specific build — e.g. an SBOM or a Grype vulnerability report. artifact_path is the artifact's relativePath as listed under 'artifacts' by get_build_status, and may contain slashes. |
get_job_config | jenkins:read | Read a job's config.xml — the only place the SCM remote and pipeline script path are exposed. Use after list_jobs to answer 'which job builds repo X'. The shape depends on job type. Multibranch: <sources> … <source> carries <sshRemote>, <httpRemote> and <projectPath>, and the script path is <factory><scriptPath>. Freestyle/classic pipeline: <scm> with <url> and <branches>, script path at <definition><scriptPath>. Returns XML, not JSON. Folders have a config.xml but no SCM — point this at a job. |