Page MenuHomeDevCentral

Deploy Anubis for DevCentral
Needs ReviewPublic

Authored by ptdradmin on Feb 6 2026, 16:32.
Tags
None
Referenced Files
F24960763: D3908.id10480.diff
Sat, Mar 21, 12:38
F24960745: D3908.id10478.diff
Sat, Mar 21, 12:34
Unknown Object (File)
Sat, Mar 21, 01:53
Unknown Object (File)
Wed, Mar 18, 10:46
Unknown Object (File)
Wed, Mar 18, 08:18
Unknown Object (File)
Thu, Mar 12, 14:47
Unknown Object (File)
Thu, Mar 12, 14:46
Unknown Object (File)
Thu, Mar 12, 14:46
Subscribers
None
Tokens
"Y So Serious" token, awarded by dereckson.

Details

Reviewers
dereckson
Maniphest Tasks
T2193: Investigate Anubis
Summary

Integrate Anubis as a WAF/Reverse Proxy for DevCentral to secure traffic
and challenge AI scrapers.

Ref T2193.

Test Plan

Initial proof of concept verified on Dwellers.

Tests for production:

  • Anubis service starts and populates socket
  • Sockets permissions are correct
  • It's possible to connect to the socket and get challenge, then site
  • Bot policies correctly filter and challenge traffic via curl tests
  • nginx redirects correctly to Anubis instead of the site directly

Diff Detail

Repository
rOPS Nasqueron Operations
Lint
Lint Passed
Unit
No Test Coverage
Branch
anubis-prod
Build Status
Buildable 6502
Build 6786: arc lint + arc unit

Event Timeline

ptdradmin created this revision.
This comment was removed by ptdradmin.
dereckson requested changes to this revision.Feb 6 2026, 17:32
dereckson added inline comments.
pillar/paas/docker/docker-002/main.sls
312

It's under docker_images, so make sense only if we deploy Anubis as a Docker image.

(In that case, could be complicated to get the socket path)


If the goal is to give a new configuration for Anubis deployed outside Docker, this pillar is fine, but we need to put it at the same level than docker_images (so one less tab)

313

Format is:

docker_images:
  <service name>:
    <container name>:

The container name devcentral is already used, so I guess that would be something like anubis_devcentral

(but only if we use Docker)

