Agent Deployment
Install and configure the TATER compliance agent on Windows, macOS, and Linux endpoints for automated evidence collection, OS compliance scanning, and speed testing.
The agent makes outbound HTTPS connections to api.tatersecurity.com and www.tatersecurity.com. If your environment uses an SSE/SASE platform (Microsoft Global Secure Access, Zscaler, Netskope, Cisco Umbrella, Palo Alto Prisma) or a corporate proxy with TLS inspection, you almost certainly need to add bypass rules. See Agent Network Requirements for the full domain allowlist and SSE/SASE bypass guide. Most agent-not-reporting cases trace back to TLS inspection breaking the API connection.
Agent Overview
The TATER Agent is a lightweight, cross-platform Go binary that runs as a system service on Windows, macOS, and Linux endpoints. It collects compliance data, runs security benchmark checks, and uploads results to the TATER API. Key features:
- Windows: CIS benchmark scanning (registry, services, firewall, audit policy) via PowerShell controls
- macOS: 20 security controls (FileVault, Firewall, Gatekeeper/SIP, auto-updates, screen lock, sharing, and more) via bash scripts
- Linux: 20 security controls (firewall, SSH hardening, disk encryption, SELinux/AppArmor, auditd, and more) via bash scripts
- Network speed testing using self-hosted test files
- Automatic result upload to the TATER API
- Auto-update with SHA-256 hash verification
- System tray application for status monitoring (Windows and macOS)
- Local compliance dashboard (opens in browser)
| Platform | Binary | Service | Tray | Controls |
|---|---|---|---|---|
| Windows (x64) | tater-agent.exe | Windows SCM | Yes | PowerShell (.ps1) |
| macOS (Apple Silicon) | tater-agent-darwin-arm64 | launchd | Yes | Bash (.sh) |
| macOS (Intel) | tater-agent-darwin-amd64 | launchd | Yes | Bash (.sh) |
| Linux (x64) | tater-agent-linux-amd64 | systemd | No (headless) | Bash (.sh) |
| Linux (ARM64) | tater-agent-linux-arm64 | systemd | No (headless) | Bash (.sh) |
MSI Installation
Interactive Installation
Download the MSI
Download TATER-Agent.msi from the TATER Settings → Endpoint Agent page, or from https://www.tatersecurity.com/Agent/TATER-Agent.msi.
Run the installer
Double-click the MSI file. The installation wizard will prompt for the TATER API base URL, API key, and Organization ID.
Enter configuration
Provide the API base URL (e.g., https://api.tatersecurity.com/api), your API key, and your organization ID. The installer auto-appends /api if not present.
Complete installation
Click Install. The agent service starts automatically and the tray application launches.
Silent Installation
For unattended deployments, use msiexec with the /qn flag:
# Basic silent install
msiexec /i TATER-Agent.msi /qn APIBASE="https://api.tatersecurity.com/api" APIKEY="your-key" TENANTID="your-tenant" ORGANIZATIONID="your-org"
# With logging for troubleshooting
msiexec /i TATER-Agent.msi /qn APIBASE="https://api.tatersecurity.com/api" APIKEY="your-key" TENANTID="your-tenant" ORGANIZATIONID="your-org" /l*v "%TEMP%\tater-install.log"
# Uninstall silently
msiexec /x TATER-Agent.msi /qn
MSI Properties
MSI properties use uppercase KEY=value syntax on the msiexec command line. The installer writes these to config.json during installation (see Configuration File Reference below).
| Property | Required | config.json Key | Description |
|---|---|---|---|
APIBASE | Yes | apiBase | TATER API base URL. The MSI auto-appends /api if missing. |
APIKEY | Yes | apiKey | API key for authenticating scan uploads. Generate from Settings → API Keys. |
TENANTID | Yes | tenantId | Your Azure AD tenant ID (GUID). |
ORGANIZATIONID | Yes | organizationId | Organization ID (format: org-xxxxxxxx). Found on Settings → Endpoint Agent. |
APPID | No | appId | App registration client ID for app-only cloud scan authentication. |
CERTTHUMBPRINT | No | certificateThumbprint | Certificate thumbprint for app-only authentication. Note: the config.json key is certificateThumbprint — not certThumbprint. |
M365ORG | No | organization | Your Microsoft 365 tenant domain (e.g. contoso.onmicrosoft.com). Note: the config.json key is organization — not m365Org. |
SCHEDULEFREQUENCY | No | (schedule object) | Scan schedule frequency: Daily (default), Weekly, or Hourly. |
SCHEDULEHOUR | No | (schedule object) | Hour of day to run (0–23, default 3). Only used when SCHEDULEFREQUENCY is Daily or Weekly. |
The MSI installer uses uppercase KEY=value Windows Installer property syntax, while the Go agent binary reads directly from config.json. These use different key names in several cases:
CERTTHUMBPRINT(MSI) →certificateThumbprint(config.json) — completely different casing and nameM365ORG(MSI) →organization(config.json) — completely different nameORGANIZATIONID(MSI) →organizationId(config.json) — case change only
When writing a config.json directly (macOS, Linux, or custom Windows deploy), always use the camelCase config.json key names, not the MSI property names.
Installation Paths (Windows MSI)
The TATER MSI creates files in two separate directories:
| Path | Contents | Notes |
|---|---|---|
C:\Program Files\TATER\ | Agent binary (tater-agent.exe) | User-selectable install directory. Default is Program Files\TATER. |
C:\ProgramData\TATER\ | All runtime data | Always this path — not affected by install directory selection. |
C:\ProgramData\TATER\config.json | Agent configuration | Written by MSI from installer properties. Edit to reconfigure without reinstalling. |
C:\ProgramData\TATER\Logs\ | Agent log files | Rotated automatically; last 10 logs retained. |
C:\ProgramData\TATER\Controls\ | PowerShell control scripts | Downloaded from TATER at runtime for compliance checks. |
C:\ProgramData\TATER\Scans\ | Local scan result cache | Last 10 scan results retained. |
Windows Service: The MSI installs a Windows service named TATERAgent. Detection scripts should query this service directly:
Get-Service -Name "TATERAgent" -ErrorAction SilentlyContinue
Configuration File Reference
The agent reads configuration from config.json at startup. On Windows the MSI writes this file; on macOS and Linux your install script must write it directly.
{
"apiBase": "https://api.tatersecurity.com/api",
"apiKey": "tater_xxxxxxxxxxxx",
"tenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"organizationId": "org-xxxxxxxxxxxxxxxx",
// Optional: app-only authentication for cloud scanning
"appId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"certificateThumbprint": "AABBCC...",
"organization": "contoso.onmicrosoft.com",
// Optional: agent behavior
"products": "All",
"scanIntervalHours": 24,
"controlsPath": "C:\\ProgramData\\TATER\\Controls"
}
| Key | Type | Description |
|---|---|---|
apiBase | string | TATER API base URL. Must end in /api. |
apiKey | string | API key for scan upload authentication. |
tenantId | string | Azure AD tenant ID (GUID). |
organizationId | string | TATER Organization ID (format: org-xxxxxxxx). |
appId | string | App registration client ID for app-only cloud authentication. |
certificateThumbprint | string | Certificate thumbprint (hex, uppercase). Used with appId for app-only auth. |
organization | string | Microsoft 365 tenant domain (e.g. contoso.onmicrosoft.com). |
products | string | Compliance products to scan. Default: All. Options: All, AllCloud, AllEndpoint. |
scanIntervalHours | integer | Hours between automated scans. Default: 24. |
controlsPath | string | Directory containing control scripts. Windows default: %ProgramData%\TATER\Controls. |
logPath | string | Directory for agent log files. Windows default: %ProgramData%\TATER\Logs. |
The TATER Agent supports Windows 10/11 or Windows Server 2019+, macOS 12+ (Apple Silicon or Intel), and Linux (amd64 or arm64, systemd required). The agent service runs as SYSTEM (Windows) or root (Linux/macOS) and requires local administrator privileges for compliance checks (registry, services, firewall, audit policy).
Intune Deployment (Windows)
Three deployment methods are supported. Pick the one that matches your environment:
| Method | Best for | Self-heals | Works on AVD multi-session | Uninstall on removal |
|---|---|---|---|---|
| Proactive Remediation (recommended) | Most fleets — workstations and AVD hosts alike | Yes (re-runs on schedule) | Yes | Manual |
| Win32 App | Single-session workstations only | No | No (unsupported) | Automatic via uninstall command |
| Group Policy / SCCM | On-prem AD environments without Intune | No | N/A | Manual |
If you're not sure, use Proactive Remediation. It's the most resilient and the only one compatible with Windows Server multi-session AVD hosts.
Proactive Remediation (Recommended)
Proactive Remediation is the recommended deployment method for Windows endpoints, including AVD (Azure Virtual Desktop) multi-session hosts and standard workstations. Unlike Win32 apps, Proactive Remediation scripts run in system context, re-run on a schedule to self-heal if the agent is removed or stops reporting, and work on AVD multi-session OS where Win32 app deployment is unsupported.
If you have older Intune scripts that check for %ProgramData%\TATER\TATER-Agent.ps1 or a scheduled task running PowerShell, those are v1.3.4 (legacy PS agent) patterns. The current v2.x agent is a Go binary (tater-agent.exe) running as a Windows service named TATERAgent. Detection scripts looking for the PS1 file or scheduled task will never find them after a successful install — producing an infinite remediation loop where Intune flags every device as Non-compliant despite the agent working correctly. Use the v2.x scripts below.
Create two PowerShell scripts. The detection script below covers four health signals: service installed, service running, config valid, and recent agent output (so a stuck service that never produces logs gets re-remediated):
Detect-TATERAgent.ps1 — returns exit code 1 (non-compliant) if any health signal fails:
# Detect-TATERAgent.ps1 — Intune Proactive Remediation Detection (Go agent v2.x)
$TATERDir = Join-Path $env:ProgramData 'TATER'
$ConfigPath = Join-Path $TATERDir 'config.json'
$LogDir = Join-Path $TATERDir 'Logs'
$ScansDir = Join-Path $TATERDir 'Scans'
$MaxAgeHours = 48
$issues = @()
# 1 — Windows service installed and running
$svc = Get-Service -Name 'TATERAgent' -ErrorAction SilentlyContinue
if (-not $svc) {
$issues += "TATERAgent Windows service not installed"
} elseif ($svc.Status -ne 'Running') {
$issues += "TATERAgent service is $($svc.Status), expected Running"
} elseif ($svc.StartType -eq 'Disabled') {
$issues += "TATERAgent service start type is Disabled"
}
# 2 — config.json present with required keys
if (-not (Test-Path $ConfigPath)) {
$issues += "config.json not found at $ConfigPath"
} else {
try {
$cfg = Get-Content $ConfigPath -Raw | ConvertFrom-Json
foreach ($key in @('apiBase', 'tenantId', 'organizationId')) {
if (-not $cfg.$key) { $issues += "config.json missing required key: $key" }
}
if (-not $cfg.apiKey -and -not $cfg.encryptedApiKey) {
$issues += "config.json missing apiKey or encryptedApiKey"
}
} catch {
$issues += "config.json is not valid JSON: $_"
}
}
# 3 — Recent log or scan evidence (only if service is otherwise healthy)
if ($svc -and $svc.Status -eq 'Running' -and (Test-Path $ConfigPath)) {
$lastEvidence = $null
if (Test-Path $LogDir) {
$latest = Get-ChildItem -Path $LogDir -Filter 'TATER-Agent_*.log' -ErrorAction SilentlyContinue |
Sort-Object LastWriteTime -Descending | Select-Object -First 1
if ($latest) { $lastEvidence = $latest.LastWriteTime }
}
if (Test-Path $ScansDir) {
$latest = Get-ChildItem -Path $ScansDir -Filter '*.json' -ErrorAction SilentlyContinue |
Sort-Object LastWriteTime -Descending | Select-Object -First 1
if ($latest -and (-not $lastEvidence -or $latest.LastWriteTime -gt $lastEvidence)) {
$lastEvidence = $latest.LastWriteTime
}
}
if (-not $lastEvidence) {
$issues += "No agent log or scan files found — service running but agent has not produced output yet"
} else {
$ageHours = ((Get-Date) - $lastEvidence).TotalHours
if ($ageHours -gt $MaxAgeHours) {
$issues += "Agent last produced output $([math]::Round($ageHours,1))h ago (threshold: ${MaxAgeHours}h)"
}
}
}
if ($issues.Count -gt 0) {
Write-Output "NON-COMPLIANT: $($issues -join ' | ')"
exit 1
}
Write-Output "COMPLIANT: TATERAgent service running, config valid, evidence within ${MaxAgeHours}h"
exit 0
Remediate-TATERAgent.ps1 — installs the MSI, writes config.json directly (overwrites any defaults the MSI dropped), restarts the service, and triggers a one-shot scan:
# Remediate-TATERAgent.ps1 — Intune Proactive Remediation (Go agent v2.x)
# Edit these values before deploying
$Config = @{
apiBase = "https://api.tatersecurity.com/api"
apiKey = "your-api-key"
tenantId = "your-azure-tenant-id"
organizationId = "your-org-id"
products = "All"
appId = "your-cloud-scan-app-id" # optional, for cloud scans
certificateThumbprint = "your-cloud-scan-cert-thumbprint" # optional, for cloud scans
organization = "your-tenant.onmicrosoft.com" # optional, for cloud scans
tenantEnvironment = "commercial" # commercial | usGovGcc | usGovGccHigh | usGovDoD
}
$TATERDir = Join-Path $env:ProgramData 'TATER'
$ConfigPath = Join-Path $TATERDir 'config.json'
$LogDir = Join-Path $TATERDir 'Logs'
$MSI_URL = "https://www.tatersecurity.com/Agent/TATER-Agent.msi"
$TempDir = "C:\Windows\Temp\TATERInstall"
$MSIPath = Join-Path $TempDir 'TATER-Agent.msi'
function Write-Log { param([string]$m) Write-Output "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] $m" }
try {
# 1. Install MSI if service is missing
$svc = Get-Service -Name 'TATERAgent' -ErrorAction SilentlyContinue
if (-not $svc) {
Write-Log "TATERAgent service not installed — downloading and installing MSI..."
if (-not (Test-Path $TempDir)) { New-Item -ItemType Directory -Path $TempDir -Force | Out-Null }
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest -Uri $MSI_URL -OutFile $MSIPath -UseBasicParsing -ErrorAction Stop
# Pass required MSI properties — the MSI's GenerateConfig custom action will
# fail the install if APIBASE / APIKEY / TENANTID / ORGANIZATIONID are missing.
# We still rewrite config.json from $Config in step 3 below, but the MSI itself
# must succeed first or the service is never installed. Start-Process accepts
# an array of arguments and quotes each one automatically — no need for
# PowerShell backtick-escape soup.
$logPath = Join-Path $TempDir 'tater-install.log'
$msiArgs = @(
'/i', $MSIPath,
'/qn',
'/l*v', $logPath,
"APIBASE=$($Config.apiBase)",
"APIKEY=$($Config.apiKey)",
"TENANTID=$($Config.tenantId)",
"ORGANIZATIONID=$($Config.organizationId)"
)
$proc = Start-Process -FilePath 'msiexec.exe' -ArgumentList $msiArgs -Wait -PassThru
if ($proc.ExitCode -ne 0 -and $proc.ExitCode -ne 3010) {
throw "MSI install failed with exit code $($proc.ExitCode) — see $TempDir\tater-install.log"
}
Write-Log "MSI installed (exit code: $($proc.ExitCode))"
} else {
Write-Log "TATERAgent service already installed (status: $($svc.Status))"
}
# 2. Ensure data dir exists
foreach ($dir in @($TATERDir, $LogDir)) {
if (-not (Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null }
}
# 3. Write config.json (no BOM — Go agent strips BOMs but writing clean is safer)
Write-Log "Writing config.json..."
$json = $Config | ConvertTo-Json -Depth 3
[System.IO.File]::WriteAllText($ConfigPath, $json, [System.Text.UTF8Encoding]::new($false))
Write-Log "config.json written"
# 4. Auto-start + (re)start the service so it picks up the new config
Set-Service -Name 'TATERAgent' -StartupType Automatic -ErrorAction Stop
$svc = Get-Service -Name 'TATERAgent'
if ($svc.Status -eq 'Running') {
Write-Log "Restarting TATERAgent..."
Restart-Service -Name 'TATERAgent' -Force -ErrorAction Stop
} else {
Write-Log "Starting TATERAgent..."
Start-Service -Name 'TATERAgent' -ErrorAction Stop
}
# 5. Trigger an immediate one-shot scan so detection finds fresh evidence
$exePath = (Get-WmiObject -Class Win32_Service -Filter "Name='TATERAgent'").PathName
if ($exePath) {
$exe = ($exePath -replace '"', '').Trim() -split ' ' | Select-Object -First 1
if (Test-Path $exe) {
Write-Log "Triggering one-shot scan via '$exe -scan'..."
Start-Process -FilePath $exe -ArgumentList '-scan' -WindowStyle Hidden -ErrorAction SilentlyContinue
}
}
Write-Log "SUCCESS: TATERAgent remediated"
exit 0
} catch {
Write-Log "ERROR: $($_.Exception.Message)"
exit 1
} finally {
Remove-Item -Path $MSIPath -Force -ErrorAction SilentlyContinue
}
1. Create the Proactive Remediation
In Intune admin center, go to Devices > Scripts and remediations > Create. Name it "TATER Agent Deployment".
2. Upload scripts
Upload Detect-TATERAgent.ps1 as the detection script and Remediate-TATERAgent.ps1 as the remediation script. Set Run script in 64-bit PowerShell to Yes.
3. Configure schedule
Set Run frequency to Every 1 hour (ensures self-healing). Set Run this script using the logged-on credentials to No (runs as SYSTEM).
4. Assign to groups
Assign to All Windows Devices or a specific device group. For AVD session hosts, use the host pool device group.
Proactive Remediation requires Microsoft Intune Plan 1 (included in Microsoft 365 E3/E5, Business Premium, or as a standalone add-on). It is available under Endpoint Analytics in the Intune admin center.
Win32 App (Alternative)
Win32 app deployment does not work on Azure Virtual Desktop (AVD) multi-session OS hosts. Use Proactive Remediation for AVD environments.
For standard (non-AVD) Windows devices, the Win32 app method is also supported:
- Package the MSI using the Microsoft Win32 Content Prep Tool (
IntuneWinAppUtil.exe) - In Intune admin center, go to Apps > All Apps > Add
- Select Windows app (Win32)
- Upload the
.intunewinpackage - Install command:
msiexec /i TATER-Agent.msi /qn APIBASE="https://api.tatersecurity.com/api" APIKEY="your-key" TENANTID="your-tenant" ORGANIZATIONID="your-org" - Uninstall command:
msiexec /x TATER-Agent.msi /qn - Detection rule: File exists at
C:\Program Files\TATER\tater-agent.exe - Assign to target device groups
Group Policy / SCCM Deployment
For Group Policy or SCCM deployment, create a deployment package with the MSI and a transform (.mst) file or use command-line properties:
# Group Policy software installation
# Place the MSI on a network share accessible by target machines
# Create a GPO with Software Installation pointing to:
\\fileserver\share\TATER-Agent.msi
# For SCCM, create a package with the following program command line:
msiexec /i TATER-Agent.msi /qn APIBASE="https://api.tatersecurity.com/api" APIKEY="your-key" TENANTID="your-tenant" ORGANIZATIONID="your-org"
macOS Deployment
Platform Scripts (Recommended)
The recommended way to deploy the TATER Agent on macOS via Intune is Platform Scripts (formerly Shell Scripts). A single idempotent script installs the agent, writes the config file, registers the launchd daemon, and starts the service. The script is safe to run multiple times — it skips steps that are already complete.
The Go agent reads configuration only from /Library/Application Support/TATER/config.json. It does not accept --apiBase, --apiKey, --tenantId, or other config flags — those are silently ignored. If your LaunchDaemon's ProgramArguments array passes 16 string flags to tater-agent, the agent starts with empty config, fails the cfg.ApiBase == "" validation check, and exits. launchctl load still reports success, so the install script appears to succeed, but the agent never actually scans. Also ensure RunAtLoad is true — otherwise the agent only fires at the 3 AM scheduled interval. Use the script below, which writes a proper config.json and invokes tater-agent with no flags.
The TATER macOS agent binary is currently not signed or notarized with an Apple Developer ID. Files downloaded via curl automatically receive the com.apple.quarantine extended attribute, which causes macOS Gatekeeper to silently block execution — even when launched by launchd running as root. launchctl load reports success, but the process never starts, so the agent appears installed but never produces logs, scans, or API posts. The binary is also unlaunchable from Finder/Terminal until the xattr is removed. The script below now runs xattr -d com.apple.quarantine after each download. If you've already deployed an earlier version of this script and your devices show installed-but-not-reporting, run sudo xattr -c /usr/local/bin/tater-agent && sudo launchctl kickstart -k system/com.tatersecurity.agent to clear the attribute and restart.
tater_agent_install.sh — create this script and deploy it via Intune:
#!/bin/bash
# tater_agent_install.sh — TATER Agent idempotent installer for Intune Platform Scripts
# Deploy via: Devices > Scripts > macOS > Add
# ── Configure these four values ────────────────────────────────────────────
API_BASE="https://api.tatersecurity.com/api"
API_KEY="your-api-key"
TENANT_ID="your-azure-tenant-id"
ORG_ID="your-org-id"
# ───────────────────────────────────────────────────────────────────────────
set -euo pipefail
ARCH=$(uname -m)
if [[ "$ARCH" == "arm64" ]]; then
BINARY_URL="https://www.tatersecurity.com/Agent/tater-agent-darwin-arm64"
else
BINARY_URL="https://www.tatersecurity.com/Agent/tater-agent-darwin-amd64"
fi
INSTALL_DIR="/usr/local/bin"
DATA_DIR="/Library/Application Support/TATER"
PLIST_PATH="/Library/LaunchDaemons/com.tatersecurity.agent.plist"
BINARY_PATH="$INSTALL_DIR/tater-agent"
# Download binary if not already installed or if outdated
if [[ ! -f "$BINARY_PATH" ]]; then
curl -fsSL "$BINARY_URL" -o "$BINARY_PATH"
chmod 755 "$BINARY_PATH"
chown root:wheel "$BINARY_PATH"
# CRITICAL: strip the com.apple.quarantine xattr that curl applies to downloads.
# Without this, macOS Gatekeeper silently blocks the unsigned binary from running
# — launchctl load reports success but the process never actually starts.
xattr -d com.apple.quarantine "$BINARY_PATH" 2>/dev/null || true
xattr -c "$BINARY_PATH" 2>/dev/null || true
fi
# Create data directory
mkdir -p "$DATA_DIR/Logs"
# Write config (idempotent)
cat > "$DATA_DIR/config.json" <<EOF
{
"apiBase": "$API_BASE",
"apiKey": "$API_KEY",
"tenantId": "$TENANT_ID",
"organizationId": "$ORG_ID",
"scanIntervalHours": 24
}
EOF
# Register launchd daemon
cat > "$PLIST_PATH" <<PLIST
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key><string>com.tatersecurity.agent</string>
<key>ProgramArguments</key>
<array><string>$BINARY_PATH</string></array>
<key>WorkingDirectory</key><string>$DATA_DIR</string>
<key>RunAtLoad</key><true/>
<key>KeepAlive</key><true/>
<key>StandardOutPath</key><string>$DATA_DIR/Logs/tater-agent.stdout.log</string>
<key>StandardErrorPath</key><string>$DATA_DIR/Logs/tater-agent.stderr.log</string>
</dict>
</plist>
PLIST
chmod 644 "$PLIST_PATH"
chown root:wheel "$PLIST_PATH"
# Load/reload the daemon
launchctl unload "$PLIST_PATH" 2>/dev/null || true
launchctl load "$PLIST_PATH"
echo "TATER Agent installed and started successfully."
exit 0
1. Upload the script to Intune
In Intune admin center, go to Devices > Scripts > macOS > Add. Upload tater_agent_install.sh.
2. Configure script settings
Set Run script as signed-in user to No (runs as root). Set Hide script notifications on devices to Yes. Script frequency: Not configured (runs once on enrollment; re-run manually as needed).
3. Assign to groups
Assign to All macOS Devices or a specific device group. The script is idempotent — safe to re-run on existing devices.
Manual macOS Installation
# Download and install (Apple Silicon)
sudo TATER_API_BASE="https://api.tatersecurity.com/api" \
TATER_API_KEY="your-api-key" \
TATER_TENANT_ID="your-tenant-id" \
TATER_ORG_ID="your-org-id" \
bash install.sh
# Check service status
launchctl list com.tatersecurity.agent
# View logs
tail -f "/Library/Application Support/TATER/Logs/tater-agent.stdout.log"
# Restart service
sudo launchctl unload /Library/LaunchDaemons/com.tatersecurity.agent.plist
sudo launchctl load /Library/LaunchDaemons/com.tatersecurity.agent.plist
# Uninstall
sudo bash uninstall.sh
Intune Detection Rule
Set the detection rule to: Custom script that checks test -f /usr/local/bin/tater-agent, or use File exists at /usr/local/bin/tater-agent.
macOS Security Controls (20)
| Control | Check | Tool |
|---|---|---|
| MAC_001 | FileVault disk encryption | fdesetup status |
| MAC_002 | Application Firewall + stealth mode | socketfilterfw |
| MAC_003 | Gatekeeper + System Integrity Protection | spctl, csrutil |
| MAC_004 | Automatic software updates | defaults read |
| MAC_005 | Screen lock password (within 5s) | defaults read |
| MAC_006 | Remote Login (SSH) disabled | systemsetup |
| MAC_007 | No sharing services enabled | launchctl list |
| MAC_008 | Password policy configured | pwpolicy |
| MAC_009 | Time Machine backup + encryption | tmutil |
| MAC_010 | Guest account disabled | defaults read |
| MAC_011 | AirDrop not set to Everyone | defaults read |
| MAC_012 | XProtect definitions current | XProtect bundle plist |
| MAC_013 | NTP time sync enabled | systemsetup |
| MAC_014 | Bluetooth not discoverable | defaults read |
| MAC_015 | Secure Boot (Full Security) | bputil / nvram |
| MAC_016 | No pending software updates | softwareupdate -l |
| MAC_017 | Remote Management (ARD) disabled | launchctl |
| MAC_018 | Login window: Name + Password | defaults read |
| MAC_019 | OpenBSM audit daemon running | launchctl |
| MAC_020 | Wi-Fi using WPA2/WPA3 | airport -I |
Linux Deployment
# Download and install (auto-detects amd64/arm64)
sudo TATER_API_BASE="https://api.tatersecurity.com/api" \
TATER_API_KEY="your-api-key" \
TATER_TENANT_ID="your-tenant-id" \
TATER_ORG_ID="your-org-id" \
bash install.sh
# Check service status
sudo systemctl status TATERAgent
# View logs
sudo journalctl -u TATERAgent -f
# Restart service
sudo systemctl restart TATERAgent
# Uninstall
sudo tater-agent -uninstall
sudo rm /usr/local/bin/tater-agent
Linux installs to /usr/local/bin/tater-agent with config at /var/lib/tater/config.json (root) or ~/.config/tater/config.json (user). The agent registers as a systemd service and runs 20 bash security controls (firewall, SSH hardening, disk encryption, SELinux/AppArmor, auditd, kernel hardening, etc.).
Agent Auto-Update
The TATER Agent automatically checks for updates on each run:
- Agent queries
GET /api/agent/version(no authentication required) - The API returns the latest version number, download URL, and SHA-256 hash
- If a newer version is available, the agent downloads the updated MSI from the TATER SWA
- SHA-256 hash is verified against the API-provided hash to ensure integrity
- The update is applied silently on the next agent restart
The /api/agent/version endpoint requires no authentication, allowing agents behind firewalls to check for updates without API key exposure. The response includes: { version, downloadUrl, sha256 }.
Speed Test
If your tenant uses Microsoft Global Secure Access, Zscaler, Netskope, Cisco Umbrella, or Palo Alto Prisma Access, the speed-test endpoints below need to be bypassed from traffic forwarding and SSL inspection — otherwise the test measures proxy throughput, not real-world ISP capacity. See the Agent Network Requirements guide for the FQDN bypass list and per-vendor configuration steps.
The agent includes a built-in network speed test that measures download bandwidth:
- Tests use self-hosted files at
https://www.tatersecurity.com/Agent/speedtest/100mb.binand50mb.bin - No dependency on third-party services (Cloudflare caps at ~25MB)
- Results are uploaded to the TATER API and visible on the Scans page in the "Speed Test" group
- Speed test data is also displayed in individual device detail views
Tray Application
The TATER Tray application runs in the system tray and provides:
- Agent status indicator (running, idle, scanning)
- Last scan timestamp and result summary
- Manual scan trigger
- Speed test trigger
- Access to agent logs
- Hidden from the Windows taskbar — only visible in the system tray notification area
- Uses the TATER shield logo icon
History Cleanup
The agent automatically manages disk space by keeping only the most recent data:
- Keeps the last 10 log files
- Keeps the last 10 scan result files
- Keeps the last 10 speed test result files
- Older files are deleted at the start of each agent run
Post-install Verification
After deploying to a test device, run these checks to confirm the agent is healthy before rolling out to the full fleet. The first scan typically completes within 10 minutes of install.
Windows
# 1. Service is installed and running
Get-Service -Name 'TATERAgent'
# Expected: Status = Running, StartType = Automatic
# 2. Config file is present and valid JSON
Get-Content "$env:ProgramData\TATER\config.json" | ConvertFrom-Json |
Format-List apiBase, tenantId, organizationId
# Expected: all three fields populated; no parse errors
# 3. Agent has produced output recently (logs or scans)
Get-ChildItem "$env:ProgramData\TATER\Logs", "$env:ProgramData\TATER\Scans" `
-Recurse -ErrorAction SilentlyContinue |
Sort-Object LastWriteTime -Descending | Select-Object -First 5 FullName, LastWriteTime
# Expected: at least one file modified within the last hour after install
# 4. Trigger a one-shot scan if no recent output
& "$env:ProgramFiles\TATER\tater-agent.exe" -scan
macOS
# 1. LaunchDaemon is loaded and process is running
sudo launchctl print system/com.tatersecurity.agent | head -20
# Expected: state = running
# 2. Config file is present
cat "/Library/Application Support/TATER/config.json"
# Expected: apiBase, tenantId, organizationId all populated
# 3. No quarantine xattr blocking the binary (see macOS section above)
xattr /usr/local/bin/tater-agent
# Expected: no output (or no com.apple.quarantine line)
# 4. Recent log output
sudo tail -50 "/Library/Application Support/TATER/Logs/tater-agent.stdout.log"
# Expected: scan loop heartbeat or scan-completion lines
Linux
# 1. systemd service status
sudo systemctl status tater-agent
# Expected: active (running), enabled
# 2. Config file
cat /var/lib/tater/config.json
# Expected: apiBase, tenantId, organizationId populated
# 3. Recent journal output
sudo journalctl -u tater-agent -n 50 --no-pager
# Expected: scan-loop heartbeat or successful upload lines
In TATER (any platform)
- Open app.tatersecurity.com → Devices. The newly installed device should appear within 10 minutes of the first successful scan upload.
- Open Scans. There should be a fresh endpoint scan with the device's hostname in the list.
- Open Settings → Endpoint Agent. The status card "Total Devices" and "Last Scan" should reflect the new device.
Troubleshooting
Common Issues
| Issue | Solution |
|---|---|
| Intune Proactive Remediation reports Failed but service is installed | The MSI custom action requires APIBASE, APIKEY, TENANTID, ORGANIZATIONID at install time. Older versions of the Remediate script ran msiexec /i $MSIPath /qn with no properties — the install fails before the service is created. Confirm your script passes all four MSI properties on the msiexec command line. See the Remediate-TATERAgent.ps1 above for the correct pattern. Inspect C:\Windows\Temp\TATERInstall\tater-install.log on a failed device to see which property the installer rejected. |
| Intune detection always reports Non-Compliant after install | You're likely running a v1.x detection script that looks for %ProgramData%\TATER\TATER-Agent.ps1 or a scheduled task. The current v2.x agent is a Go binary running as a Windows service. Replace the detection script with the v2.x version above (checks the TATERAgent Windows service + config file + recent log output). |
| macOS install succeeds but agent never reports / can't be launched manually | The agent binary is unsigned, and curl applies com.apple.quarantine on download — macOS Gatekeeper silently blocks execution even when launchd runs as root. The current install script strips the xattr automatically. To fix already-deployed devices: sudo xattr -c /usr/local/bin/tater-agent && sudo launchctl kickstart -k system/com.tatersecurity.agent. |
| MSI install fails with BadImageFormatException | Ensure the MSI custom actions are compiled as AnyCPU, not x64-only. |
| Agent installed but no scans appearing in TATER | Almost always one of: (1) outbound HTTPS to api.tatersecurity.com blocked by an SSE/SASE platform doing TLS inspection — see Agent Network Requirements; (2) wrong API key (check config.json); (3) wrong Organization ID (check it starts with org-); (4) the API key was generated in a different organization than the one configured. Check the agent log file for HTTP 401/403 responses to narrow it down. |
| Agent cannot reach API | Verify HTTPS connectivity to api.tatersecurity.com on port 443. Check proxy settings and TLS inspection rules. SSE/SASE platforms typically need a bypass rule for *.tatersecurity.com. |
| Scans not uploading | Check the API key is valid and the Organization ID is correct. Review agent logs in the TATER data directory (%ProgramData%\TATER\Logs on Windows, /Library/Application Support/TATER/Logs on macOS, /var/lib/tater/logs on Linux). |
| Speed test shows 0 Mbps | Verify access to www.tatersecurity.com/Agent/speedtest/. Check for firewall rules blocking large file downloads. |
| Auto-update not working | The agent checks /api/agent/version without auth. Ensure this endpoint is accessible. Check SHA-256 hash match. |
Integrity Repair
If the agent installation becomes corrupted, run the integrity repair script:
# Run from the TATER installation directory
.\Fix-Integrity.ps1
TATER