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:

    Field Required Notes
    Name Yes Shown in the Site selector and every scoped page
    Slug Yes URL-safe identifier; auto-generated from the name
    City No Shown in the Site selector search
    Country No Shown in the Site selector search
    Timezone No Used for scheduled tasks and log display
    Description No Internal 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:

Tab What you see
Overview Device count, health summary, registered controllers
Network Subnets associated with the site
VPN Site-to-site VPN status
Agent Agents registered to this site
Devices Device inventory scoped to the site
Settings Edit 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:

    Type Fields
    Username / Password username, password
    API Key key (+ optional header name)
    Token token string
    Certificate cert + key (PEM)
    SNMP v2c community string
    SNMP v3 auth protocol, auth key, priv protocol, priv key
    OAuth2 client_id, client_secret, token URL
    SSH Key private 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), 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:

Adapter Module(s) Write-capable Notes
Omada Network Yes (staged) Gold-standard network adapter
UniFi Network Partial Skeleton adapter; some features incomplete
OPNsense Firewall Yes (staged) Production adapter; ; 13 domains
pfSense Firewall Yes (staged) Production adapter
MikroTik (RouterOS v7) Firewall Yes (staged) Production adapter
OpenWrt Firewall Yes (staged, unverified) Preview - unaudited; do not use in production fleets
Hikvision Cameras Yes (staged) ISAPI;
ONVIF Cameras Yes (direct, no staging gate) Generic shim;
FreePBX VoIP Yes (staged) Beta; AMI + ARI + REST;
Grandstream VoIP Yes (staged)
Proxmox Compute / Hypervisor Yes (staged)
TrueNAS Storage Read-only WS 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:

Field Notes
Name Display name in the Controllers list
Site Which FreeSDN site this controller belongs to
Host / URL IP address or hostname; do not append the path
Port Defaults vary by adapter
Credential Select the credential you stored earlier
Use SSL / Verify SSL Per-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:

Symptom Likely cause
401 / authentication failure Credential rotated on the vendor side; update the credential record
Connection refused / timeout Host or port is wrong; firewall blocking FreeSDN server egress
SSL certificate error Wrong SSL mode selected, or self-signed cert not trusted
Omada cloud: 403 client_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:

Tab What you see
Overview Status, last sync time, discovered device count, adapter metadata
Devices Devices imported from this controller
Sync Log Per-sync history with success/failure and record counts
Settings Edit 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.


Action Required permission
View sites list settings:read or any authenticated user
Create / edit / delete sites settings:admin or site_admin role at the target site
View credentials list settings:read
Create / edit / delete credentials settings:write
View controllers list controller:read
Add a controller controller:create
Edit a controller controller:update
Delete a controller controller:delete
Trigger manual sync controller:update
Force-apply a staged change Feature-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 5-tier role hierarchy is: super_admin (100) > org_admin (60) > site_admin (40) > operator (20) > viewer (10). 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.

Method Path Purpose
GET /api/v1/sites List sites (org-scoped)
POST /api/v1/sites Create a site
PATCH /api/v1/sites/{id} Update site metadata
DELETE /api/v1/sites/{id} Delete a site
GET /api/v1/credentials List credentials (secrets masked)
POST /api/v1/credentials Create a credential
PUT /api/v1/credentials/{id} Update (leave secret blank to keep existing)
GET /api/v1/controllers List controllers
POST /api/v1/controllers Register a controller
POST /api/v1/controllers/{id}/sync Trigger immediate sync
GET /api/v1/controllers/{id}/storage TrueNAS health proxy (read-only)
GET /api/v1/discovery/drivers Read-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.

All product names, logos, and brands are property of their respective owners. FreeSDN is an independent project and is not affiliated with or endorsed by the vendors it integrates with. See Trademarks.