Skip to content

R-A4 align rule should also consult top-level secrets.generate keys (not just module-form) #541

@intel352

Description

@intel352

Surfaced by

Core-dump C-1 staging-PG cutover (workflow PR #538 / W-1..W-9 conformance, downstream consumer).

Behavior

R-A4 (cmd/wfctl/infra_align_rules.go::checkRA4) checks every `${VAR}` reference in module env_vars against `ctx.secretKeys` then falls back to `os.Getenv`. `ctx.secretKeys` is populated only from MODULE-form `secrets.generate` (per buildAlignContext switch arm at line 58). The TOP-LEVEL `secrets:` block populates `ctx.secretGens` (used by R-A9) but NOT `ctx.secretKeys`.

Effect

A config that declares secrets the canonical way (top-level `secrets:` block, e.g. core-dump's infra.yaml line 26-71 with `STAGING_PG_PASSWORD` as random_hex and `STAGING_VPC_UUID` as infra_output) will trigger R-A4 strict FAIL on `${STAGING_PG_PASSWORD}` references in container env_vars unless the GH workflow also exports the secret as an env var to the align step. This forces:

```yaml

  • name: Validate alignment
    run: wfctl infra align --strict
    env:
    STAGING_PG_PASSWORD: ${{ secrets.STAGING_PG_PASSWORD }} # workaround
    ```

even though W-5 JIT secret resolution at apply time means the value is never needed at align/plan time.

Expected

`buildAlignContext` should populate `ctx.secretKeys` with the keys from `cfg.Secrets.Generate` (and `cfg.Secrets.Requires` if the latter exists) at the same time it populates `ctx.secretGens`. R-A4 then correctly skips secrets declared in either form.

Test

```go
// cmd/wfctl/infra_align_test.go (new test)
func TestInfraAlign_RA4_TopLevelSecretsBlock_NoFinding(t *testing.T) {
yaml := `
secrets:
generate:
- key: DB_PASSWORD
type: random_hex
length: 32
modules:

  • name: api
    type: infra.container_service
    config:
    image: "myapp:latest"
    env_vars:
    DB_PASS: "${DB_PASSWORD}"
    `
    // expect zero R-A4 findings
    }
    ```

References

  • Discovery: core-dump deploy.yml C-1 cutover; `feat/c1-staging-pg-cutover` branch
  • W-5 design: `iac/jitsubst/jitsubst.go` (JIT resolution makes plan-time secret-value substitution unnecessary)
  • Related: R-A9 (cmd/wfctl/infra_align_rules.go:683) DOES use top-level `ctx.secretGens` correctly — R-A4 should follow the same pattern

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions