# sudoers grant that lets the unprivileged `ops` account install the homelab dashboards
# host agent on a monitored host. One line, one script path — deploy/nut-sudoers is the
# separate NUT grant on driveripper.
#
# Install (from the staged copy on the host, as root — the command-scoped `ops` sudo on
# these hosts does NOT include visudo, which is exactly why this file exists):
#
#   sudo visudo -cf /home/ops/agent-install/deploy/agent-sudoers   # syntax check FIRST
#   sudo install -m 0440 -o root -g root /home/ops/agent-install/deploy/agent-sudoers \
#     /etc/sudoers.d/dashboards-agent
#   sudo visudo -cf /etc/sudoers.d/dashboards-agent   # and check the installed copy
#
# Scope: an absolute path (no wildcards, `secure_path` is in effect), no shell, no editor,
# no `tee`, nothing that can amend this file. Running install-agent.sh without root prints
# this exact grant with the script's own resolved path, so a checkout at another path tells
# you what to add instead of saying "run as root" to someone who cannot.
#
# WHY THIS IS NEEDED
# The agent is read-only by construction: it answers GET /snapshot on a socket, writes
# nothing anywhere, and every request except /health needs the bearer token it reads from a
# file only root and the agent's own service user can read (0640 root:dashboards-agent — the
# agent opens the path itself, so the service user must be in that group). What needs root is
# the *install*, not the agent: creating the
# dashboards-agent system user, writing /usr/local/lib/dashboards-agent/host_agent.py,
# dropping /etc/systemd/system/dashboards-agent.service, storing the token, and running
# systemctl daemon-reload + enable --now (disable --now for --uninstall).
# Phase 10 runs each host's agent as that systemd service bound to the address the
# dashboard dials directly, so the account that deploys over ssh — ops — has to be able to
# run the installer, and that is the only reason it is granted anything.
#
# WHY THE WHOLE SCRIPT PATH AND NOT A FLAG LIST
# The flags carry no secrets: --bind/--port choose the socket, --status is read-only,
# --uninstall removes exactly what this install put in place, --rotate-token mints a token
# the operator is about to be shown anyway. sudoers can only match flags with a wildcard,
# and a wildcard list has to be edited in step with every flag the script gains — an edit
# whose failure mode is a broken install, not a smaller privilege. The one flag whose
# *argument* would be sensitive is --token, and no documented flow uses it: the installer
# generates the token, prints it once, and hands the agent --token-file, because argv is
# world-readable through ps while the file is not.

# ---- the grant ------------------------------------------------------------------ #
# The host has no repo checkout, so deploy/ and agent/ are staged to ~/agent-install/
# (phase 10 task 02 does the copy), which keeps this path identical on every host:
#
#   ssh ops@host 'mkdir -p ~/agent-install'
#   scp -r deploy agent ops@host:~/agent-install/
#
# `ops` is the fleet's monitored/deploy account; change only that field if the agent is
# installed by a different account. Nothing follows the path, which in sudoers means the
# script may be run with any of its own flags — see the block above.
ops ALL=(root) NOPASSWD: /home/ops/agent-install/deploy/install-agent.sh

# ---- making the grant mean something (one root command, recommended) ------------ #
# A sudo grant on a path is only as strong as who can write that path. ops owns
# ~/agent-install, so until the staged copy is root-owned this line is a convenience for a
# human, not a boundary. After staging, as root:
#
#   sudo chown -R root:root /home/ops/agent-install
#
# ops can still wipe its own home directory and re-copy (it is ops' home), so this guards
# against drift and a stray edit — not against an operator who wants something else.

# ---- deliberately NOT granted --------------------------------------------------- #
#   visudo, vim, nano, sh, bash, tee  — no self-amendment of this grant, no shell, and no
#                                       writing any file as root
#   systemctl (anything else)         — the installer already runs the few unit operations
#                                       it needs as itself; a bare systemctl * could stop
#                                       anything on the host
#   cat /etc/dashboards-agent.token   — the token is readable by root and the agent user
#                                       only; install-agent.sh prints it once on first
#                                       install and --rotate-token mints a new one
#   useradd, usermod, groupmod        — the installer creates its own user and its disk
#                                       group membership; a bare usermod could add ops to
#                                       any group on the box
#   upscmd, upsrw                     — NUT instant commands stay the dashboard's gated
#                                       POST /api/ups/command; see deploy/nut-sudoers
