chore(agents): re-vendor agent installers with --level support

Synced from the agent repo's feat/agent-permission-levels branch; the drift
check will pass once that branch is released.
This commit is contained in:
Juan Denis committed 2026-11-03 00:32:48 -05:00
1 parent 0aab404e35
commit 89cb315353
2 files changed
+210 -5

No files matched your search

+98 -5
View File
@@ -30,6 +30,17 @@
.PARAMETER Version
Specific agent version to install (optional, defaults to latest)
.PARAMETER Level
Permission level: monitor (report-only, no inbound commands), protect
(security actions only) or full (everything). If omitted: a menu on an
interactive console, otherwise full with a warning.
.PARAMETER Reconfigure
Required to change the level of an already-installed agent.
.PARAMETER Yes
Skip the typed confirmation when reconfiguring.
.EXAMPLE
.\install.ps1 -Token "sk_reg_xxx" -Server "https://your-serverkit.com"
@@ -53,7 +64,15 @@ param(
[string]$Name,
[Parameter(Mandatory=$false)]
[string]$Version = "latest"
[string]$Version = "latest",
[Parameter(Mandatory=$false)]
[ValidateSet("monitor", "protect", "full")]
[string]$Level,
[switch]$Reconfigure,
[switch]$Yes
)
# Configuration
@@ -172,11 +191,61 @@ function New-ConfigDirectory {
}
}
# Level recorded in an existing config ("" when none; no key = legacy = full).
function Get-InstalledLevel {
$cfg = Join-Path $ConfigDir "config.yaml"
if (-not (Test-Path $cfg)) { return "" }
$m = Select-String -Path $cfg -Pattern '^\s+level:\s*"?(\w+)"?' | Select-Object -First 1
if ($m) { return $m.Matches[0].Groups[1].Value }
return "full"
}
# Refuses to silently change an installed agent's level; returns the level to use.
function Resolve-Level {
param([string]$Level, [bool]$Reconfigure, [bool]$Yes)
$current = Get-InstalledLevel
if ($current) {
if (-not $Level) { return $current }
if ($Level -eq $current) { return $Level }
if (-not $Reconfigure) {
Write-ColorOutput "This agent is already installed at level '$current'. Re-run with -Reconfigure to change it to '$Level'." "Error"
exit 1
}
if (-not $Yes) {
$answer = Read-Host "Changing level $current -> $Level. Type '$Level' to confirm"
if ($answer -ne $Level) {
Write-ColorOutput "Confirmation did not match; permission level unchanged (use -Yes for scripted use)" "Error"
exit 1
}
}
$script:ChangeLevelFrom = $current
return $Level
}
if ($Level) { return $Level }
if ([Environment]::UserInteractive -and -not [Console]::IsInputRedirected) {
Write-Host ""
Write-Host " Choose what this agent may do on this server:"
Write-Host " 1) monitor report-only, accepts no commands from the panel"
Write-Host " 2) protect security actions only (firewall, fail2ban, CrowdSec, origin lock)"
Write-Host " 3) full everything"
switch (Read-Host " Selection [1-3]") {
"1" { return "monitor" }
"2" { return "protect" }
"3" { return "full" }
default { Write-ColorOutput "Invalid selection" "Error"; exit 1 }
}
}
Write-ColorOutput "No -Level given and no console: defaulting to FULL control. Pass -Level monitor|protect|full to choose." "Warning"
return "full"
}
function Register-Agent {
param(
[string]$Token,
[string]$Server,
[string]$Name
[string]$Name,
[string]$Level
)
Write-ColorOutput "Registering agent with ServerKit..." "Info"
@@ -188,6 +257,11 @@ function Register-Agent {
if ($Name) {
$arguments += @("--name", $Name)
}
$arguments += @("--level", $Level)
if ($script:ChangeLevelFrom) {
Start-Process -FilePath $agentPath -ArgumentList @("--config", $configPath, "permissions", "set", $Level, "--yes") -Wait -NoNewWindow | Out-Null
}
try {
$process = Start-Process -FilePath $agentPath -ArgumentList $arguments -Wait -PassThru -NoNewWindow
@@ -307,7 +381,15 @@ function Install-ServerKitAgent {
[string]$Name,
[Parameter(Mandatory=$false)]
[string]$Version = "latest"
[string]$Version = "latest",
[Parameter(Mandatory=$false)]
[ValidateSet("monitor", "protect", "full")]
[string]$Level,
[switch]$Reconfigure,
[switch]$Yes
)
# Update script-level variables
@@ -321,19 +403,30 @@ function Install-ServerKitAgent {
exit 1
}
$Level = Resolve-Level -Level $Level -Reconfigure $Reconfigure.IsPresent -Yes $Yes.IsPresent
Get-LatestVersion
Install-Agent
New-ConfigDirectory
Register-Agent -Token $Token -Server $Server -Name $Name
Register-Agent -Token $Token -Server $Server -Name $Name -Level $Level
Install-WindowsService
Start-AgentService
Add-ToPath
Write-SuccessMessage
Write-Host "Permission level: $($Level.ToUpper())" -ForegroundColor Yellow
switch ($Level) {
"monitor" { Write-Host " Report-only: this agent sends metrics out and accepts NO commands." }
"protect" { Write-Host " Security actions only (firewall, fail2ban, CrowdSec, origin lock)." }
default { Write-Host " Full control: the panel can run any supported action." }
}
Write-Host " Change it (elevated prompt, this machine only):"
Write-Host " & '$InstallDir\$AgentBinary' permissions set <monitor|protect|full>"
Write-Host ""
}
# Direct execution with parameters
if ($Token -and $Server) {
Install-ServerKitAgent -Token $Token -Server $Server -Name $Name -Version $Version
Install-ServerKitAgent -Token $Token -Server $Server -Name $Name -Version $Version -Level $Level -Reconfigure:$Reconfigure -Yes:$Yes
}
elseif ($PSBoundParameters.Count -gt 0) {
Write-ColorOutput "Both -Token and -Server parameters are required" "Error"
Regular → Executable
+112
View File
@@ -30,8 +30,16 @@
# --server, -s ServerKit server URL (required)
# --name, -n Display name for this server (optional)
# --version, -v Specific agent version to install (optional, defaults to latest)
# --level, -l Permission level: monitor | protect | full (see below)
# --reconfigure Allow changing the level of an already-installed agent
# --yes, -y Skip the typed confirmation when reconfiguring
# --help, -h Show this help message
#
# Permission levels: monitor = report-only (no inbound commands), protect =
# security actions only (firewall, fail2ban, CrowdSec, Cloudflare origin lock),
# full = everything. Omitted: a menu on a terminal; `full` (with a warning)
# when non-interactive, for compatibility with older install commands.
#
set -e
@@ -67,6 +75,9 @@ TOKEN=""
SERVER_URL=""
SERVER_NAME=""
VERSION="latest"
LEVEL=""
RECONFIGURE=false
ASSUME_YES=false
# Version injected by the panel when it serves this script (the panel already
# resolves the latest agent release for its update endpoints). Empty means
@@ -108,6 +119,9 @@ show_help() {
echo " --server, -s ServerKit server URL (required)"
echo " --name, -n Display name for this server (optional)"
echo " --version, -v Specific agent version (optional, defaults to latest)"
echo " --level, -l Permission level: monitor | protect | full (optional)"
echo " --reconfigure Allow changing the level of an already-installed agent"
echo " --yes, -y Skip the typed confirmation when reconfiguring"
echo " --help, -h Show this help message"
echo ""
echo "Example:"
@@ -142,6 +156,19 @@ parse_args() {
VERSION="$2"
shift 2
;;
--level|-l)
[[ $# -ge 2 ]] || log_error "Option $1 requires a value"
LEVEL="$(printf '%s' "$2" | tr '[:upper:]' '[:lower:]')"
shift 2
;;
--reconfigure)
RECONFIGURE=true
shift
;;
--yes|-y)
ASSUME_YES=true
shift
;;
--help|-h)
show_help
;;
@@ -159,6 +186,72 @@ parse_args() {
if [[ -z "$SERVER_URL" ]]; then
log_error "Server URL is required. Use --server or -s"
fi
if [[ -n "$LEVEL" ]]; then
case "$LEVEL" in
monitor|protect|full) ;;
*) log_error "Unknown permission level '$LEVEL' (use monitor, protect or full)" ;;
esac
fi
}
# Level recorded in an existing config ("" when none; a config without the
# key is a legacy install, which means full).
installed_level() {
local cfg="${CONFIG_DIR}/config.yaml"
[[ -f "$cfg" ]] || return 0
local lvl
lvl="$(sed -n '/^permissions:/,/^[^ ]/ s/^[[:space:]]*level:[[:space:]]*//p' "$cfg" | head -n1 | tr -d "\"' \r")"
printf '%s' "${lvl:-full}"
}
is_tty() { [[ -t 0 && -t 1 ]]; }
# Refuse to silently change the level of an installed agent; --reconfigure
# plus a typed confirmation (or --yes) is required.
check_reconfigure() {
local current
current="$(installed_level)"
[[ -n "$current" ]] || return 0
if [[ -z "$LEVEL" ]]; then
LEVEL="$current"
return 0
fi
[[ "$LEVEL" != "$current" ]] || return 0
if [[ "$RECONFIGURE" != true ]]; then
log_error "This agent is already installed at level '$current'. Re-run with --reconfigure to change it to '$LEVEL'."
fi
if [[ "$ASSUME_YES" != true ]]; then
local answer=""
if is_tty; then
read -r -p " Changing level ${current} -> ${LEVEL}. Type '${LEVEL}' to confirm: " answer
fi
[[ "$answer" == "$LEVEL" ]] || log_error "Confirmation did not match; permission level unchanged (use --yes for scripted use)"
fi
CHANGE_LEVEL_FROM="$current"
}
# Pick a level when none was given: menu on a terminal, else full + warning.
resolve_level() {
[[ -z "$LEVEL" ]] || return 0
if is_tty; then
echo ""
echo " Choose what this agent may do on this server:"
echo " 1) monitor report-only, accepts no commands from the panel"
echo " 2) protect security actions only (firewall, fail2ban, CrowdSec, origin lock)"
echo " 3) full everything (docker, files, terminal, packages, ...)"
local choice=""
read -r -p " Selection [1-3]: " choice
case "$choice" in
1|monitor) LEVEL=monitor ;;
2|protect) LEVEL=protect ;;
3|full) LEVEL=full ;;
*) log_error "Invalid selection" ;;
esac
else
log_warn "No --level given and no terminal: defaulting to FULL control. Pass --level monitor|protect|full to choose."
LEVEL=full
fi
}
check_root() {
@@ -351,6 +444,14 @@ register_agent() {
if [[ -n "$SERVER_NAME" ]]; then
REGISTER_CMD+=(--name "${SERVER_NAME}")
fi
REGISTER_CMD+=(--level "${LEVEL}")
# Re-installing at a different level: apply it locally first so the
# register step sees a consistent config.
if [[ -n "${CHANGE_LEVEL_FROM:-}" ]]; then
"${INSTALL_DIR}/${AGENT_BINARY}" --config "${CONFIG_DIR}/config.yaml" \
permissions set "${LEVEL}" --yes >/dev/null 2>&1 || true
fi
if ! "${REGISTER_CMD[@]}"; then
log_error "Agent registration failed"
@@ -448,6 +549,15 @@ print_success() {
echo -e "${GREEN}║ Installation completed successfully! ║${NC}"
echo -e "${GREEN}╚═══════════════════════════════════════════════════════════╝${NC}"
echo ""
echo -e "${YELLOW}Permission level: ${LEVEL^^}${NC}"
case "$LEVEL" in
monitor) echo " Report-only: this agent sends metrics out and accepts NO commands." ;;
protect) echo " Security actions only (firewall, fail2ban, CrowdSec, origin lock)." ;;
*) echo " Full control: the panel can run any supported action." ;;
esac
echo " Change it (as root, on this machine only):"
echo " ${INSTALL_DIR}/${AGENT_BINARY} permissions set <monitor|protect|full>"
echo ""
echo "Agent Status:"
echo " Binary: ${INSTALL_DIR}/${AGENT_BINARY}"
echo " Config: ${CONFIG_DIR}/config.yaml"
@@ -466,6 +576,8 @@ main() {
print_banner
parse_args "$@"
check_root
check_reconfigure
resolve_level
detect_platform
check_dependencies
get_latest_version