* [ee] fix(autoscaling): only divide native_mode pings by NUM_WORKERS
#9020 / EE #548 changed worker counting to COUNT(DISTINCT worker_instance) to
fix native-mode over-counting (NUM_WORKERS=8 pings per pod). That collapsed
custom worker groups that share a hostname across multiple worker processes
to a count of 1, breaking their autoscaling.
EE fix uses the per-ping native_mode flag: divide native rows by 8 (CEIL),
count non-native rows as-is.
Companion EE PR: windmill-labs/windmill-ee-private#fix-autoscaling-custom-worker-group-count
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore: update ee-repo-ref to abeb405de36a3fe23382f19e762268f87b6679be
This commit updates the EE repository reference after PR #582 was merged in windmill-ee-private.
Previous ee-repo-ref: 135db676843346ed6e3015232161a49c3ce01db5
New ee-repo-ref: abeb405de36a3fe23382f19e762268f87b6679be
Automated by sync-ee-ref workflow.
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
* feat(snowflake): derive public key from private key when omitted (WIN-1959)
Snowflake key-pair auth needs a SHA256 fingerprint of the public key for
the JWT iss claim, but the public key is mathematically derivable from
the RSA private key. Other tools (e.g. Power BI) only require the
private key, so requiring users to supply both is redundant. When
public_key is missing, fall back to deriving it from private_key (PKCS#8
or PKCS#1 PEM) instead of erroring out.
Fixes WIN-1959
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(snowflake): treat empty public_key/private_key as missing
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(vault): add optional KV secret path prefix setting (WIN-1960)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore: update ee-repo-ref to 0189ba6504fd70eb4929e4881d624d48efd14aee
This commit updates the EE repository reference after PR #581 was merged in windmill-ee-private.
Previous ee-repo-ref: e32e8d6483550c67897e09b6f900dff1034bdae8
New ee-repo-ref: 0189ba6504fd70eb4929e4881d624d48efd14aee
Automated by sync-ee-ref workflow.
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
* fix: enforce auth guards on app component preview execution
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: guard previewed runnable path and worker tag in app preview
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: validate app_script id ownership and keep root push isolation
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor: scope app preview guards to operator check + referenced runnables
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: require jobs:run scope and tag check on app preview (apps:run escalation)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* [ee] feat(indexer): observability for unavailable search index
A user hit `Not found: There is no index reader to search from` when
searching service logs and could not tell whether it was a config
error or a bug, and asked for visibility into the indexer status
(WIN-1956).
Backend (EE companion PR):
- Replace the opaque error with an actionable message explaining the
likely causes (indexer disabled, still starting, or blocked
acquiring the indexer lock) and pointing to the status panel.
- Add a coarse `state` (running | stale | never_started) to
`/indexer/status`, derived from the lock row, distinguishing a
never-configured indexer from a stale/blocked one.
Frontend:
- Instance Settings > Indexer now shows Running / Stale / Not started
with a tooltip explaining what to check for each.
- Service logs search now catches failures and shows an inline,
actionable Alert instead of an unhandled rejection.
Fixes WIN-1956
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore: update ee-repo-ref to 017d36418a65ce5c840c502e3174df0c393612ba
This commit updates the EE repository reference after PR #580 was merged in windmill-ee-private.
Previous ee-repo-ref: 18b7e1b30a1ff582c4a072580bbb8aec34e22cdc
New ee-repo-ref: 017d36418a65ce5c840c502e3174df0c393612ba
Automated by sync-ee-ref workflow.
* fix(indexer): address review nits
- IndexerMemorySettings: older backends without `state` reporting
`is_alive: false` now show "Stopped" (red) again instead of
falling through to "Unknown" (codex/cubic P2).
- ServiceLogsInner: clear stale logs/counts on a failed search so the
error isn't shown alongside results from a previous query (codex P2).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
* fix(frontend): open customer portal in popup synchronously to bypass Safari blocker
Safari blocks window.open() called after an await because it loses the
user-gesture context. Open a blank tab synchronously on click, then
assign location.href once the portal URL resolves.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(backend): wire dev_override feature flag in backend crate
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat: export audit logs to dedicated object store folder
* fix: gap-free audit export via snapshot-xmin gate and stable object keys
* test: add integration test for audit log object store exporter
* fix: cursor audit export on snapshot xmin to prevent id-leapfrog loss
* fix: protect audit s3 checkpoint from config sync and bound export interval
* fix: anchor audit s3 checkpoint at enable time to not skip first-window rows
* fix: anchor first audit export at the enable transaction's xid
* fix: use epoch timestamp floor on first audit export run to not drop old backlog
* fix: anchor audit export at startup for env-var enable path
* fix: anchor audit export via enabling-txn snapshot xmin trigger
* fix: bound the bootstrap audit export to MAX_XID_INTERVAL per tick
* refactor: store audit export cursor in background_task_state, add status endpoint
* docs: align store_audit_logs_s3 setting text with the actual enable-boundary contract
* [ee] refactor: move audit s3 export core logic to EE, gate on Enterprise license
* chore: update ee-repo-ref to ec3cd353245e1cdf6a290528dbd7f2ac2498386c
This commit updates the EE repository reference after PR #579 was merged in windmill-ee-private.
Previous ee-repo-ref: 4ffc6d5f874e64d7dc4a147b4e73baa6c44867a5
New ee-repo-ref: ec3cd353245e1cdf6a290528dbd7f2ac2498386c
Automated by sync-ee-ref workflow.
---------
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
* fix(autoscaling): full-scale from below min_workers when backlog exceeds threshold
Bump EE ref to pull in the autoscaling fix: when active worker count is
below min_workers and a relevant tag's queue depth already exceeds
full_scale_jobs_waiting, scale straight to max_workers instead of slowly
ramping to min_workers first.
Companion EE PR: windmill-labs/windmill-ee-private#improve-pr-9209
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore: update ee-repo-ref to b4d68e40430cf0300b5d37734d1505fd743f1059
This commit updates the EE repository reference after PR #578 was merged in windmill-ee-private.
Previous ee-repo-ref: 99810eb763703ef0f4b3311338e0e65f53544158
New ee-repo-ref: b4d68e40430cf0300b5d37734d1505fd743f1059
Automated by sync-ee-ref workflow.
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
* fix: enable jemalloc background purge to prevent worker RSS growth
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: drop decay overrides, keep only jemalloc background_thread
The background thread is the actual fix; jemalloc's default decay
windows (dirty 10s, muzzy 0) are correct for months-long workers and
muzzy_decay_ms:5000 was more retentive than the default.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: advance postgres replication slot lsn via periodic standby status updates
* test: add e2e regression test for postgres replication slot lsn advancement
Drives sustained change traffic so the slot freeze reproduces deterministically (fails pre-fix at the 20s deadline, passes post-fix within ~10s). Also wires the postgres_trigger feature through windmill-test-utils and the integration-tests crate so the postgres trigger e2e tests are actually runnable.
* fix: honor SAML RelayState to redirect to deep link after SSO login
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore: bump ee-repo-ref for SAML RelayState validator test
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore: update ee-repo-ref to a3fefe85f5f2f52bb473fa47acc9efa8fd0b2206
This commit updates the EE repository reference after PR #577 was merged in windmill-ee-private.
Previous ee-repo-ref: 445a22536b1a6c342cde0baa6fbca9e25092f94b
New ee-repo-ref: a3fefe85f5f2f52bb473fa47acc9efa8fd0b2206
Automated by sync-ee-ref workflow.
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
* fix: reject path traversal in MCP endpoint path parameters
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: narrow MCP path-param validator to structural escapes only
Codex review: rejecting whitespace/`:`/`@` regressed legitimate
Windmill paths (app paths with spaces, email-style usernames like
u/admin@windmill.dev/...). These are ordinary path-segment data in an
absolute URL and cannot redirect the request. Reject only structural
escapes: control chars, `\`, `%`, `?`, `#`, and `.`/`..`/empty segments.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds the Docusign Authorization Code OAuth entry. Used by the
Docusign integration in the windmill-integrations hub (PR #128).
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* fix: enforce jobs:run scope on job preview and inline endpoints
Preview/inline endpoints (run/preview, run/preview_bundle, run/preview_flow,
run/dynamic_select inline) execute arbitrary request-supplied code but only
checked folder/namespace read access, which is a no-op when path is null. A
token scoped to a specific script/flow could escape its scope and run any
code. Add a jobs:run scope check, matching other arbitrary-execution
endpoints. Advisory GHSA-vxc5-w28p-m9xw.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: scope-check dynamic_select flow branch and inline preview
Address CI review: the dynamic_select Deployed{Flow} branch ran a deployed
flow's dynamic-select code without any scope check (only the Script branch
delegated to a scope-checked handler), and run_inline_preview_script executed
request-supplied code with no in-handler scope check. Add jobs:run:flows:{path}
to the flow branch and jobs:run to inline preview; correct the misleading
comment. Expand regression tests (preview_flow case, assert success for the
broad-token case). Advisory GHSA-vxc5-w28p-m9xw.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* test: remove preview scope enforcement test after local validation
The regression test passed locally (3/3) and validated the fix end-to-end;
removed from the PR per maintainer preference. Advisory GHSA-vxc5-w28p-m9xw.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: constrain unauthenticated get_public_resource to app_theme resources
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* test: remove get_public_resource regression test
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: bind /etc resolver files read-only in nsjail sandboxes
* docs(nsjail): explain why per-file /etc resolver binds are load-bearing
The explicit /etc/hosts, /etc/resolv.conf and /etc/hostname binds look
like removable duplication of the read-only /etc bind above them. They
are not: on Kubernetes those files are separate kubelet bind-mounts on
top of /etc and nsjail's read-only remount is non-recursive, so without
these shadow binds they stay writable and a job can persist cross-tenant
DNS poisoning for the pod lifetime. Comment guards against a future
"dedup cleanup" silently reintroducing the vulnerability.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs(nsjail): shorten the load-bearing-bind comment to 3 lines
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
* fix: reset parent_hash in auto_parent when all versions at path are archived
* test: regression test for auto_parent with all versions archived
---------
Co-authored-by: windmill-internal-app[bot] <1429786+windmill-internal-app[bot]@users.noreply.github.com>
Co-authored-by: Ruben Fiszel <ruben@windmill.dev>
* fix: don't show ALLOW_PRIVATE_AI_BASE_URLS hint for malformed AI base URLs
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: impl std::error::Error for SsrfValidationError for anyhow callers
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* fix: atomic bundle cache writes to prevent parallel cold-load race
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: trust-but-replace in atomic_publish_dir to never trust a stale partial cache dir
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: simplify atomic_publish_dir and add content-addressed rename-failure fallback
Revert the destroy-then-recreate dir swap (introduced concurrent-publisher
edge cases: spurious Err under a real herd, EACCES masking a stale partial)
back to a single atomic rename. Add the content-addressed exists-fallback to
atomic_write_file_bytes/atomic_copy_file so the loser of a publish race (and
Windows, where rename cannot replace an open/existing destination) treats the
already-published identical cache as success instead of failing.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
windmill-parser-ts-asset only recognized writeS3File/loadS3File when
the first arg was a bare 's3://...' string literal. The actual SDK
signature takes an S3Object ({ s3, storage? }) or 's3://bucket/key'
string, which every real script uses, so object-form writes/reads were
never detected as assets. Resolve the S3Object arg the same way the
runtime parseS3Object does, mapping { s3, storage } to s3://<storage>/
<key> and feeding it through parse_asset_syntax so the path matches the
// on s3:///… trigger form. Adds regression tests.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: aggregate wait time should target the true root job, not flow_innermost_root_job
* refactor: reuse get_root_job_id helper for wait-time aggregation
Instead of duplicating the root_job → flow_innermost_root_job →
parent_job fallback chain inline, call the existing get_root_job_id()
helper (the same one used by push_next_flow_job) and filter out the
self-id case so standalone scripts still skip aggregate insertion.
Behaviorally identical, single source of truth.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: windmill-internal-app[bot] <1429786+windmill-internal-app[bot]@users.noreply.github.com>
Co-authored-by: Ruben Fiszel <ruben@windmill.dev>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* [ee] fix(nativets): pass tracing-enabled OtelConfig to deno_telemetry::init
* chore: update ee-repo-ref to 19a76a09ffb43649ee19e62d07e8b8a42d78757b
This commit updates the EE repository reference after PR #573 was merged in windmill-ee-private.
Previous ee-repo-ref: daf7ce31f192d64ca6b5602af626ab6453d2aff4
New ee-repo-ref: 19a76a09ffb43649ee19e62d07e8b8a42d78757b
Automated by sync-ee-ref workflow.
---------
Co-authored-by: windmill-internal-app[bot] <1429786+windmill-internal-app[bot]@users.noreply.github.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>