Admin CLI (lindir-admin)
Thin Bearer-API client for day-to-day IdM and fleet tasks without hand-written curl.
For the browser UI (Vue 3 at /admin/), see Admin Web UI.
Build
COMPILER="${COMPILER:-ldc2}" # ldc2 | dmd | gdc
cd cli && dub build --compiler="$COMPILER"
# → cli/lindir-admin
Auth
export LINDIR_URL=https://id.example.com
export LINDIR_TOKEN=… # break-glass bootstrap or API token (ldt_…)
# or: --url … --token …
# lab TLS: --insecure custom CA: --ca-file /path/ca.pem
Day-to-day Admin UI login uses a directory username/password (or passkey) plus an Admin ACL binding (admin_ro / admin_rw). Bearer tokens remain emergency break-glass and always have full write.
--host-admin / --admin on user create adds the user to group lindir-host-admins (seeded sudo ALL on host *). HBAC still controls which hosts see them. This is not Lindir console access (users.is_admin is deprecated).
Command reference
health
ops attention
user list
user create --username NAME [--password P] [--email E] [--display-name N] [--host-admin|--admin]
(# --host-admin → lindir-host-admins group; not console ACL)
access admin-acl list
access admin-acl grant (--user ID | --group ID) --role admin_ro|admin_rw
access admin-acl revoke (--user ID | --group ID)
user password --user-id ID --password P
user enable|disable --user-id ID
user unlock --user-id ID
admin-login-throttle clear (--ip IP | --all)
group list
group create --name NAME [--description D]
group add-member --group-id ID --user-id ID
group remove-member --group-id ID --user-id ID
group members --group-id ID
host list
host enroll --hostname NAME [--os-family F] [--os-pretty P] [--tag TAG]… [--skip-vpn]
enroll-token list
enroll-token create [--name N] [--ttl-hours H] [--max-uses N] [--hostname-hint H]
enroll-token revoke --id ID
account-policy get
account-policy set [--min-password-length N] [--password-max-age-days N]
[--lockout-threshold N] [--lockout-minutes N] [--require-change-on-create]
token list
token create --name NAME [--role admin]
oidc client list
oidc client create --name NAME --redirect-uri URI [--public]
passkey list --user-id ID
passkey revoke --id CREDENTIAL_ROW_ID
policy hbac list
policy hbac check --host-id ID [--group-id ID]…
vpn sync-acls
fleet labels [list]
fleet labels create --name NAME [--description D]
fleet labels assign --host-id ID --label-id ID
fleet labels unassign --host-id ID --label-id ID
fleet labels hosts --label-id ID
fleet inventory
fleet upgrades [--host-id ID]
fleet apt-sources [--host-id ID]
fleet crontabs [--host-id ID]
fleet cron list|pending|cancel --id JOB
fleet cron add|remove|enable|disable --host-id|--label-id
[--scope user|system] [--username U] [--cron-d NAME] [--entry-id ID]
fleet timers [--host-id ID]
fleet timer list|pending|cancel --id JOB
fleet timer add|remove|enable|disable --host-id|--label-id …
fleet oneshots [--host-id ID]
fleet oneshot list|pending|cancel --id JOB
fleet oneshot add|remove|enable|disable --host-id|--label-id …
fleet services [--host-id ID]
fleet service list|pending|cancel --id JOB
fleet service add|remove|enable|disable|restart --host-id|--label-id …
fleet systemd-units [--host-id ID]
fleet systemd list|pending|cancel --id JOB
fleet systemd start|stop|restart|reload|enable|disable|mask|unmask …
fleet queries
fleet scripts
fleet runs
fleet sync-hbac
fleet packages list
fleet packages pending
fleet packages cancel --id JOB_ID
fleet packages install|remove|upgrade|refresh|reboot|update-client
|add-ppa|remove-ppa|enable-ppa|disable-ppa
(--host-id ID | --label-id ID) [--package NAME]…
fleet energy list
fleet energy create --name NAME [--idle-action suspend] [--idle-delay-sec N]
[--screen-blank-sec N] [--screen-off-sec N] [--lid-close suspend]
[--lid-close-docked ignore]
fleet energy assign --policy-id ID (--host-id ID | --label-id ID)
fleet energy unassign --policy-id ID (--host-id ID | --label-id ID)
fleet energy delete --policy-id ID
fleet certs list|status|discover-status
fleet certs create --name NAME --domain FQDN… [--dns-provider P --dns-credential S | --webroot PATH]
--cert-path PATH --key-path PATH [--reload-hook CMD] [--acme-directory URL]
fleet certs assign|unassign --policy-id ID (--host-id ID | --label-id ID)
fleet certs delete --policy-id ID
fleet certs discover --host-id ID [--path DIR]…
fleet vulns list [--host-id ID]
fleet vulns scan
fleet vulns refresh [--force]
fleet vulns job
mdm compliance
mdm policies
mdm policy create --name NAME
mdm assign --policy-id ID (--host-id ID | --label-id ID)
mdm unassign --policy-id ID (--host-id ID | --label-id ID)
mdm targets --policy-id ID
mdm lock --host-id ID
mdm retire --host-id ID
audit [--actor A] [--action A] [--resource-type T] [--resource-id ID] [--since T] [--limit N]
Scheduler / systemd details: Fleet. Host TLS / ACME: Certificates.
Also: lindir-admin help.
Passkey registration needs a browser WebAuthn ceremony — use Admin Directory → Passkeys, or the API begin/finish flow. CLI covers list/revoke.
Examples
lindir-admin health
lindir-admin ops attention
lindir-admin user create --username alice --password '…' --email alice@example.com
lindir-admin user disable --user-id UUID
lindir-admin group create --name admins
lindir-admin group add-member --group-id UUID --user-id UUID
lindir-admin host enroll --hostname box1 --tag tag:lindir
lindir-admin host enroll --hostname box1 --skip-vpn # already on Tailscale
lindir-admin enroll-token create --name lab --ttl-hours 24 --max-uses 1
lindir-admin account-policy get
lindir-admin account-policy set --min-password-length 12
lindir-admin oidc client create --name grafana --redirect-uri 'https://grafana/…'
lindir-admin oidc client create --name spa --redirect-uri 'https://spa/cb' --public
lindir-admin vpn sync-acls
lindir-admin fleet packages list
lindir-admin fleet packages pending
lindir-admin fleet packages cancel --id JOB_UUID
lindir-admin fleet packages install --host-id UUID --package nginx
lindir-admin fleet packages install --label-id UUID --package curl
lindir-admin fleet packages reboot --host-id UUID
lindir-admin fleet packages update-client --host-id UUID
lindir-admin fleet upgrades --host-id UUID
lindir-admin fleet energy list
lindir-admin fleet energy create --name laptop --idle-action suspend --idle-delay-sec 1800
lindir-admin fleet energy assign --policy-id UUID --label-id UUID
lindir-admin fleet energy unassign --policy-id UUID --label-id UUID
lindir-admin fleet certs create --name edge --domain example.com \
--dns-provider cloudflare --dns-credential "$CF_TOKEN" \
--cert-path /etc/lindir/certs/fullchain.pem --key-path /etc/lindir/certs/privkey.pem
lindir-admin fleet certs assign --policy-id UUID --host-id UUID
lindir-admin fleet certs status
lindir-admin fleet certs discover --host-id UUID
lindir-admin fleet labels assign --host-id UUID --label-id UUID
lindir-admin fleet labels hosts --label-id UUID
lindir-admin group remove-member --group-id UUID --user-id UUID
lindir-admin policy hbac check --host-id UUID --group-id UUID
lindir-admin mdm assign --policy-id UUID --host-id UUID
lindir-admin mdm unassign --policy-id UUID --host-id UUID
lindir-admin passkey list --user-id UUID
lindir-admin fleet vulns refresh --force
lindir-admin fleet vulns scan
lindir-admin fleet vulns list
lindir-admin audit --action auth --since '2026-01-01 00:00:00'
