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
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions