Skip to content

Sites & Controllers

Sites are the geographic or logical groupings that scope every page in FreeSDN. Controllers are the vendor devices - network switches, firewalls, PBX systems, hypervisors, NVRs - that FreeSDN reads from (and, with explicit operator approval, writes to). You set up sites first, then attach credentials, then register controllers against those credentials. The rest of the platform flows from that foundation.

This page covers the full workflow in order: create a site, store its credentials, add a controller, pick an adapter, and understand what the sync cycle actually does.


Every API query, every dashboard widget, every alert, every audit log in FreeSDN carries a site_id. The global Site selector in the top bar scopes the entire UI to one site at a time. Pages that aggregate across sites (Users, Organizations, Notification Providers) are only visible when you select All Sites.

A site can represent a physical location, a customer, a branch office, or any logical boundary that makes sense for your operation. FreeSDN is multi-tenant at the organization level and multi-site within each organization.


Navigate to Overview → Sites in the sidebar, or go directly to /sites/. The Sites page follows the canonical list-page pattern: a stats header, a toolbar with search and filter, a table of existing sites, and a Create Site button.

To create a site:

  1. Click Create Site (top-right of the toolbar).

  2. Fill in the required fields in the dialog:

    FieldRequiredNotes
    NameYesShown in the Site selector and every scoped page
    SlugYesURL-safe identifier; auto-generated from the name
    CityNoShown in the Site selector search
    CountryNoShown in the Site selector search
    TimezoneNoUsed for scheduled tasks and log display
    DescriptionNoInternal notes
  3. Click Save. The site appears in the list and in the global Site selector immediately.

Once a site exists, select it in the Site selector (top bar, Ctrl+Shift+S / Cmd+Shift+S) to scope the dashboard to it. The sidebar reveals site-only items such as Topology and Discovery.

Click a site row or navigate to /sites/{siteId}/ to open the site detail view. Tabs:

TabWhat you see
OverviewDevice count, health summary, registered controllers
NetworkSubnets associated with the site
VPNSite-to-site VPN status
AgentAgents registered to this site
DevicesDevice inventory scoped to the site
SettingsEdit site metadata; toggle auto-adopt for discovered devices

The Settings tab has an auto-adopt toggle. When on, high-confidence device discoveries (matching driver fingerprints) are adopted automatically into the managed inventory. Leave it off if you prefer to review discoveries manually before adopting.


Before you can add a controller, you need a stored credential. Credentials are encrypted at rest (Fernet encryption) and are never returned in plaintext after creation - you can update them but you cannot read the secret back.

Navigate to Administration → Credentials (/credentials/). This page is gated by the settings:read permission.

  1. Click Add Credential.

  2. Choose the Type. The form adjusts to show the fields that type requires:

    TypeFields
    Username / Passwordusername, password
    API Keykey (+ optional header name)
    Tokentoken string
    Certificatecert + key (PEM)
    SNMP v2ccommunity string
    SNMP v3auth protocol, auth key, priv protocol, priv key
    OAuth2client_id, client_secret, token URL
    SSH Keyprivate key (PEM), optional passphrase
  3. Give it a descriptive Name - you reference this name when adding a controller, and it appears in audit logs.

  4. Optionally enter a Target Host and click Test to verify the credential resolves before saving.

  5. Click Save.

On subsequent edits, leave secret fields blank to keep the existing value. Fill them in only if you are rotating the credential.


With a site and credential in hand, navigate to Administration → Controllers (/controllers/). The Controllers page lists every registered controller across all sites - network controllers (Omada, UniFi), firewall/gateway controllers (OPNsense, pfSense, MikroTik, OpenWrt), camera NVRs (Hikvision, ONVIF, UniFi Protect), VoIP PBX systems (FreePBX, Grandstream), hypervisors (Proxmox), and storage appliances (TrueNAS).

Click Add Controller to open the add wizard.

Step 1 - Select vendor / adapter

Choose from the registered adapter list. The adapter determines which fields appear next and what the controller can do:

