Repository navigation
Conversation
…HCL parse The Key Vault grant guard matched lines, so it could not see the nested spellings of the inert grant (an access_policy block, static or dynamic, inside azurerm_key_vault), and it read comment and heredoc text as declarations. Four earlier line matchers each got one of those cases wrong because a line has no enclosing resource type. Parse the files with hashicorp/hcl/v2 (hclsyntax) in a small checker, cmd/check-azure-kv-access-policy, which the existing script now runs: - report the azurerm_key_vault_access_policy resource, and access_policy or dynamic "access_policy" blocks that are direct children of an azurerm_key_vault, naming file, line and the enclosing vault; - ignore the same block name in any other resource, prefix-named and same-named attributes, and comment and heredoc text; - exit 2 for a file that does not parse, as for .tf.json, never 0. The CI job gains a setup-go step. The self-test adds fixtures for each case and asserts the reported lines, not only exit codes. Closes LeanerCloud#204 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
Comment |
Bring the branch up to date with main. Conflicted files: - .github/workflows/ci.yml: main (LeanerCloud#1112) added the rollback-ecr-registry job directly above azure-kv-access-policy; this branch rewrote the azure-kv-access-policy job's header comment (the guard now parses HCL and covers nested access_policy blocks, so main's "nested form is not covered" note is stale). Kept main's new job unchanged, followed by the branch's comment and job (with its Set up Go step). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Collaborator
Author
|
Merged origin/main (2374b4e) into this branch. New head: 05aa896. It still merges cleanly with the current main (8f186a8). Conflict resolution:
Checks on the merged head:
|
This branch has not been deployed
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.
The Key Vault grant guard (
scripts/check-azure-kv-access-policy.sh) now parses Terraform as HCL instead of matching lines. It reports the nested spellings of the inert grant only when they sit inside anazurerm_key_vault, and it no longer reads comment or heredoc text as a declaration.Closes #204
Root cause
The guard matched one regex per line. A line can't tell you which resource encloses a block, or whether the text is inside a heredoc or a block comment. So the nested forms (
access_policy { }anddynamic "access_policy" { }insideazurerm_key_vault) were left unchecked on main. The script said so itself (a nested access_policy block is NOT checked). The four earlier rounds in cloud-commitments-cli#1817 were each too narrow or too broad. Separately, main's resource-form regex still fired on the banned literal inside a heredoc or a/* ... */comment.Fix
cmd/check-azure-kv-access-policy(Go, about 200 lines). It parses each file withhashicorp/hcl/v2/hclsyntax, the parser Terraform uses, and walks the top-level blocks:resource "azurerm_key_vault_access_policy"is reported. The parse also handles any indentation, no inter-token spacing, and unquoted labels.resource "azurerm_key_vault", a direct child blockaccess_policyordynamic "access_policy"is reported.azurerm_storage_share'sacl { access_policy { } }), attributes such asaccess_policy_enabled = falseoraccess_policy = "metadata",datasources, comments, and heredoc text.FILE:LINE: <header line as written>. Nested findings add(inside resource "azurerm_key_vault" "<name>")..tf.json, a missing file, or no arguments gives exit 2, never 0.scripts/check-azure-kv-access-policy.shis still the entry point. It keeps the argument checks, default scan roots (terraform/,iac/),.tf.jsonrejection and the remediation text. It now builds the checker into amktemp -ddir and runs it. Exit 0 or 1 is passed through, and anything else (a build failure, a crash, Go missing from PATH) becomes exit 2. The header comment now describes the parse and its limits instead of the old "not checked" note..github/workflows/ci.yml, jobazure-kv-access-policy) gains aSet up Gostep, the same pinnedactions/setup-goandGO_VERSIONthe other jobs use. The job was shell-only, so the checker needs this step.github.com/hashicorp/hcl/v2v2.25.0 (MPL-2.0), plus its transitive depszclconf/go-cty,agext/levenshtein,apparentlymart/go-textseg/{v15,v17},mitchellh/go-wordwrap,golang.org/x/{mod,tools}. Nothing already in the module graph parses HCL, since only HCL v1 was even in the local module cache. The issue explicitly asks forhclparse/hclsyntaxover a fifth text matcher, andterraform show -jsonwould need aterraform init/plan with providers. Only the CI checker imports it, so the server binary doesn't link it.Verification
All of this is fixture/unit evidence: CI-only shell and Go checks, no cloud APIs, no
terraform plan/apply.Fail-before. I ran the new self-test against two old guards: main's guard, and the round-3 "whole block header" matcher from cli
704bdd3a, which is the one the issue describes. Each was dropped into a scratch copy ofscripts/.access_policy {}in a key vault exits 1dynamic "access_policy"in a key vault exits 1access_policyblock/attribute outside a key vault exits 0Totals: main's guard 15 passed and 11 failed, round-3 18 passed and 8 failed, this PR 26 passed and 0 failed. I left one result out of those failure counts because it came from the harness: "default scan roots" also exited 2 under both old guards. The scratch tree symlinked
terraform/andiac/, andfinddoesn't follow symlinked roots. On the real tree it passes:OK: no Key Vault access policy (resource or nested block) declared in 207 Terraform file(s).That run also shows every real.tffile under both roots parses withhclsyntax.Pass-after (this branch):
bash scripts/test-azure-kv-access-policy.sh:Results: 26 passed, 0 failed.The 12 original cases still pass, and 14 are new.go test -count=1 ./cmd/check-azure-kv-access-policy/: ok.TestScanSourcehas 9 cases and asserts the exact rendered findings, with file and line.TestRunExitCodeshas 6 cases, covering clean, violation, no args, missing file, a parse error next to a real finding (exit 2, no stdout), and JSON.main.go, each restored afterwards:TestScanSourcefails.dynamicblock of any label as a grant:TestScanSourcefails. This one survived at first, so I added adynamic "network_acls"case.TestRunExitCodesfails.Commands, with
AWS_CONFIG_FILE=/dev/null AWS_SHARED_CREDENTIALS_FILE=/dev/null AWS_EC2_METADATA_DISABLED=trueand Go 1.26.9:go build ./...,go vet ./...,go vet -tags integration ./...: cleango mod tidy: stable after the changego test ./internal/mocks/ -count=1: okgolangci-lintv2.10.1run --allow-parallel-runners ./cmd/check-azure-kv-access-policy/...: 0 issues. Two gosec taint findings (G703 onos.ReadFile(argv path), G705 onFprintlnto stdout) are suppressed with#nosecand a reason, following the repo's existing pattern.gocyclo -over 10 -ignore "_test\.go" cmd/check-azure-kv-access-policy/main.go: nothing over 10shellcheck0.11.0 onscripts/check-azure-kv-access-policy.shandscripts/test-azure-kv-access-policy.sh: clean. Six other untouchedscripts/test-*.shfiles have shellcheck findings on main; I left them alone.actionlint .github/workflows/ci.yml: clean.zizmorisn't installed locally.Combined-tree verification. This branch was tested together with the other queued branches on a local, never-pushed tree:
queue/platform@b56afb2b= origin/maina14dc8f2plus these heads, merged in this order:fix/issue-324andfix/issue-204both edit.github/workflows/ci.ymlnext to theazure-kv-access-policyjob. The tree kept #324's new "Run Function URL reader self-tests" step and #204's updated job comment; whichever PR merges second takes that same resolution.Linux, Go 1.26.9,
AWS_CONFIG_FILE=/dev/null AWS_SHARED_CREDENTIALS_FILE=/dev/null AWS_EC2_METADATA_DISABLED=true; Docker Postgres via testcontainers. The full suite ran oned0c7174, which differs fromb56afb2bonly by one.gitallowedline on fix/issue-324:go build ./...,go vet ./...,go vet -tags integration ./...and the fullgo test -race -short -count=1 ./....--build-tags integration.gocyclo -over 10is silent on the changed non-test files.-tags integration -count=1, 60-minute local timeout):internal/api,internal/purchase,internal/schedulerandinternal/serverall pass..gitallowedline. Re-run atb56afb2b: git-secrets, using the repo'sscripts/setup-git-secrets.shpatterns in a fresh repo with an isolated HOME, found nothing in the changed files, and a planted fake key was flagged.scripts/test-git-secrets-allowlist.sh: 137 PASS, 0 FAIL.Deploys
This changes only a CI guard, its self-test and a CI job step. Nothing deploys and no Terraform under
terraform/oriac/changes. So the current Azure/GCP deploy pause doesn't block merging it.Deliberately out of scope
access_policy = [ ... ], the azurerm provider's attributes-as-blocks mode) isn't reported. The issue's spec covers the block forms, and the documented use of the attribute form isaccess_policy = []to clear every policy, which is harmless. Flagging non-empty forms would be a small follow-up if wanted. This is a judgment call for the owner.azurerm_key_vaultare checked, which is where the provider schema putsaccess_policy. Modules are scanned as source files, not expanded, the same as before..tf.jsonstays fail-closed (exit 2), as the issue requires.hcl/v2could parse it, but that isn't needed today because none exist.scripts/test-*.shfiles.Please mirror the issue's triage labels onto this PR:
triaged,type/security,effort/m,priority/p3,severity/low,urgency/eventually,impact/internal.🤖 Generated with Claude Code