Skip to content

Commit 287995f

Browse files
icecrasher321claude
andcommitted
Revert "fix(execution): count the runtime payload as secret material in scope"
This reverts commit 754e37c. The classifier's secret catalog is the Secrets feature and nothing else: `outputSecretNamesByScanLiteral` and `outputSecretPlaintextsByName` are built only from `envVars`, and mounted-file entries trace back to the same place. `contextVariables`, `blockData`, and `workflowVariables` are ordinary workflow data — resolved block outputs the user already sees in logs — and the text export path does not scan them either. Treating their mere presence as secret material was a heuristic, not a security property, and it created exactly the asymmetry rejected two rounds earlier: a binary derived from a context variable would be `unknown` while a text export of the same bytes stays exact-empty. Stricter than the text path for the same content is not a boundary. It was also nearly inert. `scopeEnvironmentVariables` returns every workspace secret when scope is `all` (the default), so any workflow Function block with secrets configured already trips the env branch. The only slice it changed was executions with no env vars at all, where the workspace has no secret for a context variable to carry. A Secret resolved into an upstream block's output and arriving here through blockData is a real gap, but it is pre-existing, identical for text exports, and belongs at the executor -> route boundary as a provenance envelope for params — not as a presence check in this classifier. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 754e37c commit 287995f

2 files changed

Lines changed: 0 additions & 57 deletions

File tree

apps/sim/app/api/function/execute/route.test.ts

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -890,40 +890,6 @@ describe('Function Execute API Route', () => {
890890
)
891891
})
892892

893-
it('keeps a binary export unknown when resolved context variables reach the sandbox', async () => {
894-
envFlagsMock.isRemoteSandboxEnabled = true
895-
mockExecuteInSandbox.mockResolvedValueOnce({
896-
result: 'done',
897-
stdout: '',
898-
sandboxId: 'sandbox-123',
899-
exportedFiles: { '/home/user/small.jpg': '/9j/4AAQ' },
900-
})
901-
902-
const response = await POST(
903-
createMockRequest('POST', {
904-
code: 'print("done")',
905-
language: 'python',
906-
workspaceId: 'workspace-1',
907-
// Resolved upstream block output — the route has no catalog to classify it.
908-
contextVariables: { upstreamValue: 'could-be-anything' },
909-
outputs: {
910-
files: [
911-
{
912-
path: 'files/small.jpg',
913-
sandboxPath: '/home/user/small.jpg',
914-
mimeType: 'image/jpeg',
915-
},
916-
],
917-
},
918-
})
919-
)
920-
921-
expect(response.status).toBe(200)
922-
expect(mockWriteWorkspaceFileByPath).toHaveBeenCalledWith(
923-
expect.objectContaining({ secretProvenance: { status: 'unknown' } })
924-
)
925-
})
926-
927893
it('keeps a binary export unknown when files were mounted without a provenance envelope', async () => {
928894
envFlagsMock.isRemoteSandboxEnabled = true
929895
mockExecuteInSandbox.mockResolvedValueOnce({

apps/sim/app/api/function/execute/route.ts

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -990,12 +990,6 @@ interface FunctionRouteExecutionContext {
990990
outputSecretPlaintextsByName: Map<string, string>
991991
mountedFileSecretProvenanceScanner?: MountedFileSecretProvenanceScanner
992992
hasMountedSandboxFiles: boolean
993-
/**
994-
* Whether the serialized runtime payload carried `params` or `contextVariables` into the sandbox.
995-
* Those are resolved block outputs and workflow variables — the route has no catalog for them, so
996-
* it cannot tell a secret-bearing one from an ordinary value.
997-
*/
998-
hasUnclassifiedRuntimeInputs: boolean
999993
}
1000994

1001995
type ResolvedSecretNamesMetadataType =
@@ -1225,15 +1219,9 @@ function activateOutputSecretProvenance(
12251219
* are unclassifiable rather than clean: absence of an envelope is absence of evidence, not evidence
12261220
* the mount carried nothing. Those fail closed here so the classification can never be stronger
12271221
* than what the caller actually attested to.
1228-
*
1229-
* The serialized runtime payload counts too. It carries `params` and `contextVariables` — resolved
1230-
* block outputs and workflow variables — into the sandbox as a private-input file, and the route
1231-
* has no catalog to tell a secret-bearing one from an ordinary value. Only an execution with
1232-
* nothing at all in scope earns an exact-empty binary.
12331222
*/
12341223
function hasSecretMaterialInScope(context: FunctionRouteExecutionContext): boolean {
12351224
if (context.outputSecretPlaintextsByName.size > 0) return true
1236-
if (context.hasUnclassifiedRuntimeInputs) return true
12371225
const scanner = context.mountedFileSecretProvenanceScanner
12381226
return scanner ? scanner.hasSecrets : context.hasMountedSandboxFiles
12391227
}
@@ -2043,12 +2031,6 @@ export const POST = withRouteHandler(async (req: NextRequest) => {
20432031
outputSecretPlaintextsByName: new Map(),
20442032
mountedFileSecretProvenanceScanner,
20452033
hasMountedSandboxFiles: (_sandboxFiles?.length ?? 0) > 0,
2046-
// Values, not keys: `executionParams._context` is explicitly set to undefined just above,
2047-
// so a key count would read every execution as carrying params. Raised below once the
2048-
// resolved context variables are known.
2049-
hasUnclassifiedRuntimeInputs: Object.values(executionParams).some(
2050-
(value) => value !== undefined
2051-
),
20522034
}
20532035
for (const [name, plaintext] of Object.entries(envVars)) {
20542036
if (!plaintext) continue
@@ -2092,11 +2074,6 @@ export const POST = withRouteHandler(async (req: NextRequest) => {
20922074
...codeResolution.contextVariables,
20932075
...preResolvedContextVariables,
20942076
}
2095-
// Resolved block outputs and workflow variables ride into the sandbox inside the runtime
2096-
// payload, so an output file can carry them even with nothing mounted and no env secret.
2097-
if (Object.keys(contextVariables).length > 0) {
2098-
routeContext.hasUnclassifiedRuntimeInputs = true
2099-
}
21002077
const compilation = await compileCodePlaceholders({
21012078
code: codeResolution.resolvedCode,
21022079
language: lang,

0 commit comments

Comments
 (0)