In daemon mode (etc-collector daemon), the collector runs as a persistent background service that polls the SaaS platform at api.etcsec.com for commands, executes audits, and reports results remotely. An optional local GUI/API server can run alongside.
┌──────────────────────────────────────────────────────────────────┐
│ CLOUD │
│ ┌──────────────────────────────┐ │
│ │ SaaS Platform │ │
│ │ api.etcsec.com │ ← Operator manages from here │
│ └──────────────┬───────────────┘ │
│ ↕ HTTPS (polling every N seconds) │
├──────────────────────────────────────────────────────────────────┤
│ ON-PREMISES / CUSTOMER SITE │
│ ┌────────────────────────────────────────────────┐ │
│ │ etc-collector daemon │ │
│ │ ├── SaaS poll loop (receive commands) │ │
│ │ ├── Audit engine │ │
│ │ ├── Health reporter │ │
│ │ ├── Auto-updater (binary update watcher) │ │
│ │ └── Local GUI/API server (optional :8443) │ │
│ └──────────┬─────────────────┬───────────────────┘ │
│ ↓ LDAP :636 ↓ Graph API :443 │
│ [Active Directory] [Azure Entra ID / Microsoft] │
└──────────────────────────────────────────────────────────────────┘
Enrollment registers this instance with the SaaS platform and stores encrypted credentials locally.
# Basic enrollment
etc-collector enroll YOUR_TOKEN --saas-url https://api.etcsec.com
# With environment variables
export ETCSEC_ENROLL_TOKEN=YOUR_TOKEN
export ETCSEC_SAAS_URL=https://api.etcsec.com
etc-collector enrollThe enrollment token is obtained from the SaaS platform dashboard when creating a new collector.
After enrollment, a credentials file is saved to the config directory (encrypted). The plaintext token is not stored.
# Start in foreground (for testing)
etc-collector daemon
# As a systemd service (production)
sudo systemctl start etcsec-collectoretc-collector statusOutput:
Status: Enrolled
Collector ID: 550e8400-e29b-41d4-a716-446655440000
SaaS URL: https://api.etcsec.com
LDAP: ldaps://dc.example.com:636 (configured)
Azure: not configured
Poll interval: 30s
Credentials: /etc/etc-collector/credentials.json
- Polling: The daemon sends an HTTP request to
{saas-url}/api/collector/pollevery N seconds (default: 30 seconds) - Command processing: The platform responds with a command (e.g.,
RUN_AUDIT,UPDATE_CONFIG,RESTART) - Execution: The daemon runs the requested audit using the locally-configured providers
- Reporting: Results are sent back to the SaaS platform
- Health reporting: The daemon periodically reports uptime, version, and provider status
The local GUI is disabled on network interfaces by default in daemon mode (only 127.0.0.1). This is intentional — the collector sits inside the customer network and the GUI is not always needed.
# Accessible from the local machine only
etc-collector server enable --host 127.0.0.1 --port 8443
# Accessible from the network (internal)
etc-collector server enable --host 0.0.0.0 --port 8443
# Without interactive prompts (scripted)
etc-collector server enable --host 0.0.0.0 --port 8443 --yesetc-collector server disableThe SaaS daemon continues polling — only the local GUI is affected.
In daemon mode, LDAP and Azure configuration can come from:
- SaaS platform — pushed as an
UPDATE_CONFIGcommand (stored encrypted locally) - Local config file —
/etc/etc-collector/config.yaml - CLI flags — override at startup
# Override LDAP from daemon CLI flags
etc-collector daemon \
--ldap-url ldaps://dc.example.com:636 \
--ldap-bind-dn "CN=svc-audit,CN=Users,DC=example,DC=com" \
--ldap-bind-password "P@ssw0rd" \
--ldap-base-dn "DC=example,DC=com"In daemon mode, the collector can update itself when a new version is pushed from the SaaS platform:
- SaaS sends an
UPDATE_BINARYcommand with download URL + checksum - Daemon downloads the new binary to a staging directory
- A watcher subprocess (
update watch) takes over: waits for the parent to exit - Parent exits
- Watcher replaces the binary and restarts the service
- On Linux:
restoreconis called automatically if SELinux is detected
The daemon is designed for deploying one collector per AD site/domain:
SaaS Platform
├── Site A — Collector (daemon on server-a.contoso.com)
│ └── contoso.com AD domain
├── Site B — Collector (daemon on server-b.fabrikam.local)
│ └── fabrikam.local AD domain
└── Azure — Collector (daemon on azure-collector.example.com)
└── Azure Entra ID tenant
Each collector is enrolled independently and managed from the SaaS dashboard.
etc-collector unenrollThis:
- Notifies the SaaS platform (best-effort)
- Deletes local credentials
- The daemon will fail at next startup (not enrolled)
| Flag | Default | Description |
|---|---|---|
--config-dir |
/etc/etc-collector |
Directory containing credentials.json |
--ldap-url |
(from SaaS config) | Override LDAP URL |
--ldap-bind-dn |
(from SaaS config) | Override LDAP bind DN |
--ldap-bind-password |
(from SaaS config) | Override LDAP password |
--ldap-base-dn |
(from SaaS config) | Override base DN |
--ldap-tls-verify |
true |
Override TLS verification |
--gui-port |
8443 |
Local GUI port (0 = disabled) |
--gui-host |
127.0.0.1 |
Local GUI listen address |