From 00d0e93a3965d43c2cbe4983472aaa8027702eea Mon Sep 17 00:00:00 2001 From: Ruben Fiszel Date: Tue, 14 Jul 2026 19:10:02 +0000 Subject: [PATCH] feat(apps): collapse s3 read paths into a discreet disclosure (also covers raw apps) Co-Authored-By: Claude Opus 4.8 (1M context) --- .../apps/editor/AppEditorHeaderDeploy.svelte | 101 +++++++++++------- 1 file changed, 62 insertions(+), 39 deletions(-) diff --git a/frontend/src/lib/components/apps/editor/AppEditorHeaderDeploy.svelte b/frontend/src/lib/components/apps/editor/AppEditorHeaderDeploy.svelte index d3c8850ae4..26ed152f76 100644 --- a/frontend/src/lib/components/apps/editor/AppEditorHeaderDeploy.svelte +++ b/frontend/src/lib/components/apps/editor/AppEditorHeaderDeploy.svelte @@ -3,7 +3,7 @@ import Badge from '$lib/components/common/badge/Badge.svelte' import Toggle from '$lib/components/Toggle.svelte' import { enterpriseLicense, userStore, workspaceStore } from '$lib/stores' - import { Loader2, Plus, X } from 'lucide-svelte' + import { ChevronDown, ChevronRight, Loader2, Plus, X } from 'lucide-svelte' import Tooltip from '$lib/components/Tooltip.svelte' @@ -102,6 +102,10 @@ // `s3_read_scopes` is author-declared and must survive `updatePolicy` (which // recomputes `allowed_s3_keys`), so it is edited directly on `policy` and // persisted on the next deploy — reassign the array so the change is reactive. + // Collapsed by default (most apps never need it); auto-expanded when scopes exist. + // untrack: we intentionally capture only the initial value, not react to `policy`. + let showReadScopes = $state(untrack(() => (policy?.s3_read_scopes?.length ?? 0) > 0)) + let readScopeCount = $derived(policy.s3_read_scopes?.length ?? 0) function addReadScope() { policy.s3_read_scopes = [...(policy.s3_read_scopes ?? []), { path_glob: '' }] } @@ -298,49 +302,68 @@ {#if policy.execution_mode !== 'viewer'} -
-
-

S3 read paths (on-behalf)

+
+
+ - Literal globs (e.g. f/sensitive/*** within a path segment, - ** across segments) of S3 keys this deployed app may read on-behalf of its - on-behalf-of identity, for files it displays but does not produce during a viewer's session - (e.g. results a separate job persisted to S3). Applies to the primary storage. Unlike the - workspace advanced-permission rules, template variables such as - {'{folder_read}'} + Optional. Literal globs (e.g. f/sensitive/*** within a path + segment, ** across segments) of S3 keys this deployed app may read on-behalf of + its on-behalf-of identity. Only needed when the app displays an S3 file whose reference is + not returned by one of the app's own runnables — e.g. a file a separate job or schedule + wrote to S3. Files produced by the app's own jobs, and static file components, are already + authorized. Applies to the primary storage. Unlike the workspace advanced-permission rules, + template variables such as {'{folder_read}'} are not expanded. Reads are still bounded by the on-behalf identity's S3 permissions — a path - here never grants more access than that identity already has. Files the app produces itself, - or static file components, do not need an entry. + here never grants more access than that identity already has.
-
- Leave empty if the app only shows files it produces itself. Takes effect on next deploy. -
-
- {#each policy.s3_read_scopes ?? [] as _scope, i (i)} -
-
- -
- -
+
+ {#each policy.s3_read_scopes ?? [] as _scope, i (i)} +
+
+ +
+
+ {/each} +
+
+ +
+
+ {/if}
{/if}