Integrate security hardening PRs 1885, 1886, 1887 - #1888
Merged
simple-agent-manager[bot] merged 3 commits intoAug 23, 2026
Conversation
Contributor
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
origin/main.DEPLOYMENT_IMAGE_RESOLVE_*Worker vars through deployment config generation, and binds the default image-resolver fetch asglobalThis.fetch(input, init)so Cloudflare Workers host functions keep the required receiver. Both fixes have regression tests.Pinned constituent heads verified before integration:
5b713fc41f0f6d79c5ef77cfbca727fc7f4c70c70e1e5de105a672c93c764d186aed2da88442cbb7d830c8f28686c1eb04f977ab826275aee5799aadIntegration evidence:
origin/mainatb672af2312a4a362a106cc2f5ed3b6460014c6d3b5fa49028fcba5d18f53cfc4a55b3192e42f92de6da7ed53ecb03fe1aba7ec2fbc4da15a6ce52ada7012e39200aab6ab3af8c8396c2c4e965c43c671.codex/config.tomlis absent from the mega diff.Validation
pnpm lintpnpm typecheckpnpm testAdditional validation already run:
pnpm exec vitest run scripts/quality/sync-wrangler-config.test.ts scripts/quality/deploy-reusable-workflow.test.ts scripts/quality/deployment-workflow-hardening.test.ts apps/api/tests/unit/image-resolver.test.ts— passed, 162 tests.pnpm --filter @simple-agent-manager/api test -- tests/unit/routes/deployment-release-compose-submission.test.ts tests/unit/routes/node-observability-logs.test.ts tests/unit/services/release-tag-resolution.test.ts— passed, 22 tests.cd packages/vm-agent && go test ./internal/server— passed.cd packages/vm-agent && go test ./...— passed.cd packages/cli && go test ./...— passed.pnpm lint && pnpm typecheck && pnpm test && pnpm build— passed.pnpm check:fast— passed; baseline warnings only.pnpm quality:scripts:test— passed, 38 files / 517 tests.quality:wrangler-bindings,quality:agent-install-manifest,quality:skill-references,quality:ast-checks,quality:file-sizes,quality:stale-artifacts,quality:migration-safety,quality:do-migration-safety,quality:source-contract-tests,quality:no-tracked-stale-binaries,quality:observability-noise,quality:dependency-governance,quality:workspace-test-surfaces,quality:migration-ordering,quality:repo-visibility,quality:runtime-boundary-semantics,quality:direct-dependency-evidence,quality:govulncheck-diff.quality:gitleaks:currentpassed (53 reviewed baseline findings, 0 new);quality:gitleaks:prpassed (0 findings).quality:do-wall-timeafter exact-head staging deploy is still red forsam-api-staging / 95fdea1992ac4f6cb80ca133c0500e3c / 01KRXWNWXCR9ZQCV5VY4VBHBRP / alarm: recent 2026-08-22T08:21:12.779Z–2026-08-23T08:21:12.779Z, baseline 2026-08-15T08:21:12.779Z–2026-08-22T08:21:12.779Z, expected ratio <= 2x, actual 2.08x, recent avg P99 2187ms over 1439 requests vs baseline avg P99 1051ms over 3510 requests. Diff proof shows this PR does not touch ProjectData/alarm/scheduled paths, and a bounded post-deploy object-only recheck passed, so causality points to pre-existing/current-staging telemetry; the official gate remains red until waiver or remediation.No sweep/cron/alarm candidate-selection logic is changed by this PR. The DO wall-time check itself is a live analytics gate, not a candidate-selection change.
Staging Verification (REQUIRED for all code changes — merge-blocking)
All checkboxes below are mandatory for any PR that changes runtime code (
.ts,.tsx,.go, etc.). WriteN/A: docs-onlyONLY if the PR contains zero runtime code changes. See.claude/rules/13-staging-verification.md.Deploy Stagingworkflow run32627169272passed for exact head6da7ed53ecb03fe1aba7ec2fbc4da15a6ce52adaapp.sammy.party(staging) using the saved primary session; dashboard/API smoke passedStaging Verification Evidence
Current exact-head evidence:
32627169272, branchsam/mega-security-hardening-1885-1887, head6da7ed53ecb03fe1aba7ec2fbc4da15a6ce52ada; jobsValidate Configuration,Deploy to Cloudflare, andsmoke-testssucceeded. No further same-head deploy should be triggered unless code/config changes.6da7ed53ecb03fe1aba7ec2fbc4da15a6ce52adaare terminal green with expected skips for non-applicable visual/CLI/devcontainer/go-vuln-diff jobs./dashboard; primary superadmin session valid;/api/agentslists enabled Claude Code, Codex, and OpenCode; platform Hetzner cloud-provider credential01KNY6DC06C9QCYQM0389NAGNTis enabled; health response shape is stable.01M0PVJC0EZ16PRSZEVAZF1HVVand01M0PVX8SZ49RQDKXR8B222DF3ran on node01M0PVJBHTJ06Z9Z87RXTZS2GT; management-proxiedsystem-info,events,logs,containers,events/export,metrics/export, and logs WebSocket passed; both workspaces and the node were deleted. Direct raw VM fetch was unreachable rather than observable as HTTP 401/403, so local/structural auth tests remain the direct-denial evidence.docker.io/library/hello-world:latestanddocker.io/library/busybox:latestboth reached400 MANIFEST_VALIDATION_FAILEDat the deployed release endpoint with release count still zero, proving Docker Hub tag resolution completed. Direct Docker Hub challenge/token/manifest flow forhello-worldreturned manifest200, digestsha256:5dd0d3e6e255913fc30f90b9f2b1d359cc2cbdb48090cc4b65f1676e203243cc,ratelimit-limit: 100;w=3600,ratelimit-remaining: 98;w=3600,docker-ratelimit-source: 135.181.47.172, and noRetry-After; bearer token/realm were redacted. No Docker Hub staging/test credential exists by workspace env name or GitHub repo/staging secret/variable name, so authenticated Docker Hub probing was not available. Prior Docker Hub429evidence is therefore classified as transient upstream rate-limit state on the same deployed head, not a6da7ed53code/config regression.01KTKXZ4ZZAT6MJFXRW1ZTQ7RBand prompts that required each provider to clone/inspecthttps://github.com/raphaeltm/simple-agent-managerread-only. Direct target-project membership path remains documented: target project01KPKHSS72Q5JW01WFA7FGW2ANis owned bysystem_anonymous_trials; primary user has no membership; supported member API requires existing access; raw D1 and Wrangler minimalproject_membersinsert attempts were denied by Cloudflare permissions. Matrix evidence: Claude Code task01M0PX94K8JKZ8K6TKHRDTDF14, session3ff5a646-fd7b-4ed3-a1ad-57e30e961ec8, workspace01M0PXFMYNATKK1CP728XXRXHH, node01M0PX9ANYAMQBNGYNHQ3Z296H, agent session01M0PXGHWTB1EX9H25HDN7X4YQ; response citedapps/api/src/services/image-resolver.ts,apps/api/src/routes/nodes.ts,packages/vm-agent/internal/server/events.go,scripts/deploy/workflow-resource-names.mjs, and.github/workflows/deploy-reusable.yml. Codex task01M0PXPE3M2X5MTXS65H6TFRY2, session2cb287a1-18ea-4dd8-9695-83dd5497cf94, workspace01M0PXVP3W8HW66KY63VM81ZSB, node01M0PXPKQZ9E04Z83PEXC20130; response citedapps/api/src/services/image-resolver-outbound.ts,apps/api/src/routes/deployment-release-image-resolver.ts,apps/api/src/routes/nodes.ts,packages/vm-agent/internal/server/events.go,.github/workflows/deploy-reusable.yml,.github/workflows/teardown.yml, and workflow tests. OpenCode task01M0PY3M6SH299ETB7X0Q7XHKZ, sessioned7d2631-6fda-4326-84a7-7acd62ee2a97, workspace01M0PYBWNAG2549Y8RGB329HP7, node01M0PY3SWRJT9CK8DH80V0Y85T; response citedapps/api/src/services/image-resolver.ts,apps/api/src/routes/deployment-release-image-resolver.ts,apps/api/src/routes/nodes.ts,apps/api/src/services/node-agent-diagnostics.ts,apps/api/src/routes/projects/compose-publish-release-callback.ts,apps/api/src/services/node-agent.ts, andapps/api/src/services/strict-node-deletion.ts. All three reached persisted session/task/workspace paths and coherent repo-grounded responses; each workspace/node was deleted before the next provider; final staging cleanup returned nodes0, workspaces0. Caveat: after explicit cleanup, the linked conversation-mode task rows can showfailed/workspace_missing; the persisted sessions and responses remain intact and final reviewers accepted this as a cleanup side effect, not a provider-response failure.GET /api/nodescount0; finalGET /api/workspaces?limit=100returned no active visible workspaces; target project membership still only containssystem_anonymous_trialsowner.Remaining merge blockers: #1887 live head drift from pinned head and official DO wall-time red/waiver absent. Provider matrix is completed through primary-session real workflows with direct target-repo clone prompts; target-project temporary membership attempts remain documented as unavailable due API/D1 permissions.
UI Compliance Checklist (Required for UI changes)
.codex/tmp/playwright-screenshots/(see `.claude/rules/17-ui-visual-testing.md)N/A: no UI files or UI behavior changed. Staging browser checks are still required for release smoke.
End-to-End Verification (Required for multi-component changes)
.claude/rules/10-e2e-verification.md)Data Flow Trace
.github/workflows/*intoscripts/deploy/workflow-resource-names.mjs, which validates resource names before shell use. Structural tests inscripts/quality/deployment-workflow-hardening.test.tsreject direct${{ }}shell interpolation.apps/api/src/routes/nodes.tsmint node-management tokens and proxy diagnostics to VM-agent endpoints inpackages/vm-agent/internal/server/events.go; workspace-scoped credentials are rejected at the VM-agent boundary. Tests cover logs, events, exports, and WebSocket access.apps/api/src/routes/deployment-release-image-resolver.ts, which usesapps/api/src/services/image-resolver.tsandapps/api/src/services/image-resolver-outbound.tsfor bounded registry fetches, redirect validation, token-realm validation, and digest/tag handling. Env limits are declared inapps/api/src/env.ts, documented inapps/api/.env.exampleandapps/www/src/content/docs/docs/reference/configuration.md, and now propagated byscripts/deploy/sync-wrangler-config.tsplus.github/workflows/deploy-reusable.yml.Untested Gaps
Pending staging validation:
Post-Mortem (Required for bug fix PRs)
What broke
This PR aggregates three accepted security hardening bug-fix PRs and includes one additional release-blocker fix discovered during integration review: documented image-resolution limit env vars were not propagated through normal deployment config generation.
Root cause
The resolver env declarations/docs were updated in the constituent work, but the deploy-time Worker config sync allowlist and reusable deploy workflow env blocks did not include the new
DEPLOYMENT_IMAGE_RESOLVE_*variables.Class of bug
Configuration propagation gap across code, docs, and deployment workflow.
Why it wasn't caught
Resolver unit tests validated runtime parsing and behavior, but there was no structural test proving every documented resolver limit reached generated Worker vars through the deploy workflow.
Process fix included in this PR
Added regression coverage in
scripts/quality/sync-wrangler-config.test.tsandscripts/quality/deploy-reusable-workflow.test.ts.Post-mortem file
This PR body records the integration post-mortem. No separate post-mortem file was added to avoid unrelated durable artifacts in this release mega diff.
Specialist Review Evidence (Required for agent-authored PRs)
If local subagents were used during Phase 5, list every reviewer below. Do NOT merge until every row shows PASS or ADDRESSED. If any reviewer could not complete (timeout, workspace killed, error), you MUST add the
needs-human-reviewlabel and stop — do not self-merge. See.claude/rules/25-review-merge-gate.md.needs-human-reviewlabel added and merge deferred to human01a02d2d-92e1-7fc0-9208-a515a70ea23c)01a02d2d-d4d7-73f2-881f-01a7fff9dca2)DEPLOYMENT_IMAGE_RESOLVE_*; fixed in657530dewith deploy workflow/config tests.01a02da1-e58e-73b3-9eba-3c0fc0cb03ea)6da7ed53receiver-preservation fix before redeploy; no changes required.01a02da1-fbec-7462-bd30-087f333dbb1f)01a02dc3-8a17-7d63-86ab-b1fb39d14e1c)6da7ed53: no release-blocking findings; Docker Hub 429 treated as product reliability follow-up, not a security bypass.01a02dc3-9ff6-7b53-92c4-cb9ee09ede74)01a02de9-9c38-7581-8e08-544f5f1ebc84)01a02de9-9efa-78f2-8a2e-8af87542fc9c)workspace_missingcaveat. Release remains blocked only on #1887 head drift and official DO wall-time/waiver.Exceptions (If any)
scripts/deploy/sync-wrangler-config.ts,scripts/quality/sync-wrangler-config.test.ts,apps/api/src/services/image-resolver.ts, andapps/api/tests/unit/image-resolver.test.ts.Agent Preflight (Required)
Classification
External References
N/A: no external API behavior was changed. This work integrates already accepted repository PRs and validates local SAM/Cloudflare Worker deployment, VM-agent, and registry resolver code paths against repository tests and project release policy.
Codebase Impact Analysis
Affected paths include
.github/workflows/*deploy/teardown/restore/provision workflows,scripts/deploy/*,scripts/quality/*,apps/api/src/routes/deployment-*,apps/api/src/services/image-resolver*,apps/api/src/routes/nodes.ts,packages/vm-agent/internal/server/events.go,apps/api/tests/unit/*,packages/vm-agent/internal/server/events_test.go,apps/www/src/content/docs/docs/reference/*, andspecs/*/contracts/*.Documentation & Specs
Docs/specs updated in
apps/www/src/content/docs/docs/reference/configuration.md,apps/www/src/content/docs/docs/reference/vm-agent.md,specs/014-multi-workspace-nodes/contracts/node-agent-api.md, andspecs/020-node-observability/contracts/vm-agent-logs.md.Constitution & Risk Check
Checked Principle XI / no hardcoded operational values: the new resolver work/size limits are configurable via env, documented, and now propagated through deployment. Key risks are staging-only until verified: live Worker DNS/rebinding behavior, node-wide diagnostics auth boundaries, registry redirect/token-realm fail-closed behavior, and three-provider real-agent workflow continuity.