Atlantis: Enabling Different Policy Approvers per Directory in a Monorepo

David Gamba, @gambaeng
version 0.1, 2026-04-29 #atlantis #terraform #monorepo #iac

Note
No AI was used to write this!

In this document I go over what I had to do to enable policy approvals in a monorepo setup.

I need different approvers depending on the directory within the monorepo, rather than a single global list:

├── test-collection-1        # owned by user_a
│   └── test-component-1
│       └── terraform
│           ├── main.tf
│           └── ...
└── test-collection-2        # owned by user_b
    └── test-component-1
        └── terraform
            ├── main.tf
            └── ...

Enabling Different Policy Approvers per Directory

The Atlantis Policy Configuration setup is done server-side. This is the first downside with it. It is a global setup that applies to all repos managed by a given instance.

Natively Atlantis seems to support policy_sets, which might lead you to think you can have a different policy set per directory with a different set of approvers each. In practice, all policy sets are run for all changes and you need them all approved, what this feature might give you is the ability to have different teams focusing on reviewing a subset of the policies.

After fumbling around with the policy sets, I finally found that Atlantis allows you to control permissions with external commands. The external command is defined under the team_authz: command: "/path/to/command" in the config as shown below:

Atlantis server-side policy config
policies:
  owners:
    users:
      - user_a # owns a given directory in the monorepo
      - user_b # owns a given directory in the monorepo
    teams:
      # SRE Engineers own everything by default
      # Using the org does not work to define team ownership
      # - my-gh-org/sre-engineers-na
      - sre-engineers-na
  policy_sets:
    - name: all_policies
      path: $PATH_TO_WORKSPACE/policy
      source: local
team_authz:
  command: /etc/atlantis-scripts/authz.sh
Note
I believe that you might need to add all the possible approvers in your config above, user_a and user_b, but I haven’t fully tested if that is true or if as long as the authz.sh script knows how to handle the user, they don’t need to be part of that list.

I mount the authz.sh (AuthZ) script with a ConfigMap. Initially, I tried to make the AuthZ script relative to the repo but it only resolves absolute paths, it doesn’t resolve Env vars like $PULL_NUM. This is unlike the pre_workflow_hooks scripts.

I use a pre_workflow_hooks script to generate the atlantis.yaml for the repo, generate_projects.sh, to bypass having to define it globally:

Atlantis server-side repo config pre_workflow_hooks example
repos:
  - id: github.com/my-gh-org/atlantis-test
    allowed_overrides:
      - workflow
      - repo_locking
      - delete_source_branch_on_merge
      - import_requirements
      - plan_requirements
      - apply_requirements
      - silence_pr_comments
      # Ensure policy checks can run after atlantis plan, regardless of who runs the plan command.
      - policy_check
    allow_custom_workflows: true
    apply_requirements:
      - approved
      - mergeable
      - undiverged
    pre_workflow_hooks:
      - run: /atlantis-data/repos/my-gh-org/atlantis-test/${PULL_NUM}/default/atlantis/generate_projects.sh
        description: Generate project configs

Doing that would have allowed me to define the policies per target repo and without the use of a global script.

Note
In the example above, I added policy_check as one of the repos allowed_overrides, otherwise the AuthZ setup won’t work.

As a workaround, I ended up implementing a JSON file in each repo that controls my policy intent:

Per repo atlantis-policy_owners.json
{
  "*": {
    "users": [],
    "teams": [
      "my-gh-org/sre-engineers-na"
    ]
  },
  "test-collection-1": {
    "users": [
      "user_a"
    ],
    "teams": []
  },
  "test-collection-2": {
    "users": [
      "user_b"
    ],
    "teams": []
  }
}
Note
The AuthZ script gets a list of GitHub teams for the current user. The team here includes the GitHub Org, unlike in the server side config.

The global AuthZ will read the atlantis-policy_owners.json file in each repo and decide if the user is allowed to run a command or not. The atlantis-policy_owners.json file is protected by CODEOWNERS in the repos I deploy it to, so that it doesn’t get modified in a given PR without proper approval. This combined with the mergeable flag ensures no unauthorized applies are allowed.

Below is my actual AuthZ script controlling policy approval permissions:

AuthZ script
#!/bin/bash

# Write to the container's stdout, use /proc/1/fd/2 for stderr
LOG_FILE="/proc/1/fd/1"
if [[ "$(uname)" == "Darwin" ]]; then
	LOG_FILE="/dev/stderr"
fi

