From b9aebab6e96ce3f33cf1aeb59fc34a492e3a806b Mon Sep 17 00:00:00 2001 From: Carlos Villela Date: Wed, 27 May 2026 09:32:27 -0700 Subject: [PATCH] ci(e2e): opt functional jobs into residual caps on CI Signed-off-by: Carlos Villela --- .github/workflows/e2e-script.yaml | 7 +++++++ .github/workflows/nightly-e2e.yaml | 8 ++++++++ test/e2e-script-workflow.test.ts | 5 +++++ test/helpers/e2e-workflow-contract.ts | 2 ++ 4 files changed, 22 insertions(+) diff --git a/.github/workflows/e2e-script.yaml b/.github/workflows/e2e-script.yaml index db07747be0..ea53638b98 100644 --- a/.github/workflows/e2e-script.yaml +++ b/.github/workflows/e2e-script.yaml @@ -66,6 +66,13 @@ on: permissions: contents: read +env: + # GitHub-hosted Linux runners retain dangerous bounding-set capabilities but + # do not grant CAP_SETPCAP to the sandbox entrypoint. Functional E2E runs opt + # in explicitly so #4264's fail-closed guard remains covered by the dedicated + # gateway-isolation security regression instead of breaking every sandbox use. + NEMOCLAW_ALLOW_RESIDUAL_CAPS: "1" + jobs: run: runs-on: ${{ inputs.runner }} diff --git a/.github/workflows/nightly-e2e.yaml b/.github/workflows/nightly-e2e.yaml index 66cd9fdb79..d67294f53c 100644 --- a/.github/workflows/nightly-e2e.yaml +++ b/.github/workflows/nightly-e2e.yaml @@ -137,6 +137,14 @@ on: permissions: contents: read +env: + # GitHub-hosted Linux runners retain dangerous bounding-set capabilities but + # do not grant CAP_SETPCAP to the sandbox entrypoint. Nightly functional E2E + # jobs opt in explicitly so #4264's fail-closed guard remains covered by the + # dedicated gateway-isolation security regression instead of breaking every + # sandbox use on these CI hosts. + NEMOCLAW_ALLOW_RESIDUAL_CAPS: "1" + concurrency: group: nightly-e2e-${{ github.event_name }}-${{ github.event_name == 'workflow_dispatch' && format('{0}-{1}', github.ref, inputs.pr_number || 'manual') || 'schedule' }} cancel-in-progress: true diff --git a/test/e2e-script-workflow.test.ts b/test/e2e-script-workflow.test.ts index cacf36d1db..cfc9f62026 100644 --- a/test/e2e-script-workflow.test.ts +++ b/test/e2e-script-workflow.test.ts @@ -8,6 +8,11 @@ import { loadE2eWorkflowContract, reusableNightlyJobs } from "./helpers/e2e-work describe("E2E reusable workflow contract", () => { const { runnerWorkflow, nightlyWorkflow, action } = loadE2eWorkflowContract(); + it("opts functional E2E workflows into residual-cap execution on CI hosts", () => { + expect(runnerWorkflow.env?.NEMOCLAW_ALLOW_RESIDUAL_CAPS).toBe("1"); + expect(nightlyWorkflow.env?.NEMOCLAW_ALLOW_RESIDUAL_CAPS).toBe("1"); + }); + it("does not persist checkout credentials in the reusable runner", () => { const checkoutSteps = runnerWorkflow.jobs.run.steps.filter((step) => String(step.uses ?? "").startsWith("actions/checkout@"), diff --git a/test/helpers/e2e-workflow-contract.ts b/test/helpers/e2e-workflow-contract.ts index 451e69fa10..f293990c42 100644 --- a/test/helpers/e2e-workflow-contract.ts +++ b/test/helpers/e2e-workflow-contract.ts @@ -23,10 +23,12 @@ export type WorkflowStep = { }; export type NightlyWorkflow = { + env?: Record; jobs: Record; }; export type RunnerWorkflow = { + env?: Record; jobs: { run: { steps: WorkflowStep[];