uci already gave OpenWrt the rarest thing in the embedded-Linux world: a single, stable config interface every daemon speaks. What it doesn't give you is a way to drive it from outside the box. This org closes the gap, without forking OpenWrt.
All projects MIT-licensed - signed APK feed - signed tags - OpenWrt 25.12 +
OpenWrt has a property few other systems have. Every long-lived
daemon (network, firewall, dhcp, wireless, dropbear, uhttpd, unbound,
sqm, snmpd, lldpd, ...) reads its config from the same place
(/etc/config/) through the same library
(libuci), reloads via the same procd
triggers, and exposes the same shape (typed sections, named or
anonymous, with options and lists). LuCI, command-line operators,
and on-box scripts all share one ABI. That's the foundation we
build on.
What that foundation is missing, for any IaC tool that wants to drive the box from somewhere else:
terraform apply from a CI runner you need HTTP, auth, TLS, and a stable wire schema.firewall + network in one logical operation needs one transaction; uci's per-package commit doesn't span that.cfg01a2b3) renumber on rewrite, which kills Terraform-style state.interface:) are deliberately kept out of uci by their package maintainers, leaving operators with hand-edited extension-config files that no IaC tool can touch.Each of those gaps is solvable without changing the daemon, the kernel, or upstream uci itself. The work is to land precise pieces that close one gap each, ship them as standard OpenWrt apk packages, and keep them inside the existing system's grain.
Native, zero-footprint REST API. Runs inside the existing uhttpd process via ucode (no daemon to supervise). Translates HTTP verbs into uci/ubus calls. Atomic transactions with snapshot-rollback, per-package locks, optimistic concurrency via ETags + If-Match, bearer tokens with hierarchical scopes, idempotency keys, signed releases with SPDX SBOM. 34 curated resources at 2.1 plus a generic raw passthrough for the long tail.
unbound's interface:, outgoing-interface:,
and friends are deliberately kept out of upstream's uci because
users are expected to hand-edit
/etc/unbound/unbound_srv.conf. This package exposes
those (plus a verbatim passthrough for anything else) as uci so
the rest of the toolchain (including uapi + Terraform) can
drive them. Generator writes managed regions into the seam
files and restarts unbound only when content actually changed.
Reference IaC client. Drives every uapi endpoint, honours ETags for drift detection, uses the same scope tree for least-privilege tokens. Lives in its own repo on Terraform Registry with its own version cadence; uapi's wire surface was shaped around what this provider needs.
Use ucode, uhttpd, ubus, uci, procd, apk-tools the way OpenWrt intends. No parallel-universe daemon, no replacement init, no shadow config tree. If our project requires you to disable a standard OpenWrt piece to make ours work, the design is wrong.
Target hardware is 32MB-RAM SoHo routers. Runtime overhead, memory, and storage stay close to zero. uapi runs inside an existing process and adds no idle cost. Extension packages are shell + uci, no compiled code.
We don't fork the unbound package because it doesn't surface a field we want; we ship an extension package alongside it. We don't fork netifd because a resource doesn't exist; we curate it through uapi. Upstream stays upstream.
GPG-signed git tags. Signed APK feed (RSA-4096, key rotated publicly when needed). Reproducible builds across target arches (PKGARCH:=all where possible). SPDX SBOM attached to each release. Multi-arch CI verifies the package works on every target SDK we ship for.
curl -fsSL https://openwrt-iac.github.io/feed/uapi-feed.pub.pem \
| tee /etc/apk/keys/uapi-feed.pub.pem > /dev/null
echo 'https://openwrt-iac.github.io/feed/packages/all/uapi/packages.adb' \
> /etc/apk/repositories.d/uapi.list
apk update
apk add uapi # HTTP control plane
apk add unbound-uci-ext # if you run unbound
One feed line, every openwrt-iac package. See /uapi/install/ for the full install + first-token walkthrough.
The bar for a new project under this org: it closes a real IaC gap for a real OpenWrt setup, stays inside the design constraints above, and is willing to live as a separate signed-and-released apk in this feed. New extension packages are particularly welcome where upstream OpenWrt has a deliberate uci gap that's costing operators hand-edits.
To get a package into the apk feed: open a PR against
openwrt-iac/openwrt-iac.github.io's
feed.yml with a one-line entry pointing at your source
repo. Requirements + release expectations are in that repo's
README.
openwrt-iac is not affiliated with the OpenWrt project or its maintainers. It started as the work of a single operator solving a specific problem on their own network, shared in the open in the hope it is useful to others with similar needs. OpenWrt is a trademark of its respective owners.