• v0.3.0-rc.1 831687ddc6

    Steward v0.3.0-rc.1
    All checks were successful
    release / release (push) Successful in 1m57s
    Pre-release

    adam released this 2026-10-25 18:37:33 +00:00 | -19 commits to main since this release

    Added

    • Captive portals (docs/portal.md). A subnet's
      clients can be kept off the internet until they accept its terms on
      Steward's portal page, a page in Steward's colors (light and dark)
      with the subnet's own title and terms. Steward lets a signed-in client
      through by adding its address to a dynamic set in Housecarl, the
      firewall manager, with a timeout that ends with its session or its
      lease, whichever comes first. A session belongs to the client, not its
      address: the set follows it to a new address, and a client that comes
      back within its session time gets straight through. Steward checks
      the sets every minute and after every lease change, and takes out the
      other addresses of its portal subnets.
      • The page is served on its own addresses (portal.listen in
        steward.yaml, on the guest networks), apart from the web UI; any
        other site's web request the firewall sends there is redirected to
        it, so phones and laptops open it by themselves.
      • With an https:// portal.url, Steward sends it in DHCP option 114
        (RFC 8910), and answers the Captive Portal API (RFC 8908).
      • Per subnet: on or off, the Housecarl set, the session time (24
        hours by default), the title and the terms. steward portal set,
        the subnet's new Portal tab, portal in the subnet API.
      • Who is signed in, with Extend and End, and the clients that
        haven't signed in, with Let in for a TV or console that can't
        open the page: the Portal tab, steward portal sessions, let-in,
        extend, end, status; /portal and /portal/sessions in the
        API (the leases grant). SIGNED IN and SIGNED OUT in Activity.
      • housecarl: in steward.yaml: Housecarl's URL or local socket, and a
        token that needs only sets:write for the portal's sets.
    • A roadmap in docs/design.md: other ways
      through a portal (passwords, vouchers, accounts) and IPv6 on portal
      networks.

    Upgrading from 0.2

    • The database gets a new version (8), applied when stewardd starts; a
      0.2 stewardd can't open it afterwards, so take a backup first (sudo stewardd backup). No subnet has a portal until you turn one on.
    • The portal needs Housecarl with its renewal fix (adding an entry that
      is in a dynamic set already must give it the new timeout).
    Downloads
  • v0.2.0 ed0a17e25f

    Steward v0.2.0
    All checks were successful
    release / release (push) Successful in 3m44s
    Stable

    adam released this 2026-10-25 17:41:17 +00:00 | -17 commits to main since this release

    Added

    • Reserve another address from a lease. The Reserve dialog on the
      Leases page fills in the lease's address but lets you change it, to
      any address of the same subnet (steward lease reserve IP --ip ADDR,
      "ip" in the API). The client moves there when it next renews.
    • Failed logins in the journal. A failed login and a refused API
      token are logged as well as audited, with the address first
      (msg="login failed" ip=… user=…, msg="token refused" ip=…), for
      Guard's steward preset or a fail2ban filter to ban such addresses
      (docs/operations.md).
    • Allow and deny lists per subnet (docs/subnets.md): a deny-list
      subnet (the default) answers everyone not denied; an allow-list subnet
      only clients allowed or with a reservation. Entries are MAC addresses,
      prefixes (aa:bb:cc:*) or client IDs. A refused client gets no answer
      (DENIED in the activity log, with an Allow button), or a NAK when it
      next renews. steward access, the subnet's Access tab, access,
      allow and deny in the API.
    • Every option of a DHCP message, in words: ▸ on an Activity row,
      steward activity show N or --details, and GET /events/{id}. What
      the client asked for (its parameter request list, by name), its client
      ID and host name, and what Steward sent back.

    Upgrading from 0.1

    • The database gets a new version (7), applied when stewardd starts; a
      0.1 stewardd can't open it afterwards, so take a backup first (sudo stewardd backup). Every subnet stays a deny-list subnet with empty
      lists, so nothing changes until you add entries.
    Downloads
  • v0.2.0-rc.3 f6c31858a3

    Steward v0.2.0-rc.3 Pre-release

    adam released this 2026-10-25 00:29:07 +01:00 | -16 commits to main since this release

    Added

    • Reserve another address from a lease. The Reserve dialog on the
      Leases page fills in the lease's address but lets you change it, to
      any address of the same subnet (steward lease reserve IP --ip ADDR,
      "ip" in the API). The client moves there when it next renews.

    • Failed logins in the journal. A failed login and a refused API
      token are logged as well as audited, with the address first
      (msg="login failed" ip=… user=…, msg="token refused" ip=…), for
      Guard's steward preset or a fail2ban filter to ban such addresses
      (docs/operations.md).

    • Allow and deny lists per subnet (docs/subnets.md): a deny-list
      subnet (the default) answers everyone not denied; an allow-list subnet
      only clients allowed or with a reservation. Entries are MAC addresses,
      prefixes (aa:bb:cc:*) or client IDs. A refused client gets no answer
      (DENIED in the activity log, with an Allow button), or a NAK when it
      next renews. steward access, the subnet's Access tab, access,
      allow and deny in the API.

    • Every option of a DHCP message, in words: ▸ on an Activity row,
      steward activity show N or --details, and GET /events/{id}. What
      the client asked for (its parameter request list, by name), its client
      ID and host name, and what Steward sent back.

    Upgrading from 0.1

    • The database gets a new version (7), applied when stewardd starts; a
      0.1 stewardd can't open it afterwards, so take a backup first (sudo stewardd backup). Every subnet stays a deny-list subnet with empty
      lists, so nothing changes until you add entries.
    Downloads
  • v0.2.0-rc.2 c7a64773a7

    Steward v0.2.0-rc.2 Pre-release

    adam released this 2026-10-22 18:58:57 +01:00 | -14 commits to main since this release

    Added

    • Failed logins in the journal. A failed login and a refused API
      token are logged as well as audited, with the address first
      (msg="login failed" ip=… user=…, msg="token refused" ip=…), for
      Guard's steward preset or a fail2ban filter to ban such addresses
      (docs/operations.md).

    • Allow and deny lists per subnet (docs/subnets.md): a deny-list
      subnet (the default) answers everyone not denied; an allow-list subnet
      only clients allowed or with a reservation. Entries are MAC addresses,
      prefixes (aa:bb:cc:*) or client IDs. A refused client gets no answer
      (DENIED in the activity log, with an Allow button), or a NAK when it
      next renews. steward access, the subnet's Access tab, access,
      allow and deny in the API.

    • Every option of a DHCP message, in words: ▸ on an Activity row,
      steward activity show N or --details, and GET /events/{id}. What
      the client asked for (its parameter request list, by name), its client
      ID and host name, and what Steward sent back.

    Upgrading from 0.1

    • The database gets a new version (7), applied when stewardd starts; a
      0.1 stewardd can't open it afterwards, so take a backup first (sudo stewardd backup). Every subnet stays a deny-list subnet with empty
      lists, so nothing changes until you add entries.
    Downloads
  • v0.2.0-rc.1 c995ae819d

    Steward v0.2.0-rc.1 Pre-release

    adam released this 2026-10-18 20:27:51 +01:00 | -12 commits to main since this release

    Added

    • Allow and deny lists per subnet (docs/subnets.md): a deny-list
      subnet (the default) answers everyone not denied; an allow-list subnet
      only clients allowed or with a reservation. Entries are MAC addresses,
      prefixes (aa:bb:cc:*) or client IDs. A refused client gets no answer
      (DENIED in the activity log, with an Allow button), or a NAK when it
      next renews. steward access, the subnet's Access tab, access,
      allow and deny in the API.
    • Every option of a DHCP message, in words: ▸ on an Activity row,
      steward activity show N or --details, and GET /events/{id}. What
      the client asked for (its parameter request list, by name), its client
      ID and host name, and what Steward sent back.

    Upgrading from 0.1

    • The database gets a new version (7), applied when stewardd starts; a
      0.1 stewardd can't open it afterwards, so take a backup first (sudo stewardd backup). Every subnet stays a deny-list subnet with empty
      lists, so nothing changes until you add entries.
    Downloads
  • v0.1.0 b3c8329ae8

    adam released this 2026-10-18 20:26:30 +01:00 | -10 commits to main since this release

    The first version of Steward, a DHCPv4 server with a web UI, a REST API
    and a CLI, built the way Jarl is.

    Added

    • DHCPv4 server (stewardd serve):
      • Answers DISCOVER, REQUEST (selecting, init-reboot, renewing,
        rebinding), DECLINE, RELEASE and INFORM, as RFC 2131 describes.
      • Serves each subnet on its own network interface, with a socket per
        interface bound to it, so a VLAN's clients only get that VLAN's
        addresses.
      • Several subnets on one interface are served together, as a shared
        network.
      • Opens an interface's socket when the interface appears, such as a
        VLAN that comes up later, and closes it when its last subnet goes.
    • Address choice, in this order:
      1. the client's reservation;
      2. the address it had before;
      3. the address it asks for;
      4. a pool address never handed out, else the one free the longest.
    • Reserved addresses are never handed out to anyone else, even inside
      a pool.
    • Leases are kept in SQLite and saved before the ACK is sent. Ended
      ones stay 30 days, so returning clients get their address again.
    • Conflict checks:
      • An address is pinged before it is offered, and one that answers is
        held back.
      • An address a client declines is held back for a day.
      • Both use the decline_hold setting.
    • Authority: a request for an address that doesn't belong on the
      interface gets a NAK, so the client starts over at once. This can be
      turned off when another server shares a network.
    • Options:
      • 27 by name (routers, domain-name-servers, domain-search,
        ntp-servers, classless-static-route, …), and any other by number
        with a type.
      • Set globally, per subnet and per reservation, the most specific
        winning.
      • When a client sends a parameter request list, it gets what it asked
        for, in that order.
    • Configuration changes:
      • Validated as a whole, with stable problem codes (docs/validation.md).
      • Saved with a history entry, and can be undone after a check that
        nothing changed since.
      • ?dry_run=1 (or steward -n) previews a change.
    • REST API (docs/api.md):
      • users, sessions with CSRF protection, and API tokens limited by role
        or grant (config, leases, audit);
      • an audit log;
      • a local unix socket where root needs no token.
    • CLI steward (docs/cli.md):
      • commands: status, subnet, reservation, lease, activity, settings,
        option, interface, history (with undo), import kea, user, token,
        password, audit, config;
      • output as tables, JSON, YAML or IDs.
    • Web UI:
      • a dashboard of interfaces, pool use, problems and recent messages;
      • subnets with their leases, reservations and settings;
      • leases, with reserve and delete;
      • reservations;
      • live DHCP activity;
      • settings and global options;
      • history with undo, the audit log, users and tokens.
      • A new subnet suggests its network and a pool from the interface's
        address.
    • Kea import: steward import kea (POST /import/kea) reads a
      kea-dhcp4.conf and its lease files (docs/kea.md):
      • global, shared-network and subnet options, pools, lease times and
        reservations;
      • each subnet's interface: Kea's, else the host's interface with an
        address in the subnet, else --interface PREFIX=IFACE.
      • It lists what it doesn't support instead of dropping it silently.
      • Importing again keeps subnets' and reservations' IDs and Steward's
        subnet names.
    • stewardd commands: init (asks for the administrator's name),
      user add|password|token, check, backup (with pruning), restore,
      config --example.
    • The web UI's certificate from Let's Encrypt, through Jarl
      (docs/certificates.md, docs/jarl.md):
      • tls.acme in steward.yaml names the certificate, and jarl: the
        Jarl server and a token that may only write the challenge record.
      • Steward gets the certificate with the DNS-01 challenge, writing the
        record through Jarl's API into every view that has the zone.
      • It renews with a third of the lifetime left, and swaps the new
        certificate in without a restart.
      • A check runs before every order, and on demand: Jarl, the zone, the
        token's permission, a test record, the zone's public name servers and
        public resolvers, clean-up. Each step says what to fix.
      • It starts with Let's Encrypt's staging service by default.
      • steward cert, cert check, cert renew; Server → Certificate in the
        web UI; GET /certificate, POST /certificate/check|renew.
      • Dashboard problems: certificate_failed, certificate_expiring,
        certificate_staging.
    • HTTPS and plain HTTP on one port: with a certificate, plain HTTP is
      redirected to HTTPS, except from the server itself (also for
      tls.cert_file).
    • Disabled reservations (steward reservation disable|enable, Disable
      in the web UI): kept but ignored, so the client gets a pool address like
      any other. Subnets get Disable/Enable buttons in the web UI too.
    • Hidden interfaces: interfaces.exclude in steward.yaml (names or
      shell patterns such as docker*) leaves interfaces out of the web UI's
      interface picker, steward interface list and GET /interfaces.
    • Last seen: with the ping check on, active leases' addresses are
      pinged every minute, and a client that answers gets a last-seen time
      (Leases page, reservations' online badge, steward lease list|show,
      steward reservation list|show, last_seen in the API). A client that
      blocks pings stays online for as long as its lease lasts, without one.
    • The Reservations page refreshes itself every 15 seconds, so online
      and last seen stay current.
    • Activity by subnet: steward activity --subnet, a subnet filter on
      the Activity page, GET /events?subnet= (ID, name or prefix).
    • Address order (docs/subnets.md): which never-used pool address a
      new client gets, sequential (the lowest, as before), reverse or
      random, in the settings, a subnet (--address-order) or a single
      pool (--pool 10.0.10.200-10.0.10.250:random). A subnet's pools are
      used in the order listed, or one at random (--pool-order random),
      weighted by its never-used addresses. Pools now keep the order they are
      given in. Kea's allocator: random is imported.
    • A reservation's own lease time (--lease-time 7d, the reservation
      dialog), over the subnet's.
    • Reservations by MAC address and client ID together: either one gets
      the client its address (a dual-boot machine sends two client IDs from
      one MAC). The Leases page shows the client ID a client sent, and
      reserving a lease uses both (steward lease reserve --by for one).
    • Token rotation (steward token rotate, POST /tokens/{id}/rotate,
      Rotate in the web UI): a new secret for a token, with an optional grace
      period for the old one, as in Jarl.
    • Packaging:
      • a sandboxed systemd unit (steward.service, also stewardd.service)
        whose only privilege is CAP_NET_BIND_SERVICE;
      • a daily backup timer, and sysusers and tmpfiles files;
      • Debian packages steward and steward-cli, and a Gitea release
        workflow.
    • The Steward logo: a key whose bow is a crown with Jarl's network
      nodes, in Jarl's blue and white, with a STEWARD wordmark in Jarl's
      letters.
    Downloads
  • v0.1.0-rc.1 abb2ee0fd7

    Steward v0.1.0-rc.1 Pre-release

    adam released this 2026-10-18 18:15:02 +01:00 | -8 commits to main since this release

    The first version of Steward, a DHCPv4 server with a web UI, a REST API
    and a CLI, built the way Jarl is.

    Added

    • DHCPv4 server (stewardd serve):
      • Answers DISCOVER, REQUEST (selecting, init-reboot, renewing,
        rebinding), DECLINE, RELEASE and INFORM, as RFC 2131 describes.
      • Serves each subnet on its own network interface, with a socket per
        interface bound to it, so a VLAN's clients only get that VLAN's
        addresses.
      • Several subnets on one interface are served together, as a shared
        network.
      • Opens an interface's socket when the interface appears, such as a
        VLAN that comes up later, and closes it when its last subnet goes.
    • Address choice, in this order:
      1. the client's reservation;
      2. the address it had before;
      3. the address it asks for;
      4. a pool address never handed out, else the one free the longest.
    • Reserved addresses are never handed out to anyone else, even inside
      a pool.
    • Leases are kept in SQLite and saved before the ACK is sent. Ended
      ones stay 30 days, so returning clients get their address again.
    • Conflict checks:
      • An address is pinged before it is offered, and one that answers is
        held back.
      • An address a client declines is held back for a day.
      • Both use the decline_hold setting.
    • Authority: a request for an address that doesn't belong on the
      interface gets a NAK, so the client starts over at once. This can be
      turned off when another server shares a network.
    • Options:
      • 27 by name (routers, domain-name-servers, domain-search,
        ntp-servers, classless-static-route, …), and any other by number
        with a type.
      • Set globally, per subnet and per reservation, the most specific
        winning.
      • When a client sends a parameter request list, it gets what it asked
        for, in that order.
    • Configuration changes:
      • Validated as a whole, with stable problem codes (docs/validation.md).
      • Saved with a history entry, and can be undone after a check that
        nothing changed since.
      • ?dry_run=1 (or steward -n) previews a change.
    • REST API (docs/api.md):
      • users, sessions with CSRF protection, and API tokens limited by role
        or grant (config, leases, audit);
      • an audit log;
      • a local unix socket where root needs no token.
    • CLI steward (docs/cli.md):
      • commands: status, subnet, reservation, lease, activity, settings,
        option, interface, history (with undo), import kea, user, token,
        password, audit, config;
      • output as tables, JSON, YAML or IDs.
    • Web UI:
      • a dashboard of interfaces, pool use, problems and recent messages;
      • subnets with their leases, reservations and settings;
      • leases, with reserve and delete;
      • reservations;
      • live DHCP activity;
      • settings and global options;
      • history with undo, the audit log, users and tokens.
      • A new subnet suggests its network and a pool from the interface's
        address.
    • Kea import: steward import kea (POST /import/kea) reads a
      kea-dhcp4.conf and its lease files (docs/kea.md):
      • global, shared-network and subnet options, pools, lease times and
        reservations;
      • each subnet's interface: Kea's, else the host's interface with an
        address in the subnet, else --interface PREFIX=IFACE.
      • It lists what it doesn't support instead of dropping it silently.
      • Importing again keeps subnets' and reservations' IDs and Steward's
        subnet names.
    • stewardd commands: init (asks for the administrator's name),
      user add|password|token, check, backup (with pruning), restore,
      config --example.
    • The web UI's certificate from Let's Encrypt, through Jarl
      (docs/certificates.md, docs/jarl.md):
      • tls.acme in steward.yaml names the certificate, and jarl: the
        Jarl server and a token that may only write the challenge record.
      • Steward gets the certificate with the DNS-01 challenge, writing the
        record through Jarl's API into every view that has the zone.
      • It renews with a third of the lifetime left, and swaps the new
        certificate in without a restart.
      • A check runs before every order, and on demand: Jarl, the zone, the
        token's permission, a test record, the zone's public name servers and
        public resolvers, clean-up. Each step says what to fix.
      • It starts with Let's Encrypt's staging service by default.
      • steward cert, cert check, cert renew; Server → Certificate in the
        web UI; GET /certificate, POST /certificate/check|renew.
      • Dashboard problems: certificate_failed, certificate_expiring,
        certificate_staging.
    • HTTPS and plain HTTP on one port: with a certificate, plain HTTP is
      redirected to HTTPS, except from the server itself (also for
      tls.cert_file).
    • Disabled reservations (steward reservation disable|enable, Disable
      in the web UI): kept but ignored, so the client gets a pool address like
      any other. Subnets get Disable/Enable buttons in the web UI too.
    • Hidden interfaces: interfaces.exclude in steward.yaml (names or
      shell patterns such as docker*) leaves interfaces out of the web UI's
      interface picker, steward interface list and GET /interfaces.
    • Last seen: with the ping check on, active leases' addresses are
      pinged every minute, and a client that answers gets a last-seen time
      (Leases page, reservations' online badge, steward lease list|show,
      steward reservation list|show, last_seen in the API). A client that
      blocks pings stays online for as long as its lease lasts, without one.
    • The Reservations page refreshes itself every 15 seconds, so online
      and last seen stay current.
    • Activity by subnet: steward activity --subnet, a subnet filter on
      the Activity page, GET /events?subnet= (ID, name or prefix).
    • Address order (docs/subnets.md): which never-used pool address a
      new client gets, sequential (the lowest, as before), reverse or
      random, in the settings, a subnet (--address-order) or a single
      pool (--pool 10.0.10.200-10.0.10.250:random). A subnet's pools are
      used in the order listed, or one at random (--pool-order random),
      weighted by its never-used addresses. Pools now keep the order they are
      given in. Kea's allocator: random is imported.
    • Token rotation (steward token rotate, POST /tokens/{id}/rotate,
      Rotate in the web UI): a new secret for a token, with an optional grace
      period for the old one, as in Jarl.
    • Packaging:
      • a sandboxed systemd unit (steward.service, also stewardd.service)
        whose only privilege is CAP_NET_BIND_SERVICE;
      • a daily backup timer, and sysusers and tmpfiles files;
      • Debian packages steward and steward-cli, and a Gitea release
        workflow.
    • The Steward logo: a key whose bow is a crown with Jarl's network
      nodes, in Jarl's blue and white, with a STEWARD wordmark in Jarl's
      letters.
    Downloads
  • v0.1.0-dev 6ad1bb9a0d

    Steward v0.1.0-dev Pre-release

    adam released this 2026-10-14 16:02:15 +01:00 | -4 commits to main since this release

    The first version of Steward, a DHCPv4 server with a web UI, a REST API
    and a CLI, built the way Jarl is.

    Added

    • DHCPv4 server (stewardd serve):
      • Answers DISCOVER, REQUEST (selecting, init-reboot, renewing,
        rebinding), DECLINE, RELEASE and INFORM, as RFC 2131 describes.
      • Serves each subnet on its own network interface, with a socket per
        interface bound to it, so a VLAN's clients only get that VLAN's
        addresses.
      • Several subnets on one interface are served together, as a shared
        network.
      • Opens an interface's socket when the interface appears, such as a
        VLAN that comes up later, and closes it when its last subnet goes.
    • Address choice, in this order:
      1. the client's reservation;
      2. the address it had before;
      3. the address it asks for;
      4. a pool address never handed out, else the one free the longest.
    • Reserved addresses are never handed out to anyone else, even inside
      a pool.
    • Leases are kept in SQLite and saved before the ACK is sent. Ended
      ones stay 30 days, so returning clients get their address again.
    • Conflict checks:
      • An address is pinged before it is offered, and one that answers is
        held back.
      • An address a client declines is held back for a day.
      • Both use the decline_hold setting.
    • Authority: a request for an address that doesn't belong on the
      interface gets a NAK, so the client starts over at once. This can be
      turned off when another server shares a network.
    • Options:
      • 27 by name (routers, domain-name-servers, domain-search,
        ntp-servers, classless-static-route, …), and any other by number
        with a type.
      • Set globally, per subnet and per reservation, the most specific
        winning.
      • When a client sends a parameter request list, it gets what it asked
        for, in that order.
    • Configuration changes:
      • Validated as a whole, with stable problem codes (docs/validation.md).
      • Saved with a history entry, and can be undone after a check that
        nothing changed since.
      • ?dry_run=1 (or steward -n) previews a change.
    • REST API (docs/api.md):
      • users, sessions with CSRF protection, and API tokens limited by role
        or grant (config, leases, audit);
      • an audit log;
      • a local unix socket where root needs no token.
    • CLI steward (docs/cli.md):
      • commands: status, subnet, reservation, lease, activity, settings,
        option, interface, history (with undo), import kea, user, token,
        password, audit, config;
      • output as tables, JSON, YAML or IDs.
    • Web UI:
      • a dashboard of interfaces, pool use, problems and recent messages;
      • subnets with their leases, reservations and settings;
      • leases, with reserve and delete;
      • reservations;
      • live DHCP activity;
      • settings and global options;
      • history with undo, the audit log, users and tokens.
      • A new subnet suggests its network and a pool from the interface's
        address.
    • Kea import: steward import kea (POST /import/kea) reads a
      kea-dhcp4.conf and its lease files (docs/kea.md):
      • global, shared-network and subnet options, pools, lease times and
        reservations;
      • each subnet's interface: Kea's, else the host's interface with an
        address in the subnet, else --interface PREFIX=IFACE.
      • It lists what it doesn't support instead of dropping it silently.
      • Importing again keeps subnets' and reservations' IDs and Steward's
        subnet names.
    • stewardd commands: init (asks for the administrator's name),
      user add|password|token, check, backup (with pruning), restore,
      config --example.
    • The web UI's certificate from Let's Encrypt, through Jarl
      (docs/certificates.md, docs/jarl.md):
      • tls.acme in steward.yaml names the certificate, and jarl: the
        Jarl server and a token that may only write the challenge record.
      • Steward gets the certificate with the DNS-01 challenge, writing the
        record through Jarl's API into every view that has the zone.
      • It renews with a third of the lifetime left, and swaps the new
        certificate in without a restart.
      • A check runs before every order, and on demand: Jarl, the zone, the
        token's permission, a test record, the zone's public name servers and
        public resolvers, clean-up. Each step says what to fix.
      • It starts with Let's Encrypt's staging service by default.
      • steward cert, cert check, cert renew; Server → Certificate in the
        web UI; GET /certificate, POST /certificate/check|renew.
      • Dashboard problems: certificate_failed, certificate_expiring,
        certificate_staging.
    • HTTPS and plain HTTP on one port: with a certificate, plain HTTP is
      redirected to HTTPS, except from the server itself (also for
      tls.cert_file).
    • Disabled reservations (steward reservation disable|enable, Disable
      in the web UI): kept but ignored, so the client gets a pool address like
      any other. Subnets get Disable/Enable buttons in the web UI too.
    • Token rotation (steward token rotate, POST /tokens/{id}/rotate,
      Rotate in the web UI): a new secret for a token, with an optional grace
      period for the old one, as in Jarl.
    • Packaging:
      • a sandboxed systemd unit (steward.service, also stewardd.service)
        whose only privilege is CAP_NET_BIND_SERVICE;
      • a daily backup timer, and sysusers and tmpfiles files;
      • Debian packages steward and steward-cli, and a Gitea release
        workflow.
    • The Steward logo: a key whose bow is a crown with Jarl's network
      nodes, in Jarl's blue and white, with a STEWARD wordmark in Jarl's
      letters.
    Downloads