Join our Newsletter — 33% off our NHI Course
Home› Guides› Atlantis Security: Protect Terraform Pull Request Automation and…
Guide Software & AI Supply Chain

Atlantis Security: Protect Terraform Pull Request Automation and Cloud Credentials

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 8 November 2026 14 min read
On this page

Atlantis runs terraform plan and apply on a server that holds credentials to your cloud accounts, so anyone who can open or comment on a pull request it trusts can, in effect, run code next to those credentials. This guide covers the customer side of running Atlantis safely: which repositories and webhooks it accepts, who may run which commands, how to keep a malicious plan from reaching cloud credentials, how to scope the Git host token and provider credentials, and what to log. It is written for platform engineers, DevOps teams and security reviewers who operate a self hosted Atlantis server. For pipeline credential patterns that apply to any Terraform automation, see the Terraform and IaC Pipeline Credential Security Guide.

This is an independent guide from NHI Mgmt Group, based on Atlantis's public documentation as of November 2026. It is not sponsored or reviewed by the Atlantis project. Product features change, so confirm settings against Atlantis's current documentation.

Key takeaways

  • Treat plan as code execution. The Atlantis docs state that a malicious provider or an external data source can run code during terraform plan, so apply approvals alone do not protect credentials.
  • Accept only what you own. Set a narrow --repo-allowlist, a webhook secret of more than 24 random characters and HTTPS, and leave --allow-fork-prs at its default of false.
  • Control behaviour from the server side. The repo level atlantis.yaml is read from the pull request branch, so keep workflows, overrides and requirements in the server side repos.yaml.
  • Gate apply by people and policy. Use apply_requirements: [approved, mergeable], --gh-team-allowlist or a team_authz command, and Conftest policy checks with named policy owners.
  • Scope the credentials Atlantis holds. Prefer cloud workload roles over static keys, separate roles per environment, restrict egress for provider downloads, and protect the web UI and API with their own secrets.

How identity and access work in Atlantis

Atlantis has no user directory of its own. It listens for webhooks from your Git host (GitHub, GitLab, Bitbucket, Azure DevOps or Gitea), reacts to pull request events and comments such as atlantis plan and atlantis apply, and posts results back using a Git host identity. Who may trigger work is decided by four layers: which repositories the server accepts, whether a webhook is genuine, who the Git host says the commenter is, and what the server side configuration allows that person to do.

LayerSettingDocumented defaultCustomer action
Repository scope--repo-allowlistRequired flag; * accepts every repositoryList your organisation or named repositories; use ! entries to exclude untrusted repositories
Webhook authenticityATLANTIS_GH_WEBHOOK_SECRET, ATLANTIS_GITLAB_WEBHOOK_SECRET; Basic auth for Azure DevOpsOptionalAlways set; more than 24 random characters; same secret on each repository webhook
Transport--ssl-cert-file, --ssl-key-file or a TLS terminating proxyHTTP unless configuredServe HTTPS so the webhook secret cannot be read in transit
Fork pull requests--allow-fork-prsfalseKeep false; Atlantis also only runs for pull requests whose head repository is on the same host
Who can run commands--gh-team-allowlist or team_authzAny team can plan and applyRestrict apply and import to named teams
Which commands exist--allow-commandsversion,plan,apply,unlock,approve_policies,cancelAdd import and state only where needed; avoid all

Atlantis checks authorisation twice: once for the repository as a whole after a command is validated, and again per project after pre workflow hooks run and affected projects are known. An external team_authz command receives the command name, repository and the user's teams, plus variables such as PROJECT_NAME, BASE_BRANCH_NAME and PULL_AUTHOR, and must print pass on its last line with exit code 0 to allow the action. The two options are mutually exclusive: when team_authz is defined, --gh-team-allowlist is ignored.

Approval semantics depend on the Git host

