Scanners
Scanners are stateless Go binaries deployed on customer networks that execute port scans. This page lets you provision new scanners, manage their lifecycle (enable/disable/delete), configure IP binding for security, and regenerate provisioning tokens. Each scanner connects to mipo via a one-time curl command generated during provisioning.
Inputs
| Name | Description | Allowed values | Default |
|---|---|---|---|
Name | Unique label identifying this scanner | Alphanumeric and hyphens only, must be unique | — |
Description | Optional free-text note about the scanner | Any text, max 10,000 characters | Empty |
Binding Mode | Restricts which source IP the scanner can connect from | ip, subnet, asn, or none | none |
Rate Limit | Maximum probes per second this scanner can fire, reflecting its hardware capacity | Integer 0–100,000 | 0 (unlimited) |
Fields & columns
| Name | Description |
|---|---|
Name | Editable inline — the scanner label |
Description | Editable inline — optional note |
Status | Pending (not yet registered), Active (sending heartbeats), Offline (no heartbeat for 2+ min), or Disabled (manually stopped) |
Binding | IP/subnet/ASN restriction for this scanner. Yellow badge shows IP mismatch count. |
Created By | User who provisioned this scanner |
Rate Limit | Editable inline — max probes per second, or "—" if unlimited |
Created | Date the scanner was provisioned |
How to
Provision a New Scanner
- Click "Add Scanner" and fill in the name.
- Copy the one-time curl command from the modal.
- Run the curl command on the target server to register the scanner binary.
- The scanner status will change from Pending to Active once it sends its first heartbeat.
Configure IP Binding
- Open the row actions menu and click "Configure Binding".
- Choose a binding mode (IP, Subnet, or ASN).
- Enter the allowed value and save.
- Connections from non-matching IPs will be flagged with a yellow mismatch badge.
Troubleshoot an Offline Scanner
- Check that the scanner process is running on the target server.
- Verify network connectivity between the scanner and the ingest endpoint (port 443).
- Check scanner logs for connection errors or authentication failures.
- Confirm the scanner API key has not been revoked in Config > Scanners.
- If the scanner was recently re-provisioned, ensure it is using the new API key.
Rotate an API key without interrupting in-flight scans
- Open the row actions menu for the active scanner.
- Click "Rotate API Key".
- In the modal, click "Rotate Key" to confirm.
- Copy the new key from the success screen — it is shown only once.
- Update the scanner host's MIPO_API_KEY env var (or /etc/mipo-scanner.env in a production install) and restart the scanner process within 24 hours. The previous key keeps working until then.
- After 24 hours the previous key stops authenticating; any scanner still using it will start logging auth failures and show as Offline.
Gotchas
- Regenerating a token invalidates the previous one — the scanner must be re-provisioned with the new curl command.
- Disabling a scanner prevents it from receiving new scan assignments but does not kill in-progress scans.
- A scanner marked Offline has simply missed heartbeats; it may still be running but unable to reach mipo.
- Rate limits interact with subnet and port list limits — the most restrictive (lowest non-zero) value wins. When scanners share a subnet via a scanner group, the subnet rate is divided equally among them.
- Rotate Key (24h grace) is different from Regenerate Token (immediate kill). Use Rotate Key for proactive rotation; use Regenerate Token only when you suspect a compromise and need the old key to stop working right now.
- The new key from a rotation is shown exactly once. If you lose it before deploying it to the scanner, you must rotate again — there is no read-back path by design.
API calls (18)
| Method | Path | Description |
|---|---|---|
| GET | /api/config/scanners | List all scanners |
| POST | /api/config/scanners | Create a new scanner |
| PUT | /api/config/scanners/:id | Update scanner name or description |
| PATCH | /api/config/scanners/:id | Update scanner binding |
| DELETE | /api/config/scanners/:id | Delete a scanner and revoke its access |
| GET | /api/config/scanners/:id/binding | Get scanner binding details |
| POST | /api/config/scanners/:id/release-binding | Release scanner IP binding |
| POST | /api/config/scanners/:id/disable | Disable a scanner |
| POST | /api/config/scanners/:id/enable | Enable a disabled scanner |
| POST | /api/config/scanners/:id/regenerate-token | Regenerate provisioning token |
| POST | /api/config/scanners/:id/rotate-key | Rotate API key with a 24h grace window. The previous key continues to authenticate for 24 hours so in-flight scans do not fail. Returns the new key once. Use regenerate-token for compromise scenarios where the old key must be killed immediately. |
| GET | /api/config/scanners/binary-hash | Get the current scanner binary hash |
| GET | /api/config/scanners/install-script-preview | Preview the scanner install script |
| GET | /api/config/scanners/source-code | Get scanner source code for review |
| GET | /api/config/scanners/:id | Get single scanner configuration |
| GET | /api/config/scanners/filter-values | Get available filter values for the scanners table |
| POST | /scanner/register | Ingest API — exchange a one-time provisioning token for a permanent API key. Body: { provisioningToken, hostname?, osInfo?, internalIp? }. Tokens are short-lived (1 hour) and single-use. Returns the API key once — it is never shown again. |
| GET | /scanner/install.sh | Ingest API — serves the static shell install script (no auth required to fetch; integrity via the X-Mipo-Sha256 header). Download it, then run with sudo MIPO_MANAGER_URL=… MIPO_PROVISIONING_TOKEN=… MIPO_BINARY_PATH=./mipo-scanner bash install.sh (or --token <provisioning-token>); the script then registers the scanner and installs a systemd service. The token is supplied via the environment at run time, not embedded in the file. |
Related
- Scanner Groups — Organize scanners into groups for distributed scanning
- Subnets — Scanners are assigned to subnets to define which networks they scan
- Recent Scans — View scan progress and results from scanner executions
- Scanner Health — Real-time health and heartbeat status for registered scanners
- Settings — Public URL setting affects scanner provisioning commands
- Scanner ACL — Exports firewall rules based on registered scanner IPs
- Discovery — Discovery lists are assigned to scanners for execution
- Scanner Binary — Build and deploy the scanner binary before provisioning
- Scanner Heartbeat — Heartbeat and result submission protocol used by scanners
- Scanner Job Dispatch — Pull-based job protocol by which scanners receive scan assignments
- Resource Limits — MAX_SCANNERS cap applies to the total number of registered scanners
- Rate Limit Hierarchy — Scanner rate limits participate in the three-level slowest-wins calculation
- Job Errors — Active job error states per scanner — Active Errors column links here