Repository navigation
feat(iac): make secret and provider-job lifecycles safe - #1019
Conversation
Discover sensitive inputs through an optional typed gRPC service. Validate real leaf values without custom lookup dispatch; reject literal credentials before provider execution.
Keep credential references in plans, hooks and durable state. Resolve a separate driver copy, preserve cross-provider references and fail closed on discovery errors. Redact known credentials only in diagnostic surfaces, not consumer payloads.
Journal exact secret keys and namespaces before writes; retain deletion debt until absence is verified after restart. Only actual creations permit compensation; create-conflict upserts retain existing resources. Add optional targeted, bounded provider jobs and independent cancellation. Lifecycle JSONB migration is additive; legacy state remains readable and metadata-dropping backends fail closed.
⏱ Benchmark Results✅ No significant performance regressions detected. benchstat comparison (baseline → PR)
|
|
CI corrections are deliberately bounded: e03188c fixes only the existing x/sys direct-import annotation; 9cefcef removes an unused, side-effect-free saved-plan filtering assignment. Focused regression tests and full golangci-lint pass locally. CodeQL alert 398 was dismissed specifically as a false positive: its unchanged sha256Hex calls hash AWS SigV4 payloads/canonical requests, not stored passwords, as required by https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-create-signed-request.html. No hash algorithm, security rule, or CI policy was changed. Fresh CI is still pending; the code review is closed and no broad design/style round is being repeated. |
Summary
Keep IaC plans/state declarative while drivers receive an isolated resolved
copy; add durable routed-secret cleanup and optional targeted provider jobs.
All provider-specific execution remains in provider plugins.
Scope Manifest
feat/iac-runtime-secret-safety-20261002.complete Gate 0A or the broader slimming program. Dependent plugins consume
the exact new Workflow release after merge/publication.
Changes
canonical pointer validation rejects literals and malformed paths.
resolved driver copies cannot mutate declarative input. Consumer payloads
are not rewritten by diagnostic redaction.
namespace, generation, and deletion/absence evidence survive restart across
filesystem, memory, PostgreSQL, CLI/shared helper adapters, and gRPC.
keys survive partial updates, alias ownership conflicts fail before writes,
and confirmed ghosts are cleaned before recreation. Only actual owned
creations permit compensation; create-conflict upserts remain updates.
Cancellation is a separately advertised optional capability; legacy runner
absence and UNIMPLEMENTED remain stable negative signals.
corrected existing timestamp scanning and nil-array NOT NULL failures.
native replacement. Windows uses native replacement/write-through flags;
native Windows runtime acceptance remains in the cross-OS phase.
Verification
GOWORK=off go test ./... -p=4 -json -count=1: 151 packages,12,635 test/subtest cases, zero failures on final tree
7637257b0e8ca89b715c373f4c22dfaeda5e5644(9cefcef6).golangci-lint run --timeout=8m: zero issues with a full local scan;latest Linux CI lint also passes. New-issue filtering is not equivalent proof.
-race. Regression fixes have observed RED/GREEN and revert-RED proofs.four lifecycle phases, close/reopen/list, JSONB readback, and deletion passed;
both pgx corrections reproduced when reverted. Fixture container removed.
buf lint; pinnedbuf generate --path plugin/external/proto/iac.prototwice; generated diff against the index clean.
authorization policy was changed. Windows module tests cross-compile only;
this is not native Windows runtime proof.
git diff --cached --checkand locked 21-task/10-PR scope check pass.Runtime Launch Transcript
Build:
GOWORK=off make build-wfctlexited 0. Built CLI state-list commandagainst committed
cmd/wfctl/testdata/infra-multi-env.yamlexited 0 and reportedno tracked resources; no provider/cloud call was made.
Launch:
go test -race ./plugin/external -run '^TestIaCJobExternalProcess$' -count=1 -timeout=180s -vexited 0 (8.314s).The actual external plugin manager discovers and launches race-instrumented
SDK executables, then wires the actual provider client through Modular DI.
The native process receives exact target identity, observes a one-second
timeout, accepts the 3600-second bound, and handles cancellation. Invalid
timeouts, caller-context cancellation, UNIMPLEMENTED, authorization and
availability errors, plus a legacy runner without cancellation are checked.
Both native and legacy processes shut down cleanly; launch failure-signature
scrape passed.
Boundary: cloud execution behind the SDK is an in-memory test dependency,
not DigitalOcean or STG. SDK, process transport, host discovery, DI wiring, and
provider client are the real artifact, not reimplementations. Live provider
workload acceptance is explicitly later scope.
Doc-reconciliation: clean.
Bounded Adversarial Review
One initial pass found four concrete ownership/recovery defects. Exact
regressions reproduced them before fixes; removing only those fixes reproduced
the failures again. The correction pass closed three and reproduced one unsafe
upsert ownership case. Its targeted final check closed that sole remaining
finding with SHIP-IT. No Critical/Important findings remain; no style/design
review cycle was reopened. The actual create/upsert outcome is covered by
interruption and ordinary write-error tests, not inferred from the plan label.
CI Corrections
e03188c3fixes only the x/sys direct-import annotation;9cefcef6removesan unused, side-effect-free saved-plan assignment. Both diagnostics were
reproduced locally before correction. CodeQL alert 398 was specifically
dismissed as a verified false positive: unchanged AWS SigV4 payload and
canonical-request hashing is required by the
AWS protocol,
not password storage. No hash algorithm, scanner rule, or CI policy changed.
The remaining current-head CI gates and release are still pending.