The approved requirement means at least one approval by someone other than the author, and the Atlantis docs note that on GitHub any user with read permission can approve. Pair approved with mergeable, so that branch protection rules (required reviewers, CODEOWNERS, status checks) decide whether an apply may run. Atlantis also offers undiverged, which requires project files to be ahead of the base branch, and the current docs state that atlantis state rm must satisfy both apply_requirements and import_requirements.

Admin roles and privileged access

The most privileged roles in an Atlantis deployment are not inside Atlantis: they are the people who can change the server's flags and repos.yaml, read its environment, or exec into its container. Treat the Atlantis host, its Helm values or task definition, and its data directory as tier zero for every cloud account it can change.

  • Server configuration owners: keep repos.yaml, server flags and policy sets in a separate, protected repository with its own reviewers. A change there can relax every guard on this page.
  • Repo level overrides: allowed_overrides lists which keys a repository's own atlantis.yaml may change (for example apply_requirements, workflow, repo_locks, policy_check). Grant overrides per repository ID, not to /.*/, and leave allow_custom_workflows false unless a repository genuinely needs its own steps.
  • Custom workflows and hooks: custom run steps and pre_workflow_hooks execute shell commands on the server. Define them only in server side configuration and use allowed_workflows to name the ones a repository may select.
  • Policy owners: under policies.owners, list the users or teams who may run atlantis approve_policies to override a failed policy. Keep this group small and distinct from day to day committers.
  • Host access: restrict SSH, kubectl exec and ECS Exec on the Atlantis workload to the platform team. The Atlantis docs note that if you can exec into the server and run Terraform, Atlantis will work; the same is true for anyone else with that access.
Control pointWhere it livesWho should hold it
Server flags and environmentHelm values, Kubernetes Secret, ECS task definition or systemd unitPlatform team, changes by pull request
repos.yaml and workflowsServer side config file, ideally baked into the image or mounted read onlyPlatform and security reviewers
Policy sets and ownerspolicies block in repos.yamlSecurity or cloud governance team
Production apply--gh-team-allowlist or team_authz plus branch protectionNamed deployers per environment
Locks and unlockWeb UI and atlantis unlockAuthenticated operators only

Integrations, API tokens and service accounts

An Atlantis server holds several non-human credentials. Inventory each one, give it a named owner and record where it is stored. See the Secrets Management Guide for storage patterns.

