Title: Add token validation (e.g. `CI_JOB_TOKEN`: probe `/job`) to improve auth diagnostics · Issue #3256 · python-gitlab/python-gitlab · GitHub
Open Graph Title: Add token validation (e.g. `CI_JOB_TOKEN`: probe `/job`) to improve auth diagnostics · Issue #3256 · python-gitlab/python-gitlab
X Title: Add token validation (e.g. `CI_JOB_TOKEN`: probe `/job`) to improve auth diagnostics · Issue #3256 · python-gitlab/python-gitlab
Description: Description of the problem, including code/CLI snippet Generic 401/403s make CI_JOB_TOKEN troubleshooting slow. Users can’t easily tell if a token is a job token, private/OAuth, or just out of scope. One may verify that their CI_JOB_TOKE...
Open Graph Description: Description of the problem, including code/CLI snippet Generic 401/403s make CI_JOB_TOKEN troubleshooting slow. Users can’t easily tell if a token is a job token, private/OAuth, or just out of scop...
X Description: Description of the problem, including code/CLI snippet Generic 401/403s make CI_JOB_TOKEN troubleshooting slow. Users can’t easily tell if a token is a job token, private/OAuth, or just out of scop...
Opengraph URL: https://github.com/python-gitlab/python-gitlab/issues/3256
X: @github
Domain: patch-diff.githubusercontent.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Add token validation (e.g. `CI_JOB_TOKEN`: probe `/job`) to improve auth diagnostics","articleBody":"## Description of the problem, including code/CLI snippet\n\nGeneric 401/403s make `CI_JOB_TOKEN` troubleshooting slow. Users can’t easily tell if a token is a job token, private/OAuth, or just out of scope.\n\nOne may verify that their `CI_JOB_TOKEN` is valid via any of:\n\n```console\n$ wget -O- --header \"JOB-TOKEN: $CI_JOB_TOKEN\" \"${CI_API_V4_URL}/job\" || :\nConnecting to gitlab.xx_xx_xx.com (xx.xx.xx.xx:443)\nwriting to stdout\n{\"id\":xxxxxxx,\"status\":\"running\",\"stage\":\"deploy\",\"name\":\"xx_xxx\",\"ref\":\"xxxxxx/xxxxxxx/debug-job-issue\",\"tag\":false,\"coverage\":null,\"allow_failure\":false,\"created_at\":\"2025-08-25T08:45:12.045Z\",\"started_at\":\"2025-08-25T08:45:21.130Z\",\"finished_at\":null,\"erased_at\":null,\"duration\":11.964642337,\"queued_duration\":8.933698,\"user\":{\"id\":xxxx,\"username\":\"x\",\"name\":\"x\",\"state\":\"active\",\"locked\":false,\"avatar_url\":\"https://secure.gravatar.com/avatar/x?s=80\\u0026d=identicon\",\"web_url\":\"https://gitlab.xx_xx_xx.com/x\",\"created_at\":\"2022-04-11T07:53:06.941Z\"},\"commit\":{\"id\":\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\",\"short_id\":\"xxxxxxxx\",\"created_at\":\"2025-08-22T18:21:27.000+03:00\",\"parent_ids\":[\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"],\"title\":\"debug locally\",\"message\":\"debug locally\\n\\nSigned-off-by: x \\u003cx@users.noreply.gitlab.com\\u003e\\n\",\"author_name\":\"x\",\"author_email\":\"x@users.noreply.gitlab.com\",\"authored_date\":\"2025-08-22T16:51:15.000+03:00\",\"committer_name\":\"x\",\"committer_email\":\"x@users.noreply.gitlab.com\",\"committed_date\":\"2025-08-22T18:21:27.000+03:00\",\"web_url\":\"https://gitlab.xx_xx_xx.com/x-x/x-x/-/commit/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"},\"pipeline\":{\"id\":xxxxxxx,\"iid\":xx,\"project_id\":xxxx,\"sha\":\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\",\"ref\":\"xxxxxx/xxxxxxx/debug-job-issue\",\"status\":\"running\",\"source\":\"web\",\"created_at\":\"2025-08-22T15:21:52.835Z\",\"updated_at\":\"2025-08-25T08:45:12.236Z\",\"web_url\":\"https://gitlab.xx_xx_xx.com/x-x/x-x/-/pipelines/xxxxxxx\"},\"web_url\":\"https://gitlab.xx_xx_xx.com/x-x/x-x/-/jobs/xxxxxxx\",\"project\":{\"ci_job_token_scope_enabled\":false},\"artifacts\":[],\"runner\":{\"id\":xxxxxx,\"description\":\"global-small\",\"active\":true,\"paused\":false,\"is_shared\":true,\"runner_type\":\"instance_type\",\"name\":\"gitlab-runner\",\"online\":true,\"status\":\"online\"},\"runner_manager\":{\"id\":xxxxx,\"system_id\":\"xxxxxxxxxxxxxx\",\"version\":\"xx.xx.x\",\"revision\":\"xxxxxxxx\",\"platform\":\"linux\",\"architecture\":\"amd64\",\"created_at\":\"2025-08-21T00:15:32.832Z\",\"contacted_at\":\"2025-08-25T08:45:32.806Z\",\"ip_address\":\"xx.xxx.x.xxx\",\"status\":\"online\"},\"artifacts_expire_at\":null,\"archived\":false,\"tag_list\":[\"global-small\"]}- 100% |********************************| 2796 0:00:00 ETA\nwritten to stdout\n\n$ wget -O- --header \"JOB-TOKEN: $CI_JOB_TOKEN\" \"${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/environments\" || :\nConnecting to gitlab.xx_xx_xx.com (xx.xx.xx.xx:443)\nwriting to stdout\n[]- 100% |********************************| 2 0:00:00 ETA\nwritten to stdout\n\n$ wget -O- --header \"JOB-TOKEN: $CI_JOB_TOKEN\" \"${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/releases\" || :\nConnecting to gitlab.xx_xx_xx.com (xx.xx.xx.xx:443)\nwriting to stdout\n[]- 100% |********************************| 2 0:00:00 ETA\nwritten to stdout\n```\n\nHowever, trying to use a `CI_JOB_TOKEN` (and failing) can have many causes. In my case, someone \"impersonated\" `CI_JOB_TOKEN` for _some kind of token_.\nI think python-gitlab telling me \"are you sure xyz is indeed a `CI_JOB_TOKEN`, and in-scope (owning job still needs to be running)?\" would've led me to this conclusion faster.\n\nOfc, Gitlab does not \"expose what kind of token X is\" - but `$CI_JOB_TOKEN /job` is a good indicator for a `job_token`.\n\nAdditionally, you have:\n\nhttps://github.com/python-gitlab/python-gitlab/blob/d40d5d2b60ce3e65ed8e6c1ffa4ea70b94059dfa/docs/api-usage.rst?plain=1#L49-L51\n\n\nValidating/Working with a `CI_JOB_TOKEN` can be PITN - I think python-gitlab telling me \"are you sure xyz is indeed a `CI_JOB_TOKEN`?\" would've led me to resolution faster.\n\nNote that `GET /job` is \"immune\" to fine-grained (job token) permissions (https://docs.gitlab.com/ci/jobs/fine_grained_permissions/)\n\n## Expected Behavior\n\nMy suggestion would be \n\nWould you be open in incorporating e.g. `gitlab.http_get(\"/job\")` inside `gl.auth()` when one is using the `job_token=`?\n(I couldn't find an `gitlab.job()` endpoint, hence the `#http_get()`)\n\n## Actual Behavior\n\n\n## Specifications\n\n - python-gitlab version:\n - Gitlab server version (or gitlab.com):\n\n\n## Additionals\n\nOfc, Gitlab does not \"expose what kind of token X is\" - but `$CI_JOB_TOKEN /job` is a good indicator for `job_token`. To be honest, I would've made a troubleshooting command for myself:\n- check `/user` [if token is private],\n- check `/job` [if token is CI_JOB_TOKEN],\n- _moar logic here_\n\nto verify dev's/user's \"claims\" i.e. using `gitlab.Gitlab(url, private_token=private_token)`, `gitlab.Gitlab(url, job_token=job_token)`","author":{"url":"https://github.com/stdedos","@type":"Person","name":"stdedos"},"datePublished":"2025-08-25T11:09:21.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":3},"url":"https://github.com/3256/python-gitlab/issues/3256"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:0a1c7646-8dac-bc8a-8dc9-13afd2bab4ad |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | B640:1B6BE9:84D4339:ABCBC96:6975D480 |
| html-safe-nonce | eb5724444743f772a7ab1b174c91ee6e56fc100e584c907d9ecd2288d94f27d5 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJCNjQwOjFCNkJFOTo4NEQ0MzM5OkFCQ0JDOTY6Njk3NUQ0ODAiLCJ2aXNpdG9yX2lkIjoiMjY3MDUzNjU4MjUzMTI0MTA4OCIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | ff9832b56448fb609cc66907455607bda6935a948bda2c6c83a9ac4571045427 |
| hovercard-subject-tag | issue:3351416444 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/python-gitlab/python-gitlab/3256/issue_layout |
| twitter:image | https://opengraph.githubassets.com/f17f925798381f00720d52fead6dc4e55c4292278d7b0af2ff741fafb0ab3525/python-gitlab/python-gitlab/issues/3256 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/f17f925798381f00720d52fead6dc4e55c4292278d7b0af2ff741fafb0ab3525/python-gitlab/python-gitlab/issues/3256 |
| og:image:alt | Description of the problem, including code/CLI snippet Generic 401/403s make CI_JOB_TOKEN troubleshooting slow. Users can’t easily tell if a token is a job token, private/OAuth, or just out of scop... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | stdedos |
| hostname | github.com |
| expected-hostname | github.com |
| None | 2bce766e7450b03e00b2fc5badd417927ce33a860e78cda3e4ecb9bbd1374cc6 |
| turbo-cache-control | no-preview |
| go-import | github.com/python-gitlab/python-gitlab git https://github.com/python-gitlab/python-gitlab.git |
| octolytics-dimension-user_id | 28886265 |
| octolytics-dimension-user_login | python-gitlab |
| octolytics-dimension-repository_id | 8077625 |
| octolytics-dimension-repository_nwo | python-gitlab/python-gitlab |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 8077625 |
| octolytics-dimension-repository_network_root_nwo | python-gitlab/python-gitlab |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | fcca2b8ef702b5f7f91427a6e920fa44446fe312 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width