openwrt-iac / uapi / docs / 1.2.1 / Installation
A router running OpenWrt 25.12+ (the first apk-based release line). Pulled-in dependencies are all in OpenWrt's base feed: uhttpd, uhttpd-mod-ucode, ucode, and the ucode-mod-{ubus,uci,fs,digest,log} mods. The package's Depends: makes apk resolve them automatically.
Get the package onto the router (any way you like: scp, USB stick, sysupgrade overlay), then:
apk add /path/to/uapi-<version>-r1.apk
The post-install hook will:
/etc/uci-defaults/99-uapi which adds list ucode_prefix '/api/v1=/usr/share/uapi/main.uc' to uhttpd.main and reloads uhttpd.Verify:
curl -k https://localhost/api/v1/healthz
# { "status": "ok", "version": "<version>" }
The project hosts an apk feed at https://raspbeguy.github.io/uapi/. Packages are RSA-4096 signed; the public key lives in the repo at keys/uapi-feed.pub.pem and is also served from the feed itself.
# Trust the feed's signing key (one-time)
curl -fsSL https://raspbeguy.github.io/uapi/uapi-feed.pub.pem \
| tee /etc/apk/keys/uapi-feed.pub.pem > /dev/null
# Register the feed
echo 'https://raspbeguy.github.io/uapi/packages/all/uapi/packages.adb' \
> /etc/apk/repositories.d/uapi.list
apk update
apk add uapi
The feed currently ships pre-release (-rc) packages; expect to upgrade as the project hardens. Until v1.0.0 final, apk add will pull the latest release candidate.
uapi inherits TLS from the main uhttpd instance. By default OpenWrt ships a self-signed certificate (regenerated at first boot via px5g); browsers and curl complain, and over a real network this is not adequate. Two well-trodden options on OpenWrt:
acme.sh + luci-app-acme: ACME (Let's Encrypt) on the router itself. Requires the router to be reachable from the internet on port 80 (or DNS-01 challenge support).uhttpd supports verifying client certificates if you set option tls_client_cert_file (path to a CA cert in PEM form) and option tls_require_client_cert '1' on the listener:
uci set uhttpd.main.tls_client_cert_file='/etc/uapi/clients-ca.pem'
uci set uhttpd.main.tls_require_client_cert='1'
uci commit uhttpd
/etc/init.d/uhttpd restart
After that, every request must present a certificate signed by the CA at /etc/uapi/clients-ca.pem. Combine this with a bearer-token scoped to read-only and you have two-factor service-account auth: the cert proves the caller is approved infrastructure; the token proves what scope it is allowed to exercise. uapi does not look at the client certificate fields itself; uhttpd terminates and validates them.
uapi enforces TLS by default for any request whose REMOTE_ADDR is not loopback:
HTTP/1.1 403 Forbidden
{ "code": "tls_required", ... }
To bypass during testing on a closed network, create the marker file:
touch /etc/uapi.insecure
That is a security hole; don't leave it on a production router.
The package wires only the uhttpd.main instance. If you run additional instances (e.g. a separate admin port), add the prefix manually:
uci add_list uhttpd.<instance>.ucode_prefix='/api/v1=/usr/share/uapi/main.uc'
uci commit uhttpd
/etc/init.d/uhttpd reload
apk del uapi
The pre-remove hook removes the ucode_prefix entry from uhttpd.main and reloads uhttpd. /etc/config/uapi (the token store) is conffile-marked and preserved across removal and upgrades. To wipe tokens: rm /etc/config/uapi after removal.