roles/paas-docker/anubis.sls
1 ↗(On Diff #10126)

Should be put in a roles/paas-docker/anubis/ directory.

We can use:

  • one file, so this would be roles/paas-docker/anubis/init.sls
  • different files living in roles/paas-docker/anubis (to split software/services/config)

I see we're at +- 40 lines so one file is good

11 ↗(On Diff #10126)

That's the name of the pillar entry, so in that case, in pillar/paas/docker/docker-002/main.sls we should have something like:

anubis_instances:

devcentral:
  socket: /run/anubis/devcentral.sock
  policies_file: /usr/local/etc/anubis/devcentral.yaml
roles/paas-docker/anubis/files/env.j2
1 ↗(On Diff #10126)

Ansible convention is to use .j2 extension for Jinja2 templates.

In our Salt repository, I see two conventions:

  • to directly use the filename for config, text
  • to append .jinja for scripts, to bypass linter (e.g. mw.sh.jinja to avoid shellcheck to lint mw.sh and reports {{ is an errror)

Here it would be safe to use something like "instance.env" as filename.

7 ↗(On Diff #10126)

So we have a target key in the anubis_instances pillar.

At this stage I imagine something like:

anubis_instances:
  devcentral:
    socket: /run/anubis/devcentral.sock
    policies_file: /usr/local/etc/anubis/devcentral.yaml
    target: http://localhost:31080

Or:

anubis_instances:
  devcentral:
    socket: /run/anubis/devcentral.sock
    policies_file: /usr/local/etc/anubis/devcentral.yaml
    target:
      type: docker # we ignore it for now, but in the future if we've a no Docker we can add target logic
      service: phabricator
      container: devcentral

The target would then be http://localhost:{{ docker_containers[config[service]][config[container]]["app_port"] }}

And we automatically grab app_port from docker_containers pillar.

10 ↗(On Diff #10126)

Same logic than app_port grabbing, but host instead

15 ↗(On Diff #10126)

We need to provide logic to provision those two credentials into Vault.

Something like in fix_anubis_devcentral.sh, but with a write in Vault to run before provisioning this.

18 ↗(On Diff #10126)

Can we try with a UNIX socket? Like in /run/anubis/metrics/?

(That's perhaps that one we didn't succeed to query)

If we can do that, that will avoid to maintain a new ports table for the Anubis metrics.

roles/paas-docker/anubis/files/policies.yaml.j2
11 ↗(On Diff #10126)

No, no, no, we're especially heavily attacked on the files :/

14 ↗(On Diff #10126)

Same, they query A LOT the source code files in Diffusion.

I guess the intent of the LLM is to get "public access", but our software isn't intended to be downloaded from DevCentral directly so we're good there

17 ↗(On Diff #10126)

We're in two scenarii:

So that rule to allow all traffic isn't useful neither

20 ↗(On Diff #10126)

Hmmmm, those aren't really annoying, the ones that are annoying are the stealth ones, the ones that masquerade themselves as legit browser traffic

roles/paas-docker/nginx/files/vhosts/phabricator.conf
47
scripts/fix_anubis_devcentral.sh
2

Hmmm

Actually, that one conflicts with everything else.

For example lines 19 to 34 offers to do the job we already do with the env file above.

What we would need is perhaps to document or script the keys generation part, the two openssl rand -base64 32, and write it to Vault afterwards (vault kv write).

This revision now requires changes to proceed.Feb 6 2026, 17:32
dereckson edited the test plan for this revision. (Show Details)
dereckson awarded a token.
ptdradmin edited the test plan for this revision. (Show Details)

Summary: Refactored Anubis deployment according to review feedback.

  • Moved to roles/paas-docker/anubis/init.sls
  • Fixed pillar indentation and schema
  • Added dynamic port detection from docker_containers
  • Switched metrics to UNIX socket
  • Simplified provisioning script for Vault only
  • Cleaned up bot policies

.

  • Refactor Anubis deployment based on review feedback. Highlights: fixed pillar indentation, moved to init.sls, added dynamic port detection, and configured metrics socket.
  1. Updating D3908: Deploy Anubis for DevCentral #
  2. Enter a brief description of the changes included in this update.
  3. The first line is used as subject, next lines as comment. #
  4. If you intended to create a new revision, use:
  5. $ arc diff --create

:wq

^O
^X

roles/paas-docker/nginx/files/vhosts/phabricator.conf
47

Next step: declare also Orbeon in anubis_instances to test on Dwellers

  • Build: add Jenkinsfile for Operations CI
  • # Enter a commit message.
dereckson requested changes to this revision.Feb 11 2026, 18:44
dereckson removed a reviewer: ptdradmin.

Next step: validate the Dwellers part and ensure it matches our current configuration there.

Peering deployment between @ptdradmin and @dereckson for that activity.

This revision now requires changes to proceed.Feb 11 2026, 18:45

Fetch private key from Vault

dereckson requested changes to this revision.Fri, Mar 20, 20:12
dereckson added inline comments.
roles/paas-docker/anubis/files/instance.env
2

We noticed a lot of hallucinations in this template.

For reference, here what we used for deck.nasqueron.org -> Orbeon in Decemmber:

/etc/anubis/site.env
TARGET=http://127.0.0.1:16080
POLICY_FNAME=/etc/anubis/botPolicies.yaml
ED25519_PRIVATE_KEY_HEX_FILE=/etc/anubis/private.key

ANUBIS_TARGET_URL seems to match expected value for TARGET

ANUBIS_METRICS_ADDR seems to match expected value for METRICS_BIND

roles/paas-docker/anubis/files/policies.yaml
2

Should be re conciliated with content in P390 currently deployed on Dwellers.

roles/paas-docker/anubis/init.sls
22

Outside the for loop, as we can try a unique policies file to avoid repeat the same information

scripts/fix_anubis_devcentral.sh
2

Can be removed, we noticed Anubis doesn't document format for the key or a way to provide one, so our best shot is to let Anubis generate one, then store it manually in Vault.

Automation can be investigated later, probably by filing a bug request on Anubis tracker to get an option to generate a key (or doc to do so ourselves).

This revision now requires changes to proceed.Fri, Mar 20, 20:12
roles/paas-docker/anubis/files/instance.env
2

The two examples we've on Dwellers:

name=Orbeon (service "anubis", our first test)
TARGET=http://127.0.0.1:16080
POLICY_FNAME=/etc/anubis/botPolicies.yaml
ED25519_PRIVATE_KEY_HEX_FILE=/etc/anubis/private.key
Bar (serviceanubis-bar)
TARGET=https://windriver.nasqueron.org
POLICY_FNAME=/etc/anubis/botPolicies.yaml
BIND=127.0.0.1:8924
METRICS_BIND=172.27.27.4:9091
ED25519_PRIVATE_KEY_HEX_FILE=/etc/anubis/private.key

Fix Anubis deployment: unify env vars, reconcile policies with P390, and align Nginx config

roles/paas-docker/anubis/files/instance.env
3

Default value is harmful here: we can't have two services listening to the same TCP port.

So better to fail loudly with an error bind or metrics_bind haven't been defined in config.

roles/paas-docker/anubis/files/policies.yaml
2

Add the usual header here.

Anything in files directory should start by that template header: https://devcentral.nasqueron.org/source/snippets/browse/main/salt/file.conf

(lines 1-14 are always used, lines 16-18 are only useful when we want to divide a long configuration in sections).

There are several goals we want to achieve:

  • if we want to edit the final file on a server, we are reminded it's auto-generated by Salt, so that we need to modify it here, not manually
  • source file gives us the path where to edit, here it will say roles/paas-docker/anubis/files/policies.yaml for example
roles/paas-docker/nginx/files/vhosts/phabricator.conf
47

Same here, to use a default port will fail at the second missing service.

To provide a default value would work only in cases where there is only one.

(Also, ports 1080 8000 and 8080 are for examples non-80 ports for TCP servers, totally fine inside an isolated container, not directly on the machine host)

@ptdradmin The provisioning of /etc/anubis/private.key we added here has disappeared: https://devcentral.nasqueron.org/D3908?vs=10478&id=10480#toc

That's the code we added in live Friday evening together to fetch the private key from Vault.

to add in init.sls
/etc/anubis/private.key:
  file.managed:
    - source: salt://roles/paas-docker/anubis/files/private.key
    - template: jinja
    - context:
        key: {{ salt["credentials.get_password"]("anubis/" + grains["id"]) }}

We also have the template:

roles/paas-docker/anubis/files/private.key
#   -------------------------------------------------------------
#   Anubis private key
#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#   Project:        Nasqueron
#   License:        Trivial work, not eligible to copyright
#   Source file:    roles/paas-docker/anubis/files/private.key
#   -------------------------------------------------------------
#
#   <auto-generated>
#       This file is managed by our rOPS SaltStack repository.
#
#       Changes to this file may cause incorrect behavior
#       and will be lost if the state is redeployed.
#   </auto-generated>

{{ key }}

YAML/Jinaj Style: remove defaults to fail loudly on missing ports/bind as suggested by dereckson, plus add headers

Apply dereckson feedback: add headers, remove defaults for bind/port to fail loudly if undefined

Restore private.key provisioning from Vault as requested by dereckson