CredentialPurposeScope guidance from the docsOur recommendation
Git host token or GitHub AppClone, comment, set commit statusesGitHub token with repo scope, or a GitHub App whose permissions are set at creation; GitLab token with api scope; Bitbucket Cloud token with Read project and Write pull request permissionsPrefer a GitHub App installed only on allowlisted repositories; use a dedicated bot account, never a person's token
Webhook secretProve webhooks came from the Git hostMore than 24 characters; same secret for each repositoryGenerate randomly, store in a secret manager, rotate on staff changes
Web UI credentialsBasic auth on the locks and jobs UI--web-basic-auth with --web-username and --web-password (password default is atlantis)Set a long random password, or front the UI with an SSO proxy
API secretAuthenticate /api/* calls via the X-Atlantis-Token header--api-secret; the API is experimental and gated by the api or drift-detection experimentEnable only when used; store and rotate like any API key
Cloud provider credentialsTerraform plan and applyInstance roles, GCE service accounts, environment variables, credential files or the Vault providerUse workload roles; avoid long lived access keys in environment variables

GitHub App permissions after upgrades

The Atlantis docs record that new GitHub App permissions were added over time (Administration from v0.19.7, Members from v0.22.3 for team based features, Actions from v0.30.0 for mergeable checks) and that upgrades do not add them automatically. When you grant a new permission, record why, and review the App's permission list after each upgrade so it stays at what your enabled features need.

Provider credentials by environment

Atlantis passes whatever credentials the host has to every Terraform run. To limit blast radius, run separate Atlantis instances (or separate workloads) per trust boundary, such as one for production accounts and one for non production. With AWS, the docs describe using a credentials file whose default profile can assume each required role; use assume role session names that include the Atlantis user, repository and pull request number so CloudTrail shows who triggered each change. Keep state backend credentials as tightly scoped as the provider role, because state files hold resource attributes that can include secrets. See the Cloud Workload Identity Guide for role based patterns.

Protecting against malicious plans

The Atlantis security page lists the main ways a server can be misused: a pull request containing a malicious provider or external data source that runs during an automatic plan, a local-exec provisioner that runs on apply, malicious custom build commands in an atlantis.yaml taken from the pull request branch, and unwanted atlantis plan or apply comments. The defences below come from that page and the server configuration reference.

  1. Control provider sources. Bake approved providers into the Atlantis image or host and deny public egress in production, or run an internal provider registry so you decide who can publish to it.
  2. Validate before plan. Add steps to the server side plan workflow that reject disallowed providers, data sources or authors; the docs suggest Conftest for this and even requiring a reaction on the pull request before plan continues.
  3. Limit autoplan where risk is high. --disable-autoplan or --disable-autoplan-label stop plans running on every push, so a human chooses when untrusted changes are planned.
  4. Restrict variable files. Keep --var-file-allowlist at its default (the Atlantis data directory) or a named directory, so comments such as atlantis plan -- -var-file=... cannot read arbitrary server files.
  5. Require explicit project applies. --disable-apply-all forces each apply to name a project, workspace or directory.
  6. Check plans with policy. Enable --enable-policy-checks, define policy_sets and owners, and add policies_passed to apply requirements. If you use --gh-team-allowlist, allowlist the internal policy_check command too, or manual plans will skip policy checks.

Policy checks run against plan output, which is after plan code has executed, so they complement egress and provider controls rather than replace them. See the OWASP CI/CD Top 10 CICD-SEC-4 Poisoned Pipeline Execution Guide for the wider pattern.

Logging and detection

Atlantis activity is spread across three places: the Git host (pull request comments, approvals, webhook deliveries), the Atlantis server (logs and metrics) and the cloud provider (API calls made by Terraform). Correlate them by pull request number.

SourceWhat to collectWhat to alert on
Atlantis server logsRun at --log-level=info and ship to your SIEMWebhook validation failures, commands from unexpected users, unlocks, policy approvals
Atlantis metricsPrometheus or StatsD via the metrics block in server side configSpikes in command errors or execution counts outside change windows
Git host audit logWebhook changes, App installation and permission changes, branch protection editsWebhook secret changed or removed; App installed on new repositories
Pull request commentsAll atlantis commands and who issued themapply, import or state on production projects by people outside the deployer group
Cloud audit logsCloudTrail, Azure Activity Log or Cloud Audit Logs for the Atlantis roleCalls from the Atlantis role outside a running job, or from unexpected networks

Metrics to track (our suggestions): share of allowlisted repositories with a webhook secret (target 100 percent); production applies with an approval and passing policy checks (target 100 percent); policy overrides per month and who approved them; age of the Git host token and webhook secret; number of static cloud keys on Atlantis hosts (target zero).

Hardening baseline

A phased rollout keeps teams working while the controls tighten. Test each phase on a non production Atlantis instance first; every step below can be rolled back by reverting the server configuration pull request.

  1. Phase 1, perimeter: set --repo-allowlist to named repositories, set the webhook secret, serve HTTPS, keep --allow-fork-prs false, and turn on --web-basic-auth with a strong password or an SSO proxy. Keep the server off the public internet except for webhook delivery, and restrict that path to your Git host's published address ranges where you can.
  2. Phase 2, who can do what: move workflows and requirements into repos.yaml, set apply_requirements: [approved, mergeable], restrict apply with --gh-team-allowlist or team_authz, and limit allowed_overrides.
  3. Phase 3, credentials: replace static keys with workload roles, split production and non production, add session names for traceability and store every secret in a secret manager rather than plain flags.
  4. Phase 4, plan safety: restrict egress, bake or mirror providers, add pre plan validation and enable Conftest policy checks with owners. Start policies as warnings in non production, then enforce.
  5. Phase 5, operate: forward logs and metrics, review App permissions after every upgrade, and apply Atlantis releases promptly using the project's security advisories.

Decision guidance

  • Small team, private repositories: one instance, organisation wide allowlist, team allowlist for apply and policy checks on production projects is a sound baseline.
  • Large or regulated estate: separate instances per environment or business unit, team_authz for per project rules, a private provider registry and egress controls.
  • Public repositories: the Atlantis docs advise against running on public repositories, because anyone can comment; if you must, keep forks disabled, disable autoplan and require approval before any plan.

Common misconfigurations

  • Wildcard allowlist without a webhook secret: --repo-allowlist=* is only reasonable in a protected network and, per the docs, dangerous without a webhook secret, because anyone who reaches the endpoint can pose as an allowlisted repository.
  • Trusting repo level configuration: allowing allow_custom_workflows: true or broad allowed_overrides for every repository lets a pull request change its own build steps, since atlantis.yaml is read from the pull request branch.
  • Relying on apply approval alone: plan time code execution reaches credentials before anyone approves an apply; add egress and provider controls.
  • One all powerful cloud identity: a single role with administrator rights across every account turns any accepted pull request into full estate access.
  • Default web credentials: leaving basic auth off, or the password at its documented default, exposes locks and job output that may include plan details.
  • Team allowlist without policy_check: manual plans then skip policy checks while autoplans still run them, which hides gaps.

Framework mapping

Control areaNIST SP 800-53 Rev 5MITRE ATT&CK risk addressedOWASP CI/CD Top 10
Repository allowlist, fork controls, pre plan validationCM-3 Configuration Change Control, SA-10 Developer Configuration ManagementT1195.002 Compromise Software Supply ChainCICD-SEC-4 Poisoned Pipeline Execution
Team allowlist, apply requirements, policy ownersAC-6 Least PrivilegeT1078.004 Cloud AccountsCICD-SEC-1 Insufficient Flow Control Mechanisms
Webhook secret, Git host token, cloud rolesIA-5 Authenticator ManagementT1552.001 Credentials In FilesCICD-SEC-6 Insufficient Credential Hygiene
Provider egress control and private registrySR-3 Supply Chain Controls and Processes, CM-7 Least FunctionalityT1195.002 Compromise Software Supply ChainCICD-SEC-3 Dependency Chain Abuse
Server logs, metrics, cloud auditAU-2 Event LoggingT1078.004 Cloud AccountsCICD-SEC-10 Insufficient Logging and Visibility

Practitioner checklist

  • Set --repo-allowlist to your organisation or named repositories, with ! exclusions for untrusted ones.
  • Configure a random webhook secret of more than 24 characters on every repository and serve Atlantis over HTTPS.
  • Keep --allow-fork-prs false and do not run Atlantis on public repositories.
  • Define workflows, requirements and allowed_overrides in server side repos.yaml; keep allow_custom_workflows off by default.
  • Require approved and mergeable for apply, import and state commands, backed by branch protection.
  • Restrict apply to named teams with --gh-team-allowlist or team_authz, and allowlist policy_check when using team lists.
  • Enable Conftest policy checks with a small owner group and add policies_passed for production.
  • Replace static cloud keys with workload roles, separated by environment, with traceable session names.
  • Restrict egress and source providers from a baked image or private registry.
  • Enable web basic auth with a strong password or SSO proxy, and set --api-secret only when the API is used.
  • Forward server logs, metrics and cloud audit events, and review GitHub App permissions after each upgrade.

Standards and references

Related NHI Mgmt Group resources: Infrastructure as Code Security Guide, Terraform and IaC Pipeline Credential Security Guide, Webhook Secrets Security Guide, CI/CD Pipeline Identity Security Guide, Policy-as-Code for Authorisation Guide.

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 8 November 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org