AdapterModule(s)Write-capableNotes
OmadaNetworkYes (staged)Gold-standard network adapter
UniFiNetworkPartialSkeleton adapter; some features incomplete
OPNsenseFirewallYes (staged)Production adapter; ; 13 domains
pfSenseFirewallYes (staged)Production adapter
MikroTik (RouterOS v7)FirewallYes (staged)Production adapter
OpenWrtFirewallYes (staged, unverified)Preview - unaudited; do not use in production fleets
HikvisionCamerasYes (staged)ISAPI;
ONVIFCamerasYes (direct, no staging gate)Generic shim;
UniFi ProtectCamerasNo (read-only: discovery, streaming, snapshots)
FreePBXVoIPYes (staged)Beta; AMI + ARI + REST;
GrandstreamVoIPYes (staged)
ProxmoxCompute / HypervisorYes (staged)
TrueNASStorageRead-onlyWS JSON-RPC; no write surface

See /discovery/drivers for the full read-only adapter registry including per-adapter maturity ratings.

Step 2 - Connection details

Fill in the fields specific to the adapter. Common fields:

FieldNotes
NameDisplay name in the Controllers list
SiteWhich FreeSDN site this controller belongs to
Host / URLIP address or hostname; do not append the path
PortDefaults vary by adapter
CredentialSelect the credential you stored earlier
Use SSL / Verify SSLPer-adapter; check your vendor’s docs

