Skip to content

Optional Groups

Optional groups, wrapped in [ and ], match commands with or without the enclosed tokens.

# Matches: git push, git push --force
- allow: 'git push [--force]'
# Matches: rm file.txt, rm -f file.txt
- allow: 'rm [-f] *'

Optional groups can contain multiple tokens including flags with values:

# Matches: curl https://example.com
# Matches: curl -X POST https://example.com
- allow: 'curl [-X|--request POST] *'

Optional groups follow a try-then-skip strategy:

  1. First, try matching with the optional tokens included
  2. If that fails, verify the optional group’s flags are absent from the command, then try matching without them

When an optional group is skipped, runok verifies that any flags in the group are not present in the command. This prevents incorrect matches where a flag is used with an unexpected value:

- allow: 'curl [-X|--request POST] *'
CommandResultReason
curl https://example.comMatchesOptional group is absent
curl -X POST https://example.comMatchesOptional group matches
curl -X DELETE https://example.comDoes not match-X is present but with wrong value
curl -X=POST https://example.comMatches=-joined form is also supported
curl -X=DELETE https://example.comDoes not match-X is present but with wrong value

To match the POSIX [ test command, [ followed by a space (or at end of input) is treated as a literal:

# Matches the POSIX test command: [ -f file ]
- allow: '[ -f * ]'

A ] outside of an optional group is also treated as a literal.

  • Optional groups cannot be nested: [[-f]] is a syntax error
  • Optional groups must be closed: [-f without ] is a syntax error