chore(template): Security Auditor DAST must clean up its own test artifacts - #29
Merged
Merged
Conversation
…ifacts Follow-up to root-cause analysis in #17 (see 2026-04-14 02:14 UTC comment). The Security Auditor's hourly DAST was creating test workspaces, secrets, and plugins to probe auth/validation logic — but only secrets and plugins had teardown in the prompt. Workspace-create probes leaked rows into `workspaces` with sequential IDs aaaaaaaa- bbbbbbbb- cccccccc- dddddddd-, each trapped in a restart loop on missing config.yaml. Four hourly runs, four leaked workspaces. Adds explicit step 4a: DAST TEARDOWN. Maintains three lists (workspaces, secrets, plugins) populated as probes run, and iterates them at the end with DELETE calls. Uses `|| true` so partial teardown failures don't break the audit, but every created artifact gets a cleanup attempt. Doesn't remove the cleanup the cron was already doing for secrets/plugins — just formalises the pattern so workspace-create (and any future probe surface) is covered by the same contract. Related: - #17 — rogue workspace restart loop (root cause was this) - #26 — audit cron routing (this PR sits alongside that structure)
HongmingWang-Rabbit
left a comment
Contributor
Author
There was a problem hiding this comment.
7-gate verification PASS:
- Gate 1 CI: 6/6 green
- Gate 2 Build: YAML-only, skipped
- Gate 3 Tests: test_api.sh 62/62 pass
- Gate 4 Security: cleanup scope bounded to self-created IDs; uses legacy /admin/secrets alias (valid); no unbounded deletion; no committed secrets
- Gate 5 Design fit: Security Auditor role unchanged; PM-routing unaffected; uses standard REST endpoints
- Gate 6 Line review: correct bash parameter expansion for ws:plugin split; || true guards against missing artifacts; quoting safe for UUIDs
- Gate 7 Canvas: N/A
Merging.
HongmingWang-Rabbit
pushed a commit
that referenced
this pull request
Apr 15, 2026
Documents the 4-step hard-delete cascade implemented in molecule-controlplane PR #29 (Stripe → Redis → Infra → DB rows), how to read the org_purges audit table when a purge fails, the 30-day GDPR deadline, and what the cascade deliberately does NOT cover (WorkOS users, LLM provider history, Langfuse traces). Cross-referenced from the "SaaS ops" block in CLAUDE.md so future agents find it when handling erasure requests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2 tasks
HongmingWang-Rabbit
pushed a commit
that referenced
this pull request
Apr 15, 2026
Extends the secret map with RESEND_API_KEY, RESEND_FROM_EMAIL, STRIPE_API_KEY, STRIPE_WEBHOOK_SECRET — the four SaaS secrets the control plane reads once the current PR stack (#29-#34 on molecule-controlplane) ships. Adds rotation procedures for each: - Resend: low-blast-radius, best-effort sends, domain verification gotcha documented - Stripe API key: independent rotation from webhook secret, live verify via /cp/billing/checkout - Stripe webhook secret: 24h overlap window procedure using stripe trigger for live verify Also adds Resend + Stripe entries to the emergency-contacts list. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
HongmingWang-Rabbit
pushed a commit
that referenced
this pull request
Apr 15, 2026
Tick 32 (manual) merged a large batch of PRs — the test counts in CLAUDE.md were drifting behind reality by enough to matter: - platform: 816 → 818 (YAML injection fix + sanitizeRuntime allowlist) - canvas: 453 → 482 (12 CookieConsent + 17 PricingTable/billing) - workspace-template: 1180 → 1179 (Hermes Phase 2a/2b dispatch tests landed but the test_hermes_providers env-var-leak fix removed a fragile flake-path count; net -1) This is measured not guessed: running the full suites on fresh main. Not in this sync but worth mentioning for the next retrospective: - controlplane repo received the full GDPR/admin/usage/consent/email stack (#29-#34) — that work sits in molecule-controlplane, not monorepo CLAUDE.md - monorepo picked up /pricing route, cookie consent banner, molecule- hitl plugin (#262), Hermes Phase 2a native Anthropic + 2b Gemini Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
molecule-ai Bot
pushed a commit
that referenced
this pull request
Apr 21, 2026
chore(template): Security Auditor DAST must clean up its own test artifacts
molecule-ai Bot
pushed a commit
that referenced
this pull request
Apr 21, 2026
Documents the 4-step hard-delete cascade implemented in molecule-controlplane PR #29 (Stripe → Redis → Infra → DB rows), how to read the org_purges audit table when a purge fails, the 30-day GDPR deadline, and what the cascade deliberately does NOT cover (WorkOS users, LLM provider history, Langfuse traces). Cross-referenced from the "SaaS ops" block in CLAUDE.md so future agents find it when handling erasure requests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
molecule-ai Bot
pushed a commit
that referenced
this pull request
Apr 21, 2026
Extends the secret map with RESEND_API_KEY, RESEND_FROM_EMAIL, STRIPE_API_KEY, STRIPE_WEBHOOK_SECRET — the four SaaS secrets the control plane reads once the current PR stack (#29-#34 on molecule-controlplane) ships. Adds rotation procedures for each: - Resend: low-blast-radius, best-effort sends, domain verification gotcha documented - Stripe API key: independent rotation from webhook secret, live verify via /cp/billing/checkout - Stripe webhook secret: 24h overlap window procedure using stripe trigger for live verify Also adds Resend + Stripe entries to the emergency-contacts list. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
molecule-ai Bot
pushed a commit
that referenced
this pull request
Apr 21, 2026
Tick 32 (manual) merged a large batch of PRs — the test counts in CLAUDE.md were drifting behind reality by enough to matter: - platform: 816 → 818 (YAML injection fix + sanitizeRuntime allowlist) - canvas: 453 → 482 (12 CookieConsent + 17 PricingTable/billing) - workspace-template: 1180 → 1179 (Hermes Phase 2a/2b dispatch tests landed but the test_hermes_providers env-var-leak fix removed a fragile flake-path count; net -1) This is measured not guessed: running the full suites on fresh main. Not in this sync but worth mentioning for the next retrospective: - controlplane repo received the full GDPR/admin/usage/consent/email stack (#29-#34) — that work sits in molecule-controlplane, not monorepo CLAUDE.md - monorepo picked up /pricing route, cookie consent banner, molecule- hitl plugin (#262), Hermes Phase 2a native Anthropic + 2b Gemini Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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
The Security Auditor's hourly DAST cron was creating test workspaces during security probes and never tearing them down, leaking rows into the live
workspacestable. Adds an explicit4a. DAST TEARDOWNstep to the cron prompt with a track-and-cleanup pattern for workspaces, secrets, and plugins.Root cause
Investigated under #17 (see comment 2026-04-14 02:14 UTC). The cron prompt already cleaned up secrets and plugins it created, but workspace-create probes had no teardown. Over four hourly runs we got four leaked rows with sequential IDs (
aaaaaaaa-…/bbbbbbbb-…/cccccccc-…/dddddddd-…), each trapped in a restart loop against the missing config.yaml.Platform log evidence at 2026-04-14 04:27:17 UTC (one sample, representative of every cycle):
Changes
Single edit to
org-templates/molecule-dev/org.yaml— adds step 4a to theHourly security auditcron prompt:TESTS_WORKSPACES,TESTS_SECRETS,TESTS_PLUGINS.DELETE. Uses|| trueso a failed cleanup doesn't abort the audit.Why inline vs. platform-layer
A platform-level circuit-breaker (reject workspace creates from DAST, or TTL test workspaces) is still valid (proposed in #17 options B/C/D). But this template-layer fix is orthogonal and the cheapest immediate stop — it doesn't depend on any code change, and it closes the specific incident class we've already seen four times today.
Test plan
python -c "import yaml; yaml.safe_load(open('org-templates/molecule-dev/org.yaml'))"— YAML valid.eeeeeeee-…row appears inworkspaces.docker ps | grep -c 'ws-[a-z]\{8\}-123'stays at 0 across successive runs.Related
🤖 Generated with Claude Code