# Connecting Steward to Jarl Steward 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)). Registering clients' names is planned to use the same connection. Steward 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 Steward, 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 Steward's own name, and nothing else: ```sh jarl user create steward --no-password --comment "Steward on dhcp01" \ --grant "records:write zones=adbraun.lol names=_acme-challenge.dhcp.adbraun.lol types=TXT" ``` Use your zone for `adbraun.lol`, and the name Steward's web UI is reached by for `dhcp.adbraun.lol` (`tls.acme.domain`). The grant lets the token add and remove TXT records at exactly `_acme-challenge.dhcp.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. Steward needs only its own name. * **Your own account's token** would carry all your permissions, and Steward's certificate would stop renewing the day your account changes. A user per program keeps the two apart, and the audit log shows `steward/...` for what Steward did. If the challenge name is a CNAME into a zone kept for challenges, such as `_acme-challenge.dhcp.adbraun.lol CNAME dhcp.acme.adbraun.lol.`, grant the target instead: `zones=acme.adbraun.lol names=dhcp.acme.adbraun.lol`. ## 2. The token Make the token, and copy it to the Steward server into a file only the `steward` user can read: ```sh jarl token create dhcp01 --user steward -q > steward.token # on the Jarl server, or with the jarl CLI anywhere scp steward.token dhcp01: ssh dhcp01 'sudo install -m 0600 -o steward -g steward steward.token /etc/steward/jarl.token && rm steward.token' rm steward.token ``` A token file is better than putting the token in `steward.yaml`: the configuration file is readable by the `steward` 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 stewardd within the grace period. Since the certificate is renewed every couple of months, nothing breaks while you do. ## 3. Steward's settings In `/etc/steward/steward.yaml`: ```yaml jarl: server: https://dns.adbraun.lol:8053 token_file: /etc/steward/jarl.token # ca_cert: /etc/steward/jarl-ca.pem # if Jarl's certificate isn't from a public CA ``` Then restart stewardd (`systemctl restart steward`). Steward needs to reach Jarl's API over the network: Jarl's `listen` must include an address Steward can reach, ideally over HTTPS. `steward cert check` ([certificates.md](certificates.md#checking)) tests the connection, the token's permission, and that the record reaches the internet.