Skip to content

fix: apply the verified managed plan snapshot - #6849

Open
chenrui333 wants to merge 2 commits into
mainfrom
fix/validated-plan-snapshot
Open

fix: apply the verified managed plan snapshot#6849
chenrui333 wants to merge 2 commits into
mainfrom
fix/validated-plan-snapshot

Conversation

@chenrui333

@chenrui333 chenrui333 commented Sep 7, 2026

Copy link
Copy Markdown
Member

Summary

Make built-in apply consume a read-only .tfplan snapshot of the exact bytes verified against ExpectedPlanHash. Missing or mismatched hashes fail before Terraform starts. Remote apply compares against the same verified bytes without rereading the mutable source.

Notes

Independent snapshot slice from #6657, based on main including #6781. No plan generations, publication claims, S3 key changes, or custom-run PLANFILE redirection. Successful apply still removes the convention plan through PlanStore.

The snapshot lives in a private system temporary directory and is removed when apply returns. Operators can override the temporary-directory location through TMPDIR. Process crashes may leave temporary copies for the host's temporary-file cleanup. The binding applies to built-in apply consumption; custom scripts retain their existing behavior and are not advertised as cryptographically bound.

Tests cover missing hashes, mutations before/after snapshot creation, permissions, cleanup, and existing direct-context/custom-workflow regressions. Local lint reports three unchanged findings (two modernize suggestions and one deprecated GitLab test field); hosted checks are still required.

Copilot AI lite review requested due to automatic review settings September 7, 2026 05:39
@github-actions github-actions Bot added go Pull requests that update Go code size/m labels Sep 7, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

It changes core apply-time integrity checks and planfile execution behavior, so it warrants careful human validation of error handling and operational edge cases.

Pull request overview

This PR hardens Atlantis’s built-in Terraform apply execution by requiring an ExpectedPlanHash and ensuring apply consumes an immutable, verified snapshot of the plan bytes (instead of reading from a mutable plan file path during execution), including for remote apply flows.

Changes:

  • Enforce ExpectedPlanHash presence and verify SHA-256 of the loaded plan bytes before any apply execution.
  • For local apply, write the verified bytes to a read-only temp snapshot (0400) and pass that snapshot path to Terraform; for remote apply, reuse the verified bytes without re-reading the plan file.
  • Update/apply tests to set ExpectedPlanHash and assert the snapshot behavior, permissions, integrity, and cleanup.
File summaries
File Description
server/core/runtime/apply_step_runner.go Adds plan-hash enforcement and validated snapshot creation; updates remote apply to use verified bytes.
server/core/runtime/apply_step_runner_test.go Extends unit coverage to require hashes and validate snapshot integrity/cleanup and file permissions.
Review details

Suppressed comments (1)

server/core/runtime/apply_step_runner.go:64

  • The new plan-hash mismatch error message is generic; including dir/workspace/project makes it easier to identify which project in a multi-project apply needs a re-plan.
	digest := sha256.Sum256(contents)
	if hex.EncodeToString(digest[:]) != ctx.ExpectedPlanHash {
		return "", fmt.Errorf("plan file changed; run `atlantis plan` before apply")
	}
  • Files reviewed: 2/2 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +58 to +60
if ctx.ExpectedPlanHash == "" {
return "", fmt.Errorf("expected plan hash is missing; run `atlantis plan` before apply")
}
Comment on lines +290 to +292
// Keep execution copies outside the checkout so custom steps still see the
// convention PLANFILE. A private directory also prevents accidental discovery
// by repository globs. Terraform consumes only these verified bytes.
@github-code-quality

github-code-quality Bot commented Sep 7, 2026

Copy link
Copy Markdown

Code Coverage Overview

Languages: Go

Go / code-coverage/go

The overall line coverage in commit 88412e0 in the fix/validated-plan-s... branch is 73%. Line coverage data for the main branch is not yet available.

Show a line coverage summary of the most covered files.
File main fix/validated-plan-s... 88412e0 +/-
server/events/v...ithub/client.go 88%
server/core/ter...aform_client.go 88%
server/controll...i_controller.go 83%
server/events/p...mand_builder.go 83%
server/events/v...itlab/client.go 80%
server/events/p...mmand_runner.go 76%
server/events/event_parser.go 76%
server/events/working_dir.go 73%
server/server.go 70%
server/controll...s_controller.go 64%

Updated September 07, 2026 23:59 UTC

Bind built-in apply execution and remote plan comparison to the exact bytes checked against ExpectedPlanHash. Preserve custom workflow PLANFILE behavior and successful apply cleanup.

Assisted-by: OpenAI GPT-6 <noreply@openai.com>
Signed-off-by: Rui Chen <rui@chenrui.dev>
Clarify that operators can override the system temporary directory.

Assisted-by: OpenAI GPT-6 <noreply@openai.com>
Signed-off-by: Rui Chen <rui@chenrui.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

go Pull requests that update Go code size/m

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants