github mattrobinsonsre/terrapod v1.6.6

3 hours ago

A security release for the 1.6 line. It fixes twenty of the twenty-one advisories reported by A3C7, bringing this line level with v1.7.3. It is a drop-in upgrade for most deployments — but four changes alter what an existing, unchanged configuration does. Read Before you upgrade first.

Security

Unauthenticated access, now closed

  • GHSA-cq5h-4hqp-c62v/oauth/authorize and /auth/authorize accepted any redirect_uri, so a crafted link returned an authorization code minted for the victim. Validated at the state-storing chokepoint, so a third route cannot forget it.
  • GHSA-63m3-56rj-qqfh — the runner plan/apply result callbacks and the configuration-version upload required no credential at all. Now authenticated, including the state-version endpoints the report did not name.
  • GHSA-r9v9-24fv-jxm2 — plan logs, apply logs and the plan JSON were served to anyone who knew the run id, which appears in UI links, audit rows and PR comments. Logs now carry a signed, expiring capability in the URL path; the plan JSON takes an ordinary credential.
  • GHSA-fcvc-826r-72m6 — linking a registry module to a workspace was authorised on the module side only, letting any authenticated user force runs in a workspace they had no access to.

Gates that did not hold

  • GHSA-w67x-7rf5-w65g — a plan-only run could be applied, bypassing mandatory policy sets and enforced security scans with nothing but run:apply, recording no override.
  • GHSA-7859-pwwx-vx4f — a workspace variable named TP_API_URL or TP_AUTH_TOKEN overrode the runner's own environment. TP_* is now reserved.

Secrets reaching places they should not

  • GHSA-5mpc-79pv-6mq7 — the AI plan summariser sent values marked sensitive to the configured model endpoint. It now redacts before sending. Stored plans and logs are unchanged; redacting those breaks drift detection.
  • GHSA-3g53-5gw3-hh42 — the MCP server returned an unredacted plan under a readOnly annotation, and ten mutating tools shipped unannotated, so a host could call them — including a governance override — without asking.
  • GHSA-g2c3-vxf6-7jr8terrapod-publish packaged state files, tfvars, dotenv files and private keys into published module tarballs. Published versions are immutable.
  • GHSA-9646-883f-wjjm — secret-bearing Terraform provider attributes were not marked Sensitive, so they landed in plaintext state and printed in plan output. Five attributes are affected on this line; the sixth is on a data source that arrived in 1.7.
  • GHSA-wqfx-wf44-cgvj — a symlink in a migrated Atlantis repository escaped the source guard, uploading another project's Terraform state as this workspace's.
  • GHSA-5fh8-vj57-6gvhgo-terrapod: the platform bearer token survived a redirect that downgraded to http:// or moved host; http:// base URLs were accepted silently; path builders did not escape their parameters; responses were read unbounded; and server bytes were reflected verbatim into operator-facing errors.
  • GHSA-5x47-chx9-ww6c — the plan log was uploaded to Slack with signed storage URLs and userinfo credentials intact.

Key material

  • GHSA-hc47-q72v-4vcm — the key signing runner tokens, run-task callbacks, download tickets and Slack links defaulted to sha256(database_url). New installs now generate a random key. An existing deployment keeps its current derivation on purpose — rotating it would invalidate every token in flight, which is what running plans and applies authenticate with — and warns at startup.
  • GHSA-7rj9-qpm8-6mv3 — two EncryptedText columns were absent from ENCRYPTED_COLUMNS, so DEK rotation silently skipped them. This one carries an operator action — see below.

Hardening

  • GHSA-wq2j-pppw-ff2p — the login rate limit was twenty times its intended value, and X-Forwarded-For was believed from any source.
  • GHSA-46gw-rvrr-jqfx — the console's page routes set no X-Frame-Options or frame-ancestors, so its destructive controls could be framed.
  • GHSA-vg6r-fvfr-27v5 — the bundled web NetworkPolicy's ingress rule had no from: selector, so it admitted all sources when enabled.
  • GHSA-mjhj-g43q-w6m9 — four migrations destroyed security-relevant data with no guard.
  • GHSA-7qcr-cvvg-w58f — a variable value beginning tpenc: collided with the encryption marker and made its own row permanently unreadable.

GHSA-qx93-5mjv-78vq (cloud-IAM database TLS) is not fixed in this release. See Known issues.

Before you upgrade

1. If you have ever rotated a DEK, you are not done. gpg_keys.private_key and run_tasks.hmac_key were never re-keyed, so the old DEK still decrypts both. Upgrading does not fix that for you. Re-run encryption_migrate encrypt, and if you rotated in response to a suspected compromise, treat the GPG signing key and every run-task HMAC key as still exposed and rotate those secrets yourself.

2. If you run networkPolicies.enabled: true, set networkPolicies.web.ingressFrom — the chart now refuses to render without it, because the previous rule admitted every source while reading as a restriction.

3. Rate limiting now attributes clients differently. X-Forwarded-For is believed only from rate_limit.trusted_proxy_cidrs, which defaults to the private ranges plus CGNAT. This relies on your ingress sanitising that header; ingress-nginx and Traefik both do so by default. See the new rate limiting guide, especially if a CDN sits in front.

4. Applying a plan-only run now returns 409. Automation that relied on it will stop working — that is the policy-gate bypass being closed.

5. go-terrapod consumers: an http:// base URL is now a construction error (TERRAPOD_ALLOW_INSECURE_TRANSPORT=1 to opt back in), and the low-level Get/Post/Put/Delete require a rooted path.

6. Terraform provider: five attributes became Sensitive. A configuration referencing one in a non-sensitive output will now fail at plan time.

A run in flight during the upgrade holds a log URL minted before the change and sends no credential, so its CLI log stream ends with a 401. The run itself continues and completes normally; re-attaching gets a fresh URL.

Known issues

  • GHSA-qx93-5mjv-78vq — cloud-IAM database authentication defaults to ssl_mode: require, which encrypts without verifying the server while sending the IAM token as the password. Fixing the default can stop a working deployment connecting, so it ships in 2.0 rather than a patch. Mitigate today by setting api.config.database.ssl_mode: verify-full and pointing ssl_root_cert at your provider's CA bundle. Deployments using password or Kubernetes-secret authentication are unaffected.

  • GHSA-mjhj-g43q-w6m9's task-stage fix is inert on an existing deployment. The migration it corrects is already stamped, so only fresh installs benefit. If a workspace has a task stage whose verdict was cascade-deleted in favour of an empty placeholder, upgrading does not repair it.

Support

1.6 is the previous minor and receives security fixes only. The current line is 1.7. Both lines carry these fixes; upgrading to 1.7.3 is the better move if you can take a minor bump.

Full Changelog: v1.6.5...v1.6.6

Don't miss a new terrapod release

NewReleases is sending notifications on new releases.