Comment Parsing#
Atlantis parses every pull request comment to determine whether it contains a valid Atlantis command. The entry point is CommentParser.Parse in server/events/comment_parser.go. The result is a CommentParseResult which holds either a parsed CommentCommand, an immediate CommentResponse (e.g., for help), or an Ignore signal.
Parsing Pipeline#
Parse processes a raw comment through these stages in order:
-
Trim & multi-line filter — strips leading/trailing whitespace and backticks, then rejects comments that contain a non-blank second line via
multiLineRegex. A trailing double-newline (from copy-paste in GitHub) is permitted. -
Executable name check — lowercases the first token and matches it against
["run", <ExecutableName>, "@<VCSUser>"]. Typos that are "similar" to the executable name (or the literal wordterraform) produce a helpful "Did you mean…?" reply . -
Shell re-parse — on a confirmed Atlantis invocation, the full comment is re-parsed with
shlex.Splitto correctly handle quoted arguments. -
Command dispatch — the second token is matched against the allowed commands. Each command (
plan,apply,unlock,version,approve_policies,import,state,cancel) gets its ownpflag.FlagSet. -
Flag parsing & validation —
parseArgsparses flags, extracts subcommands and extra args, then runs blocked-arg checks.validateDirsanitises the-d/--dirvalue. Workspace is validated against URL path encoding,..traversal, and leading~.
Supported Commands & Flags#
| Command | Key Flags |
|---|---|
plan | -w/--workspace, -d/--dir, -p/--project, --verbose |
apply | -w, -d, -p, --auto-merge-disabled, --auto-merge-method, --verbose |
approve_policies | -w, -d, -p, --policy-set, --clear-policy-approval, --verbose |
unlock | (no flags) |
cancel | (no flags) |
version | -w, -d, -p, --verbose |
import | -w, -d, -p, --verbose + positional ADDRESS ID |
state | -w, -d, -p, --verbose + subcommand (e.g. rm ADDRESS...) |
Extra Terraform arguments can be passed after -- (e.g., atlantis plan -- -target=resource).
Command Allowlist#
CommentParser is constructed with an explicit list of permitted commands via AllowCommands . NewCommentParser filters the supplied list against command.AllCommentCommands so only recognised commands are ever enabled. Unknown or disallowed commands return an error referencing the --allow-commands server flag.
Multi-Command Comments (PR #6218)#
PR #6218 adds support for multiple Atlantis commands in a single comment (one command per line):
atlantis plan -d project-a
atlantis plan -d project-b
The resolveCommentCommands helper in server/controllers/events/events_controller.go splits the comment by newline. For a single non-empty line it delegates to CommentParser.Parse directly (preserving existing behavior). For multiple lines, each line is parsed independently; results where Ignore=true are skipped, and the remainder are merged into a single CommentCommand with SubCommands. Mixing command types (e.g., plan + apply) in one comment is rejected with an error.
Security Hardening#
Blocked Extra Args#
PR #6225 introduced protection against injection via -- extra args. DefaultBlockedExtraArgs defines the default blocked list:
-chdir/--chdir— prevents working-directory traversal-plugin-dir/--plugin-dir— prevents loading malicious providers
isBlockedExtraArg rejects any extra arg that exactly matches a blocked entry or starts with <blocked>=. The list is configurable at the server level via --blocked-extra-args (comma-separated); when left empty, UserConfig.ToBlockedExtraArgs() falls back to DefaultBlockedExtraArgs . Setting --blocked-extra-args replaces (not appends to) the default list.
Workspace Validation#
Workspace names are checked against :
- URL path encoding (
url.PathEscape) — rejects special characters ..— prevents path traversal- Leading
~— prevents tilde expansion when the workspace is interpolated into shell commands
Directory Validation#
validateDir handles both plain paths and glob patterns (*, ?, [). For plain paths, filepath.Clean + filepath.Join(".", …) is used and any result starting with .. is rejected. For glob paths, .. traversal is blocked and the pattern is validated with doublestar.ValidatePattern.
Key Files & References#
| Resource | Link |
|---|---|
| Main parser | server/events/comment_parser.go |
| Parser tests | server/events/comment_parser_test.go |
CommentCommand struct | server/events/event_parser.go (lines 109–141) |
User config / ToBlockedExtraArgs | server/user_config.go |
| Multi-command support | PR #6218 |
| Blocked-args security hardening | PR #6225 |