Some adapters have additional fields:

  • Omada - choose Local or Cloud connection mode. Cloud mode requires client_id, client_secret, omada_id, and region. Local mode uses host + credential.
  • Proxmox - node address; multiple nodes in the same cluster share one controller record.
  • TrueNAS - WebSocket endpoint; TLS is mandatory (keys auto-revoke on ws://).

Step 3 - Test connection

Click Test Connection. FreeSDN sends a probe to the controller using the adapter’s auth flow and reports success or an error. Fix any issues before proceeding.

Step 4 - Omada site binding (Omada only)

If you selected Omada, an extra sub-step appears: FreeSDN queries the remote Omada controller for its list of sites, then lets you map each remote site to a FreeSDN site. This binding is how Omada’s multi-site architecture aligns with FreeSDN’s site model.

Step 5 - Save

Click Add. The controller appears in the list with a status badge. The first sync runs automatically in the background.


This means you can safely register any controller and explore all read surfaces - device inventory, VLAN state, firewall rules, VPN tunnels - without risk of accidentally modifying the live device.

All UI-authored mutations (network config, firewall rules, VPN, gateway routing, etc.) go into a staging queue. Review the queue at Gateway → Pending Changes (/gateway/pending/). The page shows every queued operation with its type, target, and payload. From there you can:

  • Discard a staged change (removes it from the queue, no effect on the device)
  • Force-apply a change (executes the mutation on the live controller - requires ADAPTER_READ_ONLY=false)

After a controller is registered, FreeSDN keeps its local inventory current through a background sync cycle driven by Celery beat tasks.

  1. Credential auth - the adapter authenticates using the stored credential (re-auth on expiry, token-version-aware).
  2. Read from the controller - the adapter fetches the current state of devices, interfaces, VLANs, clients, and other resources the adapter covers.
  3. Secret redaction - the central redact_secrets filter (~90 sensitive key patterns, camelCase-aware) strips credentials, PSKs, RADIUS secrets, LDAP passwords, and similar values before anything is written to the database or served to the UI.
  4. Upsert into the database - new records are created; existing records are updated; records no longer seen on the controller are flagged offline.
  5. Event emission - device-state changes emit events on the internal event bus, which trigger WebSocket pushes to connected browser sessions and can fire automation rules.

The default sync interval is set in the Celery beat schedule. You can trigger an immediate sync from the controller detail page:

  1. Navigate to /controllers/.
  2. Click the controller row to open its detail page.
  3. Click Sync Now in the toolbar.

A sync progress indicator appears while the task runs. The controller’s Last Sync timestamp updates on completion.

If authentication fails or the controller is unreachable, the controller’s status badge turns red and a sync error appears in the controller detail. Common causes:

SymptomLikely cause
401 / authentication failureCredential rotated on the vendor side; update the credential record
Connection refused / timeoutHost or port is wrong; firewall blocking FreeSDN server egress
SSL certificate errorWrong SSL mode selected, or self-signed cert not trusted
Omada cloud: 403client_id / client_secret / omada_id expired or wrong region

Check Administration → System Logs (/logs/) for the full adapter error trace.


Navigate to /controllers/{id}/ to open the controller detail. Tabs vary by adapter type but typically include:

TabWhat you see
OverviewStatus, last sync time, discovered device count, adapter metadata
DevicesDevices imported from this controller
Sync LogPer-sync history with success/failure and record counts
SettingsEdit host, port, credential, SSL mode; delete the controller

For storage controllers (TrueNAS), the overview proxies live ZFS pool health, alerts, disk temperatures, and redundancy status via GET /controllers/{id}/storage.


ActionRequired permission
View sites listsettings:read or any authenticated user
Create / edit / delete sitessettings:admin or site_admin role at the target site
View credentials listsettings:read
Create / edit / delete credentialssettings:write
View controllers listcontroller:read
Add a controllercontroller:create
Edit a controllercontroller:update
Delete a controllercontroller:delete
Trigger manual synccontroller:update
Force-apply a staged changeFeature-scoped permission (e.g. vpn:write, network:write, firewall:write, controller:write, hypervisor:write) + ADAPTER_READ_ONLY=false; catastrophic features (VM destroy, node shutdown, firmware upgrade, factory reset, config restore, etc.) additionally require minimum site_admin role

The 7-tier role hierarchy is: super_admin (100) > admin (80) > org_admin (60) > site_admin (40) > operator (20) > viewer (10) > guest (0). A viewer can browse synced data but cannot modify sites, credentials, or controllers, and cannot apply staged changes.


These are the endpoints the UI calls; useful for automation and scripting.

MethodPathPurpose
GET/api/v1/sitesList sites (org-scoped)
POST/api/v1/sitesCreate a site
PATCH/api/v1/sites/{id}Update site metadata
DELETE/api/v1/sites/{id}Delete a site
GET/api/v1/credentialsList credentials (secrets masked)
POST/api/v1/credentialsCreate a credential
PUT/api/v1/credentials/{id}Update (leave secret blank to keep existing)
GET/api/v1/controllersList controllers
POST/api/v1/controllersRegister a controller
POST/api/v1/controllers/{id}/syncTrigger immediate sync
GET/api/v1/controllers/{id}/storageTrueNAS health proxy (read-only)
GET/api/v1/discovery/driversRead-only adapter registry

The full OpenAPI spec is at /api/v1/docs (Swagger) and /api/v1/redoc (ReDoc). Both are disabled whenever ENVIRONMENT=production, regardless of ENABLE_DOCS. To access the OpenAPI spec, run in a non-production environment (e.g. ENVIRONMENT=development) with ENABLE_DOCS=true.


  1. The setup wizard creates a default site automatically. Use it.
  2. Add credentials for your controller (Omada, OPNsense, Proxmox, etc.).
  3. Add the controller and select the default site.
  4. Leave ADAPTER_READ_ONLY unset - browse read-only until you are comfortable.
  1. Create one site per physical location in /sites/.
  2. Store credentials per site (or share a credential if the same admin account covers multiple controllers).
  3. Add each controller and bind it to its site.
  4. Use the global Site selector to switch context; use All Sites for cross-site views like Analytics and Health.
  1. Create credentials with client_id, client_secret, omada_id, and region from the Omada Cloud portal.
  2. Add a controller, choose Omada, select Cloud connection mode.
  3. After a successful test connection, the site-binding sub-step appears - map each remote Omada site to a FreeSDN site.
  4. If a remote site has no corresponding FreeSDN site yet, create it first (back in /sites/), then return to the wizard.

  • Discover devices - once a controller syncs, run a network scan from Discovery to fingerprint and adopt devices into the managed inventory.
  • Configure sync frequency and alerting - see Automation & Fabric to fire automation rules when a controller goes offline or a sync fails.
  • Enable write operations - set ADAPTER_READ_ONLY=false in your environment, review the Write Safety reference, then use /gateway/pending/ to force-apply queued changes.
  • Set up agents - for L2/L3 discovery at remote sites without direct controller access, deploy the FreeSDN Agent.
  • Review adapter maturity - check /discovery/drivers and docs/SUPPORTED_VENDORS.md before relying on a less-mature adapter in a production environment.