fix: keep the instance-admin gate on the global concurrency listing

The listing spans every workspace's concurrency keys, and the gate rejects
only job tokens: the !is_admin branch is the pre-existing check, so
workspaced tokens and interactive admins are unaffected.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
hugocasa
2026-08-07 16:46:01 +02:00
co-authored by Claude Opus 5
parent 5291311c19
commit 530166a5a6
2 changed files with 20 additions and 4 deletions
+16 -1
View File
@@ -467,7 +467,22 @@ async fn test_wm_token_rejected_by_instance_admin_gates(db: Pool<Postgres>) -> a
resp.text().await?
);
// 3. Worker-group config: the static env value must be masked for a job token.
// 3. The sibling listing spans every workspace's concurrency keys, so it is
// gated the same way as the prune above.
let resp = authed(
client().get(format!("{base}/concurrency_groups/list")),
&sa_wm,
)
.send()
.await?;
assert_eq!(
resp.status(),
401,
"superadmin WM_TOKEN must not list global concurrency groups: {}",
resp.text().await?
);
// 4. Worker-group config: the static env value must be masked for a job token.
let body = authed(
client().get(format!("{base}/configs/list_worker_groups")),
&sa_wm,
@@ -1,9 +1,8 @@
use windmill_api_auth::{check_scopes, is_instance_admin, ApiAuthed};
use windmill_api_auth::{check_scopes, is_instance_admin, require_instance_admin, ApiAuthed};
use windmill_common::{
db::{UserDB, DB},
error::Error::PermissionDenied,
error::{self, JsonResult},
utils::require_admin,
};
use crate::query::{filter_list_completed_query, filter_list_queue_query};
@@ -43,7 +42,9 @@ async fn list_concurrency_groups(
authed: ApiAuthed,
Extension(db): Extension<DB>,
) -> JsonResult<Vec<ConcurrencyGroups>> {
require_admin(authed.is_admin, &authed.username)?;
// Instance-global: the listing spans every workspace's concurrency keys, so a job
// token's workspace-admin claim must not reach it (mirrors the prune route below).
require_instance_admin(&authed)?;
let concurrency_counts = sqlx::query_as::<_, (String, i64)>(
"SELECT concurrency_id, (select COUNT(*) from jsonb_object_keys(job_uuids)) as n_job_uuids FROM concurrency_counter",