fix: gate the credential pass budget on the features that use it

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C1xHmkxuxYb1GYvth1BS75
This commit is contained in:
hugocasa
2026-09-07 11:50:36 +02:00
co-authored by Claude Opus 5
parent c5132ead3d
commit b683b14da7
3 changed files with 26 additions and 27 deletions
+16 -14
View File
@@ -354,7 +354,9 @@ pub async fn initial_load(
)
}
});
pass.action(windmill_common::min_version::store_min_keep_alive_version(db));
pass.action(windmill_common::min_version::store_min_keep_alive_version(
db,
));
pass.setting(
windmill_common::global_settings::INSTANCE_EVENTS_WEBHOOK_SETTING,
false,
@@ -709,7 +711,6 @@ pub async fn initial_load(
pass.run(conn).await;
}
pub fn apply_metrics_enabled(value: Option<serde_json::Value>) {
if let Some(serde_json::Value::Bool(t)) = value {
METRICS_ENABLED.store(t, Ordering::Relaxed)
@@ -1066,8 +1067,8 @@ pub fn apply_fork_workspace_tag_append_fork_suffix(value: Option<serde_json::Val
}
pub async fn reload_critical_alert_mute_ui_setting(conn: &Connection) -> error::Result<()> {
let v =
load_value_from_global_settings_with_conn(conn, CRITICAL_ALERT_MUTE_UI_SETTING, true).await?;
let v = load_value_from_global_settings_with_conn(conn, CRITICAL_ALERT_MUTE_UI_SETTING, true)
.await?;
apply_critical_alert_mute_ui_setting(v);
Ok(())
}
@@ -2732,7 +2733,6 @@ pub async fn reload_timeout_wait_result_setting(conn: &Connection) {
.await;
}
pub async fn reload_extra_pip_index_url_setting(conn: &Connection) {
reload_option_setting_with_tracing(
conn,
@@ -2823,7 +2823,6 @@ pub async fn reload_bunfig_install_scopes_setting(conn: &Connection) {
.await;
}
pub async fn reload_nuget_config_setting(conn: &Connection) {
reload_option_setting_with_tracing(
conn,
@@ -2931,7 +2930,6 @@ pub async fn reload_ruby_repos_setting(conn: &Connection) {
.await;
}
pub async fn reload_workspace_registries_setting(conn: &Connection) {
match load_value_from_global_settings_with_conn(
conn,
@@ -3185,7 +3183,6 @@ pub async fn apply_job_isolation_setting(value: Option<serde_json::Value>) {
}
}
async fn resolve_license_key_value(conn: &Connection, quiet: bool) -> anyhow::Result<String> {
let q = load_value_from_global_settings_with_conn(conn, LICENSE_KEY_SETTING, true)
.await
@@ -3480,7 +3477,10 @@ impl<'a> SettingsPass<'a> {
// on compile-time defaults until the next full reload. Only the single-query transport
// can fail this way; over HTTP the batch already is the per-setting read.
if matches!(conn, Connection::Sql(_)) && values.is_empty() && !names.is_empty() {
tracing::warn!("Falling back to per-setting reads for {} settings", names.len());
tracing::warn!(
"Falling back to per-setting reads for {} settings",
names.len()
);
values = fetch_settings_individually(conn, &names).await;
}
for (name, http) in &declared {
@@ -3872,7 +3872,6 @@ pub fn parse_setting_value<T: FromStr + DeserializeOwned + Display>(
value
}
#[cfg(feature = "prometheus")]
pub async fn monitor_pool(db: &DB) {
if METRICS_ENABLED.load(Ordering::Relaxed) {
@@ -4718,6 +4717,7 @@ const GIT_CREDENTIAL_LOCK_ID: i64 = 737_483_923;
/// rotation must never be cancelled between GitLab issuing a token and Windmill
/// storing it, so the pass stops at a repository boundary instead and the
/// least-recently-checked ordering brings the rest along on the next tick.
#[cfg(all(feature = "enterprise", feature = "private"))]
const GIT_CREDENTIAL_PASS_BUDGET: Duration = Duration::from_secs(180);
/// Refresh every git-sync repository's credential status and rotate the ones near
@@ -4856,9 +4856,12 @@ async fn maintain_git_credentials_inner(db: &Pool<Postgres>) -> error::Result<()
});
if needs_hook {
let mut repo = repo.clone();
if let Err(e) =
windmill_common::git_sync_ee::sync_repo_webhook(db, &row.workspace_id, &mut repo)
.await
if let Err(e) = windmill_common::git_sync_ee::sync_repo_webhook(
db,
&row.workspace_id,
&mut repo,
)
.await
{
tracing::warn!(
"git credentials: could not reconcile the webhook for {path} in workspace {}: {e:#}",
@@ -6773,7 +6776,6 @@ pub async fn reload_critical_alerts_on_db_oversize(conn: &DB) -> error::Result<(
Ok(())
}
pub async fn reload_jwt_secret_setting(db: &DB) -> error::Result<()> {
let v = load_value_from_global_settings(db, JWT_SECRET_SETTING).await?;
apply_jwt_secret_setting(db, v).await
@@ -1384,7 +1384,7 @@ async fn maybe_post_git_sync_check(
(None, Some(deploy)) => (true, deploy),
(None, None) => return,
};
let Ok(mut check) = serde_json::from_value::<GitSyncCheck>(marker) else {
let Ok(check) = serde_json::from_value::<GitSyncCheck>(marker) else {
return;
};
// Job args are persisted, so the repository URL is not among them: it is
@@ -1395,7 +1395,11 @@ async fn maybe_post_git_sync_check(
// carries the identity to check it against. A marker written before that
// identity existed keeps using the URL it captured at enqueue, which cannot
// have been repointed since.
let repo_url = match (check.repo.is_some(), row.repo_path.as_deref(), check.repo_url.clone()) {
let repo_url = match (
check.repo.is_some(),
row.repo_path.as_deref(),
check.repo_url.clone(),
) {
// The resource path is mutable, so following it is only safe when the
// marker also carries the identity to check the result against.
(true, Some(path), _) => {
@@ -1426,8 +1430,7 @@ async fn maybe_post_git_sync_check(
};
// A resource repointed while the diff was running would otherwise close a
// check, or post a preview, on a repository that has nothing to do with it.
if check.repo.is_some()
&& windmill_common::git_sync_ee::repo_identity(&repo_url) != check.repo
if check.repo.is_some() && windmill_common::git_sync_ee::repo_identity(&repo_url) != check.repo
{
tracing::warn!(
"git sync-check: the repository moved since the check was created; leaving it alone"
@@ -1,11 +1,6 @@
<script lang="ts">
import type { Schema } from '$lib/common'
import {
ResourceService,
WorkspaceService,
type Resource,
type ResourceType
} from '$lib/gen'
import { ResourceService, WorkspaceService, type Resource, type ResourceType } from '$lib/gen'
import { canWrite } from '$lib/utils'
import { createEventDispatcher, untrack } from 'svelte'
import { userStore, workspaceStore } from '$lib/stores'
@@ -411,9 +406,8 @@
<Alert type="info" title="Windmill holds this repository's access token">
<div class="flex flex-col items-start gap-2">
<div>
The URL below carries no credential. Windmill renews the token before it expires and
hands it to this workspace's sync jobs, and forks of this workspace use it without
storing their own copy.
The URL carries no credential. Windmill stores the token and renews it before it
expires.
{#if urlDirty}
Save your URL change to replace the token.
{/if}