Skip to content

feat(config): allow wildcard matches in import statements - #1816

Merged
Xe merged 11 commits into
mainfrom
Xe/import-glob
Aug 6, 2026
Merged

feat(config): allow wildcard matches in import statements#1816
Xe merged 11 commits into
mainfrom
Xe/import-glob

Conversation

@Xe

@Xe Xe commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Allow importing files matching wildcard patterns using path/filepath#Match. For example:

bots:
  # Every rule file in the (data)/crawlers folder.
  - import: (data)/crawlers/*.yaml
  # Every rule file you put in /etc/anubis/known-good.
  - import: /etc/anubis/known-good/*.yaml

Supported wildcards

Anubis uses the Go standard library function filepath.Match for matching. It supports four wildcards:

Wildcard Matches Example
* Any run of characters in one folder crawlers/*.yaml matches crawlers/kagibot.yaml, but not crawlers/eu/kagibot.yaml.
? Exactly one character ??-allow.yaml matches 00-allow.yaml and xe-allow.yaml, but not 1-allow.yaml.
[0-9] One character from a set or range [0-9][0-9]-*.yaml matches 00-monitoring.yaml, but not xe-monitoring.yaml.
[^0-9] One character not in a set or range [^0-9]*.yaml matches xe.yaml, but not 00-xe.yaml.

Use this Go playground link to test pattern matches.

Matched files load in natural sort order

Anubis matches requests top to bottom, similar to Apache's DENY, ALLOW ACL. Anubis uses the first rule that matches the request exactly. A rule that loads early can shadow a rule that loads later.

When Anubis loads files imported with a wildcard match, it sorts the files in natural sort order. To control the order rules are loaded, put a number at the beginning of each filename:

/etc/anubis/known-good/
├── 00-allow-monitoring.yaml
├── 01-allow-git-clients.yaml
├── 02-allow-techaro-ci-bot.yaml
└── 10-weigh-everything-else.yaml

Natural sort compares numbers numerically and words alphabetically. This makes 02-deny.yaml load before 10-deny.yaml.

Every matched file must be a top level list

Anubis combines the matched files into one YAML document and then parses that document. Write each file as a list of rules at the top level, with no indentation and no bots: key.

For example, take a folder known-good with two files in it:

# known-good/techknowlogick.yaml
- name: allow-techknowlogick-gitea
  action: ALLOW
  expression:
    all:
      - host == "git.techaro.lol"
      - verifyFCrDNS(remoteAddress, "techknowlogick.com$")
# known-good/xe.yaml
- name: allow-xe-gitea
  action: ALLOW
  expression:
    all:
      - host == "git.techaro.lol"
      - verifyFCrDNS(remoteAddress, "xeiaso.net$")

When importing known-good/*.yaml, Anubis reads them as if you wrote both lists of rules into one file:

- name: allow-techknowlogick-gitea
  action: ALLOW
  expression:
    all:
      - host == "git.techaro.lol"
      - verifyFCrDNS(remoteAddress, "techknowlogick.com$")

- name: allow-xe-gitea
  action: ALLOW
  expression:
    all:
      - host == "git.techaro.lol"
      - verifyFCrDNS(remoteAddress, "xeiaso.net$")

Closes: #1815

Checklist:

  • Added a description of the changes to the [Unreleased] section of docs/docs/CHANGELOG.md
  • Added test cases to the relevant parts of the codebase
  • Ran integration tests npm run test:integration (unsupported on Windows, please use WSL)
  • All of my commits have verified signatures

Xe added 7 commits August 5, 2026 19:02
…ogical file

This is kind of a hack and only really works because of the exact way
that the configuration snippets that Anubis uses works. This joins
multiple YAML list entries as if they are just one big file that happens
to have every YAML list entry in it.

Signed-off-by: Xe Iaso <[email protected]>
@Xe Xe self-assigned this Aug 6, 2026
Signed-off-by: Xe Iaso <[email protected]>
@Xe Xe changed the title Xe/import glob feat(config): allow wildcard matches in import statements Aug 6, 2026
@Xe
Xe merged commit c589fa9 into main Aug 6, 2026
28 checks passed
@Xe

Xe commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

Oh heck i hit the wrong button. Oops. I thought this was a different PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature request] import blank/nonexistent files

1 participant