# Connecting Housecarl to Jarl Housecarl uses [Jarl](https://gitea.adbraun.lol/adam/jarl), the BIND manager, for its DNS records. In this version that means one thing: the DNS-01 challenge for the web UI's certificate ([certificates.md](certificates.md)). Naming hosts in rules by their DNS names may use the same connection later. Housecarl talks to Jarl's REST API with an API token. Give it a **user of its own**, with **only the permission it needs**. ## 1. A user for Housecarl, in Jarl On the Jarl server, make a user without a password. It can't log in to Jarl's web UI, only use its tokens. Grant it the challenge record of Housecarl's own name, and nothing else: ```sh jarl user create housecarl --no-password --comment "Housecarl on fw01" \ --grant "records:write zones=adbraun.lol names=_acme-challenge.fw.adbraun.lol types=TXT" ``` Use your zone for `adbraun.lol`, and the name Housecarl's web UI is reached by for `fw.adbraun.lol` (`tls.acme.domain`). The grant lets the token add and remove TXT records at exactly `_acme-challenge.fw.adbraun.lol`: * nothing else in the zone (`names=`); * no other record type (`types=TXT`); * no other zone (`zones=`). It can see that the zone exists, which it needs to find it, but it can't read the zone's other records. Why not something wider: * **Jarl's `acme` role** (`records:write names=_acme-challenge.* types=TXT`) would let the token publish challenges for *any* name in *any* zone, and so obtain certificates for all of them. Housecarl needs only its own name. * **Your own account's token** would carry all your permissions, and Housecarl's certificate would stop renewing the day your account changes. A user per program keeps the two apart, and the audit log shows `housecarl/...` for what Housecarl did. If the challenge name is a CNAME into a zone kept for challenges, such as `_acme-challenge.fw.adbraun.lol CNAME fw.acme.adbraun.lol.`, grant the target instead: `zones=acme.adbraun.lol names=fw.acme.adbraun.lol`. ## 2. The token Make the token, and copy it to the Housecarl server into a file only the `housecarl` user can read: ```sh jarl token create fw01 --user housecarl -q > housecarl.token # on the Jarl server, or with the jarl CLI anywhere scp housecarl.token fw01: ssh fw01 'sudo install -m 0600 -o housecarl -g housecarl housecarl.token /etc/housecarl/jarl.token && rm housecarl.token' rm housecarl.token ``` A token file is better than putting the token in `housecarl.yaml`: the configuration file is readable by the `housecarl` group, and gets copied around more readily. You can give the token an expiry (`--expires 365d`). Rotate it in Jarl with `jarl token rotate ID --grace 1d`, then put the new secret in the file and restart housecarld within the grace period. Since the certificate is renewed every couple of months, nothing breaks while you do. ## 3. Housecarl's settings In `/etc/housecarl/housecarl.yaml`: ```yaml jarl: server: https://dns.adbraun.lol:8053 token_file: /etc/housecarl/jarl.token # ca_cert: /etc/housecarl/jarl-ca.pem # if Jarl's certificate isn't from a public CA ``` Then restart housecarld (`systemctl restart housecarl`). Housecarl needs to reach Jarl's API over the network: Jarl's `listen` must include an address Housecarl can reach, ideally over HTTPS. `hc cert check` ([certificates.md](certificates.md#checking)) tests the connection, the token's permission, and that the record reaches the internet.