Newer
Older
openstack-caracal-dc-dc / docs / changelog-20260713-opnsense-api-proven.md

2026-07-13 -- D-113(a2) PROVEN: the OPNsense REST API round-trips the edge config

The API path adopted in D-113 (option a2) is now demonstrated working against the LIVE Office1 edge. This closes the open question that gated the ruling.

Bootstrap (the one manual step, by design)

An API key was minted for root in the GUI. In OPNsense 26.1 this is NOT in the user-edit dialog and NOT in the ApiKeys tab (that tab only wires search_api_key + del_api_key -- it can list and delete, but CANNOT create). It is a row action on the Users list: the fa-ticket icon, "Create and download API key for this user" (source: mvc/app/views/OPNsense/Auth/user.volt). Earlier instructions in this repo referencing "edit user -> API keys -> +" describe the OLD UI and are wrong for 26.1.

ApiKeyField::add() mints key and secret as base64(random_bytes(60)) (80 chars each) and persists key|crypt(secret,'$6$') -- the secret is shown exactly once and is stored hashed. Lose it and you delete the key and mint a new one.

Key stored at ~/vr1-office1-creds/opnsense-api.txt (0600, operator-only, never read into agent context). SEC-007 amended to cover it.

Measured, against the live edge

GET  core/firmware/status      -> HTTP 200, OPNsense 26.1 (auth works)
GET  kea/dhcpv4/get            -> dhcpv4.general.enabled = 1, interfaces = lan
POST kea/dhcpv4/search_subnet  -> 1 row:

    subnet                          = 10.10.0.0/24
    pools                           = 10.10.0.100-10.10.0.199
    option_data.routers             = 10.10.0.1
    option_data.domain_name_servers = 10.10.0.1
    option_data.domain_name         = office1.vr1.cloud.neumatrix.local
    description                     = LAN DHCP

The API reads back EXACTLY the config we pushed via config.xml yesterday -- and exposes it as TYPED, NAMED FIELDS (option_data.routers, pools, ...), not free-form XML. That is the whole (a2) argument, concretely: DOCFIX-191 (missing sshd), DOCFIX-192 (silenced console) and DOCFIX-193 (an inert ISC <dhcpd> block against a Kea backend) are not expressible here. You cannot omit a typed field that has a default, and you cannot address the wrong DHCP backend when the endpoint IS the backend.

Endpoint map (measured from Dhcpv4Controller.php, not guessed)

get | searchSubnet | getSubnet | addSubnet | setSubnet | delSubnet
searchReservation | getReservation | addReservation | setReservation | delReservation
downloadReservations | uploadReservations | searchPeer | ... | delPeer

Note OPNsense maps camelCase actions to snake_case URLs: searchSubnetAction -> POST /api/kea/dhcpv4/search_subnet. Response root key is dhcpv4 (NOT dhcp4 -- the config XML element name differs from the API key name; do not infer one from the other).

NOT done yet

  • No WRITE has been performed through the API. Read is proven; the write path (setSubnet + a reconfigure) is a live mutation and remains gated.
  • The config.xml template is still in place. It should now be reduced to a MINIMAL bootstrap (sshd + root key + console + nothing else), with DHCP/firewall/interfaces moving to the API. Until that lands, DO NOT push a full rendered config.xml -- it would clobber API-managed state.

Revert

Nothing to revert: this change is read-only against the edge plus documentation. To revoke the credential: OPNsense GUI -> System > Access > Users > root row > ApiKeys tab -> delete, then rm ~/vr1-office1-creds/opnsense-api.txt.