diff --git a/frontend/src/lib/components/VariableForm.svelte b/frontend/src/lib/components/VariableForm.svelte
index 7064e6e359..af8bb01919 100644
--- a/frontend/src/lib/components/VariableForm.svelte
+++ b/frontend/src/lib/components/VariableForm.svelte
@@ -56,6 +56,17 @@
let ws = $derived(workspace ?? $workspaceStore)
+ // Enabling seeds a date rather than revealing an empty picker, mirroring how
+ // `ScriptAdvancedSettings` seeds a timeout of 300s. An empty DateTimeInput renders a time
+ // of 12:00 beside its buttons, which reads as a date already configured.
+ const DEFAULT_EXPIRY_DAYS = 90
+
+ function defaultValueExpiry(): string {
+ const d = new Date()
+ d.setDate(d.getDate() + DEFAULT_EXPIRY_DAYS)
+ return d.toISOString()
+ }
+
// Loading the deployed secret overwrites the draft row this form shares with the AI
// chat, so every path that would trigger it has to be blocked while that row stages a
// value — otherwise the staged one is replaced and the next deploy carries the old one.
@@ -211,26 +222,38 @@
diff --git a/frontend/src/routes/(root)/(logged)/variables/+page.svelte b/frontend/src/routes/(root)/(logged)/variables/+page.svelte
index b51ddf886d..a85cbcafd2 100644
--- a/frontend/src/routes/(root)/(logged)/variables/+page.svelte
+++ b/frontend/src/routes/(root)/(logged)/variables/+page.svelte
@@ -488,8 +488,7 @@
{#snippet text()}
The value {expired ? 'expired' : 'expires'} on
- {new Date(value_expires_at).toLocaleString()}. The workspace's
- variable expiration handler runs an hour before that.
+ {new Date(value_expires_at).toLocaleString()}.
{/snippet}
diff --git a/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte b/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte
index 4301630ed5..d960019bbd 100644
--- a/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte
+++ b/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte
@@ -46,6 +46,7 @@
import PremiumInfo from '$lib/components/settings/PremiumInfo.svelte'
import Toggle from '$lib/components/Toggle.svelte'
+ import Popover from '$lib/components/Popover.svelte'
import ChangeWorkspaceName from '$lib/components/settings/ChangeWorkspaceName.svelte'
import ChangeWorkspaceId from '$lib/components/settings/ChangeWorkspaceId.svelte'
@@ -2160,22 +2161,31 @@ export async function main(
-
+
+
+
+ {#snippet text()}
+ Select a handler first
+ {/snippet}
+
The handler is executed by the automatically created group
g/variable_expiration_handler. Rotating a variable means writing to it, so grant
- that group write access to the variables it is meant to rotate — it starts with
+ that group write access to the variables it is meant to rotate. It starts with
none. A script that carries an on-behalf-of identity is the exception: it runs
as that user, with their permissions rather than the group's.