Add policy evaluation support for cloud backend remote query runs. - #39012
Open
sebasslash wants to merge 2 commits into
Open
Add policy evaluation support for cloud backend remote query runs. #39012sebasslash wants to merge 2 commits into
cloud backend remote query runs. #39012sebasslash wants to merge 2 commits into
Conversation
sebasslash
force-pushed
the
tfsearch/cloud-backend-query-plus-policy
branch
from
August 12, 2026 18:33
9c0920f to
4d83440
Compare
When --policies is passed against a cloud backend configured for remote execution, the command layer was unconditionally starting the local tfpolicy-plugin binary, surfacing a spurious 'Failed to connect to policy engine' error even though the operation was about to be delegated entirely to the remote runner. Fix 1 (internal/command/query.go): Guard policy client initialisation with '!isRemoteBackend || b.IsLocalOperations()'. The local client is still started for plain local backends and for the tfc-agent (TF_FORCE_LOCAL_BACKEND) path; it is skipped only when the operation will genuinely run remotely. op.PolicyPaths is always forwarded so the cloud backend can pass paths to the QueryRunCreate API. Fix 2 (internal/cloud/backend.go): In Operation(), when the workspace is in local execution mode, op.PolicyPaths is non-empty, and op.PolicyClient is nil (because IsLocalOperations() was false when the command layer ran), emit a 'Policy evaluation skipped' warning via op.View.Diagnostics before delegating to the local backend. Tests: two new cases in internal/cloud/backend_query_test.go verify (a) the warning fires for the local-exec-mode + nil client scenario, and (b) no warning fires when a policy client is already set.
sebasslash
force-pushed
the
tfsearch/cloud-backend-query-plus-policy
branch
from
August 12, 2026 19:33
4d83440 to
2241cf9
Compare
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.
This PR updates the cloud backend query operation to correctly forward policy paths to HCP Terraform and improve remote policy summary rendering.
A second client (
clientV2) backed by the Kiota-generated go-tfe v2 SDK is now initialised alongside the existing v1 client duringConfigure()so thatPolicyPathscan be forwarded to the HCP Terraform API — the existing go-tfe v1 SDK does not expose this field onQueryRunCreateOptions. TheclientV2is nil-safe: if initialisation fails it is logged as a warning and all existing code paths continue to use the v1 client unchanged.For Terraform Enterprise installations with a non-default base path (e.g.
/tfe/api/v2/), the v2 client is configured withAddress = scheme://hostandBasePath = /tfe/api/v2(trailing slash stripped to avoid double-slash in Kiota URL templates).When
op.PolicyPathsis non-empty andclientV2is non-nil,backend_query.gocalls the newcreateQueryRunV2()helper instead of the v1QueryRuns.Create, and the v2 response is mapped back into thetfe.QueryRuntype the rest of the cloud backend already handles.The local policy engine client (
PolicyClient) is now only initialised when the backend is not a remote backend or the workspace is in local execution mode, since previously it was always started when-policiesflags were provided even for remote-execution workspaces where the policy engine runs server-side.The cloud backend log-streaming loop (
renderQueryRunLogs) now handles thepolicy_query_summaryJSON log record type emitted by the remote runner, parsing and rendering it as a human-readable summary via the new exportedRenderPolicyQuerySummaryFromJSONhelper ininternal/command/views, with malformed records skipped gracefully.The JSON wire field and all internal Go struct fields have been renamed from
passed_policies/PassedPoliciestoevaluated_policies/EvaluatedPoliciesto more accurately reflect that the list contains all policies evaluated against a list block regardless of pass/fail. Result and per-identity labels are now title-cased (Passed,Failed,Error,Unknown) instead ofALLCAPS, the header format changes fromPolicy results for <addr> (FAIL)toPolicy results for <addr> - Failed, and per-identity rows are column-aligned using the width of the longest identity string.Test Coverage
TestCloud_queryWithPolicyPaths— v2 POST path end-to-end with a real HTTP test serverTestCloud_queryWithPolicyPaths_Enterprise— correct URL routing for a TFE installation with a non-default base pathTestCloud_queryWithNilClientV2— fallback to v1 whenclientV2is nilTestCloud_queryWithoutPolicyPaths— v1 path taken when no policy paths are providedTestCloud_queryJSONWithPolicySummary—policy_query_summaryrecords render correctlyTestCloud_queryJSONWithPolicySummaryMalformed— malformed records are skipped and the operation still succeedsTestCloud_opQuery_localExecMode_policyPathsWarning— warning emitted when workspace is in local-exec mode andPolicyClientis nilTestCloud_opQuery_localExecMode_policyPathsWithClient— no warning emitted whenPolicyClientis already setSmoke Testing
To verify the end-to-end policy query flow against a live HCP Terraform workspace:
go build -o terraform . && export PATH="$(pwd):$PATH"terraform login(or setTF_TOKEN_app_terraform_io)main.tfwith at least one resource and a.policyfile targeting itterraform init && terraform workspace select <name>terraform query -policies=./my.policy/api/v2/queries(check HCP Terraform audit logs or a local proxy); the policy paths should appear in the request bodyPolicy results for <addr> - Passed/Failedwith title-cased labels and column-aligned identity rowsclientV2initialisation (e.g. set an invalid token env var for v2 only) and confirm the command still completes using the v1 path with a[WARN]log lineTF_CLOUD_HOSTNAMEaccordingly and confirm no double-slash appears in the request URLTarget Release
1.17.x
Rollback Plan
Changes to Security Controls
Are there any changes to security controls (access controls, encryption, logging) in this pull request? If so, explain.
CHANGELOG entry