mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-17 16:03:06 +00:00
* feat: restricted job tokens (job_token_scopes on scripts and flows) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: admit flow-run reads, skip dedicated workers, gate on worker version Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: keep restricted jobs off flow runners, preserve scopes on rename and promotion Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: keep restricted jobs off every dedicated handoff, confine progress flow id Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: exclude restricted runnables from dedicated worker startup Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: gate restrictions on the release after 1.821.0 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: store per-job scopes on job_perms instead of v2_job, pin inline runs to the checked version Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * feat: step-level job_token_scopes for flow steps and agent tools Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014FHGE3ynoAu6yrgeg4kLwL * fix: fail closed on perms read errors, refuse restricted queue imports, gate step scopes in previews Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014FHGE3ynoAu6yrgeg4kLwL * fix: carry a job's scopes on its completion so a re-run keeps the caller's cap Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014FHGE3ynoAu6yrgeg4kLwL * fix: carry a zombie job's scopes into its completion Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014FHGE3ynoAu6yrgeg4kLwL * fix: leave a zombie for the next sweep when its scopes cannot be read Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014FHGE3ynoAu6yrgeg4kLwL * docs: correct the QueuedJobV2 completion comment Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014FHGE3ynoAu6yrgeg4kLwL * fix: validate step scopes in batch flows, fail closed on unvalidated step scopes Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014FHGE3ynoAu6yrgeg4kLwL * fix: refuse flows with step or tool restrictions at push while an older worker is live Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014FHGE3ynoAu6yrgeg4kLwL * fix: apply the step-scope worker gate to flow restarts Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014FHGE3ynoAu6yrgeg4kLwL * fix: list the job token toggle with the other step and flow settings Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014FHGE3ynoAu6yrgeg4kLwL * chore: pin the EE companion merged with EE main Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014FHGE3ynoAu6yrgeg4kLwL * perf: skip scope lookups for unrestricted jobs; list job token setting last Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014FHGE3ynoAu6yrgeg4kLwL * style: rustfmt scopes tests Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014FHGE3ynoAu6yrgeg4kLwL * fix: confine restricted job tokens to their own run lineage; drop remaining extra lookups Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014FHGE3ynoAu6yrgeg4kLwL * chore: update ee-repo-ref to 259ad3bfeef5285ba80eedc86309b11dca001220 This commit updates the EE repository reference after PR #843 was merged in windmill-ee-private. Previous ee-repo-ref: 2b77c0225dca441235daf7bf0a06ba968df0c927 New ee-repo-ref: 259ad3bfeef5285ba80eedc86309b11dca001220 Automated by sync-ee-ref workflow. --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
90 lines
3.2 KiB
Svelte
90 lines
3.2 KiB
Svelte
<script lang="ts">
|
|
import Toggle from './Toggle.svelte'
|
|
import ToggleButtonGroup from './common/toggleButton-v2/ToggleButtonGroup.svelte'
|
|
import ToggleButton from './common/toggleButton-v2/ToggleButton.svelte'
|
|
import ScopeSelector from './settings/ScopeSelector.svelte'
|
|
|
|
interface Props {
|
|
/** `null`/`undefined`: the job token has the full permissions of the identity it runs as. */
|
|
value: string[] | null | undefined
|
|
kind: 'script' | 'flow' | 'step'
|
|
/** Match the toggles listed around it. */
|
|
size?: 'xs' | 'sm'
|
|
textClass?: string
|
|
}
|
|
|
|
let { value = $bindable(), kind, size = 'sm', textClass }: Props = $props()
|
|
|
|
const OIDC_ONLY = ['oidc:write']
|
|
|
|
type Mode = 'oidc_only' | 'no_api' | 'custom'
|
|
|
|
function modeOf(scopes: string[]): Mode {
|
|
if (scopes.length === 0) return 'no_api'
|
|
if (scopes.length === 1 && scopes[0] === OIDC_ONLY[0]) return 'oidc_only'
|
|
return 'custom'
|
|
}
|
|
|
|
// Derived from `value` so an edit made elsewhere (the flow YAML) shows here; the flag only
|
|
// keeps "Custom" selected while a custom list happens to equal a preset.
|
|
let customPicked = $state(false)
|
|
const mode: Mode = $derived(customPicked ? 'custom' : modeOf(value ?? OIDC_ONLY))
|
|
|
|
function setMode(next: Mode) {
|
|
customPicked = next === 'custom'
|
|
value =
|
|
next === 'oidc_only' ? [...OIDC_ONLY] : next === 'no_api' ? [] : [...(value ?? [])]
|
|
}
|
|
</script>
|
|
|
|
<div class="flex flex-col gap-2">
|
|
<Toggle
|
|
{size}
|
|
{textClass}
|
|
checked={value != null}
|
|
on:change={() => {
|
|
if (value != null) {
|
|
value = null
|
|
} else {
|
|
setMode('oidc_only')
|
|
}
|
|
}}
|
|
options={{
|
|
right: 'Restrict the job token',
|
|
rightTooltip:
|
|
"Limit what the WM_TOKEN of this " +
|
|
kind +
|
|
"'s jobs can do through the API, e.g. only mint an OIDC token. Use it for code that handles untrusted input, such as AI agents."
|
|
}}
|
|
/>
|
|
{#if value != null}
|
|
<ToggleButtonGroup selected={mode} onSelected={(v) => setMode(v)}>
|
|
{#snippet children({ item })}
|
|
<ToggleButton value="oidc_only" label="OIDC token only" {item} />
|
|
<ToggleButton value="no_api" label="No API access" {item} />
|
|
<ToggleButton value="custom" label="Custom" {item} />
|
|
{/snippet}
|
|
</ToggleButtonGroup>
|
|
{#if mode === 'custom'}
|
|
<ScopeSelector
|
|
bind:selectedScopes={() => value ?? [], (scopes) => (value = [...scopes])}
|
|
emptyLabel="No scopes selected. The job token can only reach its own job."
|
|
/>
|
|
{/if}
|
|
<p class="text-2xs text-secondary">
|
|
{#if kind === 'step'}
|
|
The <code>WM_TOKEN</code> of every job this step runs can only do what these scopes allow, on top
|
|
of the flow's own restriction. Loop and branch bodies, and AI agent tools, inherit it.
|
|
{:else}
|
|
The <code>WM_TOKEN</code> of every job of this {kind} can only do what these scopes allow. Jobs
|
|
it starts, {kind === 'flow' ? 'its steps, ' : ''}and AI agent tools inherit the restriction.
|
|
{/if}
|
|
Variables and resources passed as <code>$var:</code>/<code>$res:</code> inputs, an AI agent's provider
|
|
resource, relative imports and object storage each need a read scope, and script state
|
|
(<code>getState</code>/<code>setState</code>) needs <code>resources:write</code>. Write scopes on scripts,
|
|
flows, schedules or triggers let a job escape the restriction. Jobs with a restricted token never
|
|
run on dedicated workers.
|
|
</p>
|
|
{/if}
|
|
</div>
|