# log outputs a structured JSON log line to $LOG_FILE.
# Usage: log <level> [key value]...
log() {
	local msg="$1"
	shift

	# Alpine date command doesn't support ns, hardcode the timestamp to 000z

	local json
	json=$(jq -nc \
		--arg level "info" \
		--arg ts "$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")" \
		--arg caller "authz.sh" \
		--arg msg "$msg" \
		--arg command "$COMMAND" \
		--arg comment_args "$COMMENT_ARGS" \
		--arg repo "$REPO" \
		--arg base_repo_name "$BASE_REPO_NAME" \
		--arg base_repo_owner "$BASE_REPO_OWNER" \
		--arg user "$USER_NAME" \
		--arg teams "${TEAMS[*]}" \
		--arg head_branch "$HEAD_BRANCH_NAME" \
		--arg project "$PROJECT_NAME" \
		--arg pull_num "$PULL_NUM" \
		--arg pull_url "$PULL_URL" \
		--arg pull_author "$PULL_AUTHOR" \
		--arg repo_root "$REPO_ROOT" \
		--arg repo_rel_path "$REPO_REL_PATH" \
		'{
      level: $level,
      ts: $ts,
      caller: $caller,
      msg: $msg,
      json: {
        command: $command,
        comment_args: $comment_args,
        repo: $repo,
        base_repo_name: $base_repo_name,
        base_repo_owner: $base_repo_owner,
        user: $user,
        teams: $teams,
        head_branch: $head_branch,
        project: $project,
        pull: $pull_num,
        pull_url: $pull_url,
        pull_author: $pull_author,
        repo_root: $repo_root,
        path: $repo_rel_path
      }
    }')

	# Append optional extra key-value pairs
	while [[ $# -ge 2 ]]; do
		json=$(echo "$json" | jq -c --arg k "$1" --arg v "$2" '.json += {($k): $v}')
		shift 2
	done

	echo "$json" >>"$LOG_FILE"
}

# Set variables from command-line arguments for convenience
COMMAND="$1"
REPO="$2"
TEAMS=("${@:3}")

# Always allow plans and applies to run for any user.
# Applies only run if there are no pending policy checks so this is safe.
# Additionally, atlantis has command requirements [1] that need to pass,
# for example, mergeable, that ensure that approvals are already met.
#
# [1] https://www.runatlantis.io/docs/command-requirements.html
if [[ $COMMAND == "plan" || $COMMAND == "apply" || $COMMAND == "policy_check" || $COMMAND == "unlock" ]]; then
	log "allow: $COMMAND $COMMENT_ARGS"
	echo "pass"
	exit 0
fi

POLICY_FILE="$REPO_ROOT/atlantis-policy_owners.json"

if [[ $COMMAND == "approve_policies" ]]; then
	# The auth workflow runs every command twice, the first time we allow any command, the second we validate
	# https://www.runatlantis.io/docs/repo-and-project-permissions.html#authorization-workflow
	if [[ "$PULL_NUM" == "0" ]]; then
		log "allow: pre-hooks run of $COMMAND $COMMENT_ARGS"
		echo "pass"
		exit 0
	elif [[ -f "$POLICY_FILE" ]]; then
		# Expected format:
		#
		# {
		#	  "path-to-collection-from-repo-root": {
		#			"users": ["user-a"],
		#			"teams": ["team-a"],
		#		}
		#	}

		# Iterate over each path defined in the policy file
		while read -r policy_path; do
			# Check if REPO_REL_PATH is inside the policy path
			if [[ "$REPO_REL_PATH" == "$policy_path"/* || "$REPO_REL_PATH" == "$policy_path" || "$policy_path" == "*" ]]; then
				# Check TEAMS against the teams list
				for team in "${TEAMS[@]}"; do
					if jq -e --arg t "$team" '.["'"$policy_path"'"].teams | index($t)' "$POLICY_FILE" >/dev/null 2>&1; then
						log "allow: run $COMMAND, team match $team -> $policy_path" "team" "$team" "policy_path" "$policy_path"
						echo "pass"
						exit 0
					fi
				done
				# Check USER_NAME against the users list
				if jq -e --arg u "$USER_NAME" '.["'"$policy_path"'"].users | index($u)' "$POLICY_FILE" >/dev/null 2>&1; then
					log "allow: run $COMMAND, user match $USER_NAME -> $policy_path" "user" "$USER_NAME" "policy_path" "$policy_path"
					echo "pass"
					exit 0
				fi
			fi
		done < <(jq -r 'keys[]' "$POLICY_FILE")
	fi
fi

log "fail: $USER_NAME is not authorized to run $COMMAND $COMMENT_ARGS. Check atlantis-policy_owners.json for details"
echo "fail: $USER_NAME is not authorized to run $COMMAND $COMMENT_ARGS. Check atlantis-policy_owners.json for details"
exit 0

The log output is structured following the current Atlantis log structure. When running locally (in Darwin) I send the logs to stderr, otherwise to the container’s stdout so that it gets picked up by my logging framework.

This works as intended at a high level:

  1. A developer opens a PR.

  2. The policy checks run and there is a change that requires policy approval.

    Policy Check message

    atlantis policy check message

    policy_check GitHub status check failing

    atlantis policy check failing

  3. Only members of the my-gh-org/sre-engineers-na team or the owner of the directory are allowed to approve policies.

  4. If one of those approves the policies, and the PR is in a mergeable state, the developer can run atlantis apply.

    policy_check GitHub status check approved

    atlantis policy check approval

  5. If the developer tries to run atlantis apply before policy approval, it will be blocked by Atlantis.

    Failed apply, missing approval

    atlantis policy check apply fail message

  6. If someone runs approve_policies without permissions, Atlantis blocks any subsequent applies.

However, I found a presentation bug in Atlantis for that last case, if someone runs approve_policies and the AuthZ script disallows them from it, Atlantis will clear the required atlantis/policy_check Github Status Check with the following messages:

{"level":"info","ts":"2026-05-01T16:52:59.795Z","caller":"events/approve_policies_command_runner.go:65","msg":"determined there was no project to run approve_policies in","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}

{"level":"info","ts":"2026-05-01T16:52:59.795Z","caller":"github/client.go:959","msg":"Updating GitHub Check status for 'atlantis-stage/policy_check' to 'success'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
Policy Check Bug

atlantis policy check bug

Atlantis still prevents the apply, but it would be nice if the failing check was still there.

Detailed logs

PR creation logs
{"level":"info","ts":"2026-05-01T16:48:37.917Z","caller":"events/events_controller.go:561","msg":"Handling GitHub Pull Request 'opened' event","json":{"gh-request-id":"X-Github-Delivery=xxx","repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:48:38.000Z","caller":"authz.sh","msg":"allow: plan ","json":{"command":"plan","comment_args":"","repo":"my-gh-org/atlantis-test","base_repo_name":"atlantis-test","base_repo_owner":"my-gh-org","user":"davidgamba-au","teams":"my-gh-org/north-america-engineers-na my-gh-org/sre-engineers-na my-gh-org/north-america-all-na","head_branch":"","project":"","pull":"0","pull_url":"","pull_author":"","repo_root":"","path":""}}
{"level":"info","ts":"2026-05-01T16:48:38.246Z","caller":"events/command_runner.go:203","msg":"Running autoplan...","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:48:38.246Z","caller":"github/client.go:959","msg":"Updating GitHub Check status for 'atlantis-stage/plan' to 'pending'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:48:38.612Z","caller":"events/pre_workflow_hooks_command_runner.go:56","msg":"Pre-workflow hooks configured, running...","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:48:38.615Z","caller":"events/working_dir.go:367","msg":"creating dir '/atlantis-data/repos/my-gh-org/atlantis-test/37/default'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:48:38.743Z","caller":"events/events_controller.go:561","msg":"Handling GitHub Pull Request 'other' event","json":{"gh-request-id":"X-Github-Delivery=xxx","repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:48:38.815Z","caller":"events/events_controller.go:561","msg":"Handling GitHub Pull Request 'other' event","json":{"gh-request-id":"X-Github-Delivery=xxx","repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:48:39.006Z","caller":"events/events_controller.go:561","msg":"Handling GitHub Pull Request 'other' event","json":{"gh-request-id":"X-Github-Delivery=xxx","repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:48:39.055Z","caller":"events/events_controller.go:561","msg":"Handling GitHub Pull Request 'other' event","json":{"gh-request-id":"X-Github-Delivery=xxx","repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:48:39.737Z","caller":"github/client.go:959","msg":"Updating GitHub Check status for 'atlantis-stage/pre_workflow_hook: Generate project configs' to 'pending'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:48:42.042Z","caller":"runtime/pre_workflow_hook_runner.go:83","msg":"Successfully ran 'sh -c /atlantis-data/repos/my-gh-org/atlantis-test/${PULL_NUM}/default/atlantis/generate_projects.sh' in '/atlantis-data/repos/my-gh-org/atlantis-test/37/default'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:48:42.042Z","caller":"github/client.go:959","msg":"Updating GitHub Check status for 'atlantis-stage/pre_workflow_hook: Generate project configs' to 'success'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:48:42.364Z","caller":"events/pre_workflow_hooks_command_runner.go:94","msg":"Pre-workflow hooks completed successfully","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:48:43.512Z","caller":"events/working_dir.go:137","msg":"repo is at correct commit \"yyy\" so will not re-clone","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:48:43.513Z","caller":"events/project_command_builder.go:529","msg":"successfully parsed atlantis.yaml file","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:48:43.513Z","caller":"events/project_command_builder.go:412","msg":"1 projects are to be planned based on their when_modified config","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:48:43.663Z","caller":"events/project_command_pool_executor.go:123","msg":"Running commands in parallel","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:48:43.663Z","caller":"github/client.go:959","msg":"Updating GitHub Check status for 'atlantis-stage/plan: test-collection-1/test-component-1/cicd-03-w2' to 'pending'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:48:44.028Z","caller":"events/project_locker.go:86","msg":"Acquired lock with id 'my-gh-org/atlantis-test/test-collection-1/test-component-1/terraform/cicd-03-w2/test-collection-1/test-component-1/cicd-03-w2'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:48:44.028Z","caller":"events/working_dir.go:367","msg":"creating dir '/atlantis-data/repos/my-gh-org/atlantis-test/37/cicd-03-w2'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:48:46.916Z","caller":"models/shell_command_runner.go:184","msg":"successfully ran 'sh -c' 'rm -rf .terraform' in '/atlantis-data/repos/my-gh-org/atlantis-test/37/cicd-03-w2/test-collection-1/test-component-1/terraform'","json":{"repo":"my-gh-org/atlantis-test","pull":"37","duration":0.000789714}}
{"level":"info","ts":"2026-05-01T16:48:54.634Z","caller":"models/shell_command_runner.go:184","msg":"successfully ran 'sh -c' '/atlantis-data/bin/terraform1.9.4 init -input=false -backend-config /etc/atlantis/admin.config.json' in '/atlantis-data/repos/my-gh-org/atlantis-test/37/cicd-03-w2/test-collection-1/test-component-1/terraform'","json":{"repo":"my-gh-org/atlantis-test","pull":"37","duration":7.716841773}}
{"level":"info","ts":"2026-05-01T16:48:54.661Z","caller":"tfclient/terraform_client.go:387","msg":"Successfully ran '/atlantis-data/bin/terraform1.9.4 workspace show' in '/atlantis-data/repos/my-gh-org/atlantis-test/37/cicd-03-w2/test-collection-1/test-component-1/terraform'","json":{"repo":"my-gh-org/atlantis-test","pull":"37","duration":0.026870207}}
{"level":"info","ts":"2026-05-01T16:48:55.542Z","caller":"tfclient/terraform_client.go:387","msg":"Successfully ran '/atlantis-data/bin/terraform1.9.4 workspace select cicd-03-w2' in '/atlantis-data/repos/my-gh-org/atlantis-test/37/cicd-03-w2/test-collection-1/test-component-1/terraform'","json":{"repo":"my-gh-org/atlantis-test","pull":"37","duration":0.880612512}}
{"level":"info","ts":"2026-05-01T16:49:00.393Z","caller":"models/shell_command_runner.go:184","msg":"successfully ran 'sh -c' '/atlantis-data/bin/terraform1.9.4 plan -input=false -refresh -out \"/atlantis-data/repos/my-gh-org/atlantis-test/37/cicd-03-w2/test-collection-1/test-component-1/terraform/test-collection-1::test-component-1::cicd-03-w2-cicd-03-w2.tfplan\" -var-file /etc/atlantis/backend.config.json -var-file workspaces/$WORKSPACE.tfvars.json' in '/atlantis-data/repos/my-gh-org/atlantis-test/37/cicd-03-w2/test-collection-1/test-component-1/terraform'","json":{"repo":"my-gh-org/atlantis-test","pull":"37","duration":4.851649301}}
{"level":"info","ts":"2026-05-01T16:49:03.792Z","caller":"models/shell_command_runner.go:184","msg":"successfully ran 'sh -c' '/etc/atlantis-scripts/log-plan-to-s3.sh' in '/atlantis-data/repos/my-gh-org/atlantis-test/37/cicd-03-w2/test-collection-1/test-component-1/terraform'","json":{"repo":"my-gh-org/atlantis-test","pull":"37","duration":3.398594636}}
{"level":"info","ts":"2026-05-01T16:49:03.792Z","caller":"github/client.go:959","msg":"Updating GitHub Check status for 'atlantis-stage/plan: test-collection-1/test-component-1/cicd-03-w2' to 'success'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:49:04.104Z","caller":"events/instrumented_project_command_runner.go:91","msg":"plan success. output available at: https://github.com/my-gh-org/atlantis-test/pull/37","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:49:04.887Z","caller":"github/client.go:959","msg":"Updating GitHub Check status for 'atlantis-stage/plan' to 'success'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:49:05.191Z","caller":"events/plan_command_runner.go:182","msg":"Running policy_checks for all plans","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:49:05.191Z","caller":"github/client.go:959","msg":"Updating GitHub Check status for 'atlantis-stage/policy_check' to 'pending'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:49:05.509Z","caller":"events/policy_check_command_runner.go:65","msg":"Running policy_checks in parallel","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:49:05.511Z","caller":"events/project_locker.go:86","msg":"Acquired lock with id 'my-gh-org/atlantis-test/test-collection-1/test-component-1/terraform/cicd-03-w2/test-collection-1/test-component-1/cicd-03-w2'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:49:05.512Z","caller":"models/shell_command_runner.go:184","msg":"successfully ran 'sh -c' 'echo \"${DIR%$REPO_REL_DIR}\"' in '/atlantis-data/repos/my-gh-org/atlantis-test/37/cicd-03-w2/test-collection-1/test-component-1/terraform'","json":{"repo":"my-gh-org/atlantis-test","pull":"37","duration":0.000579463}}
{"level":"info","ts":"2026-05-01T16:49:05.513Z","caller":"models/shell_command_runner.go:184","msg":"successfully ran 'sh -c' 'echo $DIR' in '/atlantis-data/repos/my-gh-org/atlantis-test/37/cicd-03-w2/test-collection-1/test-component-1/terraform'","json":{"repo":"my-gh-org/atlantis-test","pull":"37","duration":0.000620931}}
{"level":"info","ts":"2026-05-01T16:49:07.912Z","caller":"tfclient/terraform_client.go:387","msg":"Successfully ran '/atlantis-data/bin/terraform1.9.4 show -json /atlantis-data/repos/my-gh-org/atlantis-test/37/cicd-03-w2/test-collection-1/test-component-1/terraform/test-collection-1::test-component-1::cicd-03-w2-cicd-03-w2.tfplan' in '/atlantis-data/repos/my-gh-org/atlantis-test/37/cicd-03-w2/test-collection-1/test-component-1/terraform'","json":{"repo":"my-gh-org/atlantis-test","pull":"37","duration":2.39882043}}
{"level":"error","ts":"2026-05-01T16:49:08.287Z","caller":"events/project_command_runner.go:585","msg":"[{\"PolicySetName\":\"all_policies\",\"PolicyOutput\":\"FAIL - <redacted plan file> - main - Resource 'aws_ssm_parameter.foo' is not allowed to be modified without owner review\\n\\n3 tests, 2 passed, 0 warnings, 1 failure, 0 exceptions\\n\",\"Passed\":false,\"ReqApprovals\":1,\"CurApprovals\":0}]","json":{"repo":"my-gh-org/atlantis-test","pull":"37"},"stacktrace":"github.com/runatlantis/atlantis/server/events.(*DefaultProjectCommandRunner).doPolicyCheck\n\tgithub.com/runatlantis/atlantis/server/events/project_command_runner.go:585\ngithub.com/runatlantis/atlantis/server/events.(*DefaultProjectCommandRunner).PolicyCheck\n\tgithub.com/runatlantis/atlantis/server/events/project_command_runner.go:262\ngithub.com/runatlantis/atlantis/server/events.RunAndEmitStats\n\tgithub.com/runatlantis/atlantis/server/events/instrumented_project_command_runner.go:77\ngithub.com/runatlantis/atlantis/server/events.(*InstrumentedProjectCommandRunner).PolicyCheck\n\tgithub.com/runatlantis/atlantis/server/events/instrumented_project_command_runner.go:45\ngithub.com/runatlantis/atlantis/server/events.RunOneProjectCmd\n\tgithub.com/runatlantis/atlantis/server/events/project_command_pool_executor.go:21\ngithub.com/runatlantis/atlantis/server/events.runProjectCmdsParallel.func1\n\tgithub.com/runatlantis/atlantis/server/events/project_command_pool_executor.go:49"}
{"level":"error","ts":"2026-05-01T16:49:08.287Z","caller":"events/instrumented_project_command_runner.go:87","msg":"Failure running policy_check operation: Some policy sets did not pass.","json":{"repo":"my-gh-org/atlantis-test","pull":"37"},"stacktrace":"github.com/runatlantis/atlantis/server/events.RunAndEmitStats\n\tgithub.com/runatlantis/atlantis/server/events/instrumented_project_command_runner.go:87\ngithub.com/runatlantis/atlantis/server/events.(*InstrumentedProjectCommandRunner).PolicyCheck\n\tgithub.com/runatlantis/atlantis/server/events/instrumented_project_command_runner.go:45\ngithub.com/runatlantis/atlantis/server/events.RunOneProjectCmd\n\tgithub.com/runatlantis/atlantis/server/events/project_command_pool_executor.go:21\ngithub.com/runatlantis/atlantis/server/events.runProjectCmdsParallel.func1\n\tgithub.com/runatlantis/atlantis/server/events/project_command_pool_executor.go:49"}
{"level":"info","ts":"2026-05-01T16:49:09.127Z","caller":"github/client.go:959","msg":"Updating GitHub Check status for 'atlantis-stage/policy_check' to 'failure'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:49:09.478Z","caller":"events/post_workflow_hooks_command_runner.go:56","msg":"Post-workflow hooks configured, running...","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:49:09.479Z","caller":"events/working_dir.go:137","msg":"repo is at correct commit \"yyy\" so will not re-clone","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:49:09.479Z","caller":"github/client.go:959","msg":"Updating GitHub Check status for 'atlantis-stage/post_workflow_hook: Audit log' to 'pending'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:49:10.000Z","caller":"audit-log.sh","msg":"plan success for https://github.com/my-gh-org/atlantis-test/pull/37 by davidgamba-au","json":{"hostname":"atlantis-stage-0","command":"plan","comment_args":"","repo":"my-gh-org/atlantis-test","base_repo_name":"atlantis-test","base_repo_owner":"my-gh-org","user":"davidgamba-au","head_branch":"dgamba/test-policies-6","pull":"37","pull_url":"https://github.com/my-gh-org/atlantis-test/pull/37","pull_author":"davidgamba-au","status":"success","head_commit":"yyy","files_changed":["atlantis-policy_owners.json","test-collection-1/test-component-1/terraform/workspaces/cicd-03-w2.tfvars.json"],"pr_approvers":[],"policy_approver":"\"atlantis-cicd-03-w2[bot]\"","resource_changes":{"added":[],"deleted":[],"updated":["aws_ssm_parameter.foo"]}}}
{"level":"info","ts":"2026-05-01T16:49:10.928Z","caller":"runtime/post_workflow_hook_runner.go:84","msg":"Successfully ran 'sh -c /etc/atlantis-scripts/audit-log.sh' in '/atlantis-data/repos/my-gh-org/atlantis-test/37/default'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:49:10.928Z","caller":"github/client.go:959","msg":"Updating GitHub Check status for 'atlantis-stage/post_workflow_hook: Audit log' to 'success'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:49:11.248Z","caller":"events/post_workflow_hooks_command_runner.go:155","msg":"Post-workflow hooks completed","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
Approve policies for unauthorized user. Shows bug by setting policy check to success.
{"level":"info","ts":"2026-05-01T16:52:57.564Z","caller":"events/events_controller.go:694","msg":"Handling 'approve_policies' comment","json":{"gh-request-id":"X-Github-Delivery=xxx","repo":"my-gh-org/atlantis-test","pull":37}}
{"level":"info","ts":"2026-05-01T16:52:57.564Z","caller":"events/events_controller.go:738","msg":"Running comment command 'approve_policies' for user 'davidgamba-au'.","json":{"gh-request-id":"X-Github-Delivery=xxx","repo":"my-gh-org/atlantis-test","pull":37}}
{"level":"info","ts":"2026-05-01T16:52:58.000Z","caller":"authz.sh","msg":"allow: pre-hooks run of approve_policies ","json":{"command":"approve_policies","comment_args":"","repo":"my-gh-org/atlantis-test","base_repo_name":"atlantis-test","base_repo_owner":"my-gh-org","user":"davidgamba-au","teams":"my-gh-org/north-america-engineers-na my-gh-org/sre-engineers-na my-gh-org/north-america-all-na","head_branch":"","project":"","pull":"0","pull_url":"","pull_author":"","repo_root":"","path":""}}
{"level":"info","ts":"2026-05-01T16:52:58.494Z","caller":"events/pre_workflow_hooks_command_runner.go:56","msg":"Pre-workflow hooks configured, running...","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:52:58.495Z","caller":"events/working_dir.go:137","msg":"repo is at correct commit \"yyy\" so will not re-clone","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:52:58.495Z","caller":"github/client.go:959","msg":"Updating GitHub Check status for 'atlantis-stage/pre_workflow_hook: Generate project configs' to 'pending'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:52:58.939Z","caller":"runtime/pre_workflow_hook_runner.go:83","msg":"Successfully ran 'sh -c /atlantis-data/repos/my-gh-org/atlantis-test/${PULL_NUM}/default/atlantis/generate_projects.sh' in '/atlantis-data/repos/my-gh-org/atlantis-test/37/default'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:52:58.939Z","caller":"github/client.go:959","msg":"Updating GitHub Check status for 'atlantis-stage/pre_workflow_hook: Generate project configs' to 'success'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:52:59.235Z","caller":"events/pre_workflow_hooks_command_runner.go:94","msg":"Pre-workflow hooks completed successfully","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:52:59.235Z","caller":"github/client.go:959","msg":"Updating GitHub Check status for 'atlantis-stage/policy_check' to 'pending'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:52:59.000Z","caller":"authz.sh","msg":"fail: davidgamba-au is not authorized to run approve_policies . Check atlantis-policy_owners.json for details","json":{"command":"approve_policies","comment_args":"","repo":"my-gh-org/atlantis-test","base_repo_name":"atlantis-test","base_repo_owner":"my-gh-org","user":"davidgamba-au","teams":"my-gh-org/north-america-engineers-na my-gh-org/sre-engineers-na my-gh-org/north-america-all-na","head_branch":"dgamba/test-policies-6","project":"test-collection-1/test-component-1/cicd-03-w2","pull":"37","pull_url":"https://github.com/my-gh-org/atlantis-test/pull/37","pull_author":"davidgamba-au","repo_root":"/atlantis-data/repos/my-gh-org/atlantis-test/37/default","path":"test-collection-1/test-component-1/terraform"}}
{"level":"info","ts":"2026-05-01T16:52:59.795Z","caller":"events/approve_policies_command_runner.go:65","msg":"determined there was no project to run approve_policies in","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:52:59.795Z","caller":"github/client.go:959","msg":"Updating GitHub Check status for 'atlantis-stage/policy_check' to 'success'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:53:00.167Z","caller":"events/post_workflow_hooks_command_runner.go:56","msg":"Post-workflow hooks configured, running...","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:53:00.168Z","caller":"events/working_dir.go:137","msg":"repo is at correct commit \"yyy\" so will not re-clone","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:53:00.168Z","caller":"events/post_workflow_hooks_command_runner.go:155","msg":"Post-workflow hooks completed","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
Even though the GitHub status shows the policy as success with 0/0 projects, atlantis apply fails (which is the correct behaviour).
{"level":"info","ts":"2026-05-01T16:56:04.770Z","caller":"events/events_controller.go:694","msg":"Handling 'apply' comment","json":{"gh-request-id":"X-Github-Delivery=xxx","repo":"my-gh-org/atlantis-test","pull":37}}
{"level":"info","ts":"2026-05-01T16:56:04.770Z","caller":"events/events_controller.go:738","msg":"Running comment command 'apply' for user 'davidgamba-au'.","json":{"gh-request-id":"X-Github-Delivery=xxx","repo":"my-gh-org/atlantis-test","pull":37}}
{"level":"info","ts":"2026-05-01T16:56:05.000Z","caller":"authz.sh","msg":"allow: apply ","json":{"command":"apply","comment_args":"","repo":"my-gh-org/atlantis-test","base_repo_name":"atlantis-test","base_repo_owner":"my-gh-org","user":"davidgamba-au","teams":"my-gh-org/north-america-engineers-na my-gh-org/sre-engineers-na my-gh-org/north-america-all-na","head_branch":"","project":"","pull":"0","pull_url":"","pull_author":"","repo_root":"","path":""}}
{"level":"info","ts":"2026-05-01T16:56:05.787Z","caller":"github/client.go:959","msg":"Updating GitHub Check status for 'atlantis-stage/apply' to 'pending'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:56:06.128Z","caller":"events/pre_workflow_hooks_command_runner.go:56","msg":"Pre-workflow hooks configured, running...","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:56:06.129Z","caller":"events/working_dir.go:137","msg":"repo is at correct commit \"yyy\" so will not re-clone","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:56:06.129Z","caller":"github/client.go:959","msg":"Updating GitHub Check status for 'atlantis-stage/pre_workflow_hook: Generate project configs' to 'pending'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:56:06.623Z","caller":"runtime/pre_workflow_hook_runner.go:83","msg":"Successfully ran 'sh -c /atlantis-data/repos/my-gh-org/atlantis-test/${PULL_NUM}/default/atlantis/generate_projects.sh' in '/atlantis-data/repos/my-gh-org/atlantis-test/37/default'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:56:06.623Z","caller":"github/client.go:959","msg":"Updating GitHub Check status for 'atlantis-stage/pre_workflow_hook: Generate project configs' to 'success'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:56:06.978Z","caller":"events/pre_workflow_hooks_command_runner.go:94","msg":"Pre-workflow hooks completed successfully","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:56:08.000Z","caller":"authz.sh","msg":"allow: apply ","json":{"command":"apply","comment_args":"","repo":"my-gh-org/atlantis-test","base_repo_name":"atlantis-test","base_repo_owner":"my-gh-org","user":"davidgamba-au","teams":"my-gh-org/north-america-engineers-na my-gh-org/sre-engineers-na my-gh-org/north-america-all-na","head_branch":"dgamba/test-policies-6","project":"test-collection-1/test-component-1/cicd-03-w2","pull":"37","pull_url":"https://github.com/my-gh-org/atlantis-test/pull/37","pull_author":"davidgamba-au","repo_root":"/atlantis-data/repos/my-gh-org/atlantis-test/37/default","path":"test-collection-1/test-component-1/terraform"}}
{"level":"info","ts":"2026-05-01T16:56:08.224Z","caller":"events/project_command_pool_executor.go:123","msg":"Running commands in parallel","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:56:08.224Z","caller":"github/client.go:959","msg":"Updating GitHub Check status for 'atlantis-stage/apply: test-collection-1/test-component-1/cicd-03-w2' to 'pending'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:56:09.050Z","caller":"github/client.go:959","msg":"Updating GitHub Check status for 'atlantis-stage/apply: test-collection-1/test-component-1/cicd-03-w2' to 'failure'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"error","ts":"2026-05-01T16:56:09.402Z","caller":"events/instrumented_project_command_runner.go:87","msg":"Failure running apply operation: All policies must pass for project before running apply.","json":{"repo":"my-gh-org/atlantis-test","pull":"37"},"stacktrace":"github.com/runatlantis/atlantis/server/events.RunAndEmitStats\n\tgithub.com/runatlantis/atlantis/server/events/instrumented_project_command_runner.go:87\ngithub.com/runatlantis/atlantis/server/events.(*InstrumentedProjectCommandRunner).Apply\n\tgithub.com/runatlantis/atlantis/server/events/instrumented_project_command_runner.go:49\ngithub.com/runatlantis/atlantis/server/events.RunOneProjectCmd\n\tgithub.com/runatlantis/atlantis/server/events/project_command_pool_executor.go:21\ngithub.com/runatlantis/atlantis/server/events.runProjectCmds\n\tgithub.com/runatlantis/atlantis/server/events/project_command_pool_executor.go:68\ngithub.com/runatlantis/atlantis/server/events.runGroup\n\tgithub.com/runatlantis/atlantis/server/events/project_command_pool_executor.go:197\ngithub.com/runatlantis/atlantis/server/events.runProjectCmdsWithCancellationTracker\n\tgithub.com/runatlantis/atlantis/server/events/project_command_pool_executor.go:139\ngithub.com/runatlantis/atlantis/server/events.(*ApplyCommandRunner).Run\n\tgithub.com/runatlantis/atlantis/server/events/apply_command_runner.go:163\ngithub.com/runatlantis/atlantis/server/events.(*DefaultCommandRunner).RunCommentCommand\n\tgithub.com/runatlantis/atlantis/server/events/command_runner.go:427"}
{"level":"info","ts":"2026-05-01T16:56:10.154Z","caller":"github/client.go:959","msg":"Updating GitHub Check status for 'atlantis-stage/apply' to 'failure'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:56:10.520Z","caller":"events/automerger.go:23","msg":"not automerging because project at dir \"test-collection-1/test-component-1/terraform\", workspace \"cicd-03-w2\" has status \"apply_errored\"","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:56:10.520Z","caller":"events/post_workflow_hooks_command_runner.go:56","msg":"Post-workflow hooks configured, running...","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:56:10.521Z","caller":"events/working_dir.go:137","msg":"repo is at correct commit \"yyy\" so will not re-clone","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:56:10.521Z","caller":"github/client.go:959","msg":"Updating GitHub Check status for 'atlantis-stage/post_workflow_hook: Audit log' to 'pending'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:56:11.000Z","caller":"audit-log.sh","msg":"apply failed for https://github.com/my-gh-org/atlantis-test/pull/37 by davidgamba-au","json":{"hostname":"atlantis-stage-0","command":"apply","comment_args":"","repo":"my-gh-org/atlantis-test","base_repo_name":"atlantis-test","base_repo_owner":"my-gh-org","user":"davidgamba-au","head_branch":"dgamba/test-policies-6","pull":"37","pull_url":"https://github.com/my-gh-org/atlantis-test/pull/37","pull_author":"davidgamba-au","status":"failed","head_commit":"yyy","files_changed":["atlantis-policy_owners.json","test-collection-1/test-component-1/terraform/workspaces/cicd-03-w2.tfvars.json"],"pr_approvers":["autonomic-bot-sre"],"policy_approver":"\"davidgamba-au\"","resource_changes":{"added":[],"deleted":[],"updated":["aws_ssm_parameter.foo"]}}}
{"level":"info","ts":"2026-05-01T16:56:11.828Z","caller":"runtime/post_workflow_hook_runner.go:84","msg":"Successfully ran 'sh -c /etc/atlantis-scripts/audit-log.sh' in '/atlantis-data/repos/my-gh-org/atlantis-test/37/default'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:56:11.828Z","caller":"github/client.go:959","msg":"Updating GitHub Check status for 'atlantis-stage/post_workflow_hook: Audit log' to 'success'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T16:56:12.208Z","caller":"events/post_workflow_hooks_command_runner.go:155","msg":"Post-workflow hooks completed","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
Successful policy approval when user is authorized.
{"level":"info","ts":"2026-05-01T17:01:13.896Z","caller":"events/events_controller.go:694","msg":"Handling 'approve_policies' comment","json":{"gh-request-id":"X-Github-Delivery=xxx","repo":"my-gh-org/atlantis-test","pull":37}}
{"level":"info","ts":"2026-05-01T17:01:13.896Z","caller":"events/events_controller.go:738","msg":"Running comment command 'approve_policies' for user 'davidgamba-au'.","json":{"gh-request-id":"X-Github-Delivery=xxx","repo":"my-gh-org/atlantis-test","pull":37}}
{"level":"info","ts":"2026-05-01T17:01:14.000Z","caller":"authz.sh","msg":"allow: pre-hooks run of approve_policies ","json":{"command":"approve_policies","comment_args":"","repo":"my-gh-org/atlantis-test","base_repo_name":"atlantis-test","base_repo_owner":"my-gh-org","user":"davidgamba-au","teams":"my-gh-org/north-america-engineers-na my-gh-org/sre-engineers-na my-gh-org/north-america-all-na","head_branch":"","project":"","pull":"0","pull_url":"","pull_author":"","repo_root":"","path":""}}
{"level":"info","ts":"2026-05-01T17:01:14.692Z","caller":"events/pre_workflow_hooks_command_runner.go:56","msg":"Pre-workflow hooks configured, running...","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T17:01:14.693Z","caller":"events/working_dir.go:137","msg":"repo is at correct commit \"yyy\" so will not re-clone","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T17:01:14.693Z","caller":"github/client.go:959","msg":"Updating GitHub Check status for 'atlantis-stage/pre_workflow_hook: Generate project configs' to 'pending'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T17:01:15.158Z","caller":"runtime/pre_workflow_hook_runner.go:83","msg":"Successfully ran 'sh -c /atlantis-data/repos/my-gh-org/atlantis-test/${PULL_NUM}/default/atlantis/generate_projects.sh' in '/atlantis-data/repos/my-gh-org/atlantis-test/37/default'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T17:01:15.159Z","caller":"github/client.go:959","msg":"Updating GitHub Check status for 'atlantis-stage/pre_workflow_hook: Generate project configs' to 'success'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T17:01:15.482Z","caller":"events/pre_workflow_hooks_command_runner.go:94","msg":"Pre-workflow hooks completed successfully","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T17:01:15.482Z","caller":"github/client.go:959","msg":"Updating GitHub Check status for 'atlantis-stage/policy_check' to 'pending'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T17:01:16.000Z","caller":"authz.sh","msg":"allow: run approve_policies, user match davidgamba-au -> test-collection-1","json":{"command":"approve_policies","comment_args":"","repo":"my-gh-org/atlantis-test","base_repo_name":"atlantis-test","base_repo_owner":"my-gh-org","user":"davidgamba-au","teams":"my-gh-org/north-america-engineers-na my-gh-org/sre-engineers-na my-gh-org/north-america-all-na","head_branch":"dgamba/test-policies-6","project":"test-collection-1/test-component-1/cicd-03-w2","pull":"37","pull_url":"https://github.com/my-gh-org/atlantis-test/pull/37","pull_author":"davidgamba-au","repo_root":"/atlantis-data/repos/my-gh-org/atlantis-test/37/default","path":"test-collection-1/test-component-1/terraform","policy_path":"test-collection-1"}}
{"level":"info","ts":"2026-05-01T17:01:16.050Z","caller":"events/project_locker.go:86","msg":"Acquired lock with id 'my-gh-org/atlantis-test/test-collection-1/test-component-1/terraform/cicd-03-w2/test-collection-1/test-component-1/cicd-03-w2'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T17:01:16.242Z","caller":"events/instrumented_project_command_runner.go:91","msg":"approve_policies success. output available at: https://github.com/my-gh-org/atlantis-test/pull/37","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T17:01:17.009Z","caller":"github/client.go:959","msg":"Updating GitHub Check status for 'atlantis-stage/policy_check' to 'success'","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T17:01:17.345Z","caller":"events/post_workflow_hooks_command_runner.go:56","msg":"Post-workflow hooks configured, running...","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T17:01:17.347Z","caller":"events/working_dir.go:137","msg":"repo is at correct commit \"yyy\" so will not re-clone","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}
{"level":"info","ts":"2026-05-01T17:01:17.347Z","caller":"events/post_workflow_hooks_command_runner.go:155","msg":"Post-workflow hooks completed","json":{"repo":"my-gh-org/atlantis-test","pull":"37"}}

Existing GitHub Issues

Here are some existing issues that are related. I haven’t yet created an issue for the bug I describe above.