An OpenWrt package feed for both release lines — apk for 25.12 and later, opkg for 24.10 and earlier — built and published by owfeed.
wget -qO- https://repo.owfeed.org/subscribe.sh | shWorks on either release line: the script reads the router's package manager, architecture and
release, then installs the key, adds the repository and keeps both across a firmware upgrade.
Re-running it changes nothing twice. It installs no packages — apk add <name> after it.
It is generated by owfeed index from the config that laid this feed out, so it cannot document a
URL the feed does not serve. That is not a reason to skip reading it: it runs as root.
wget -O subscribe.sh https://repo.owfeed.org/subscribe.sh && less subscribe.sh && sh subscribe.sh# HTTPS needs these. Stock images have them; custom builds may not.
apk add ca-bundle libustream-mbedtls
wget https://repo.owfeed.org/owfeed-packages.pem -O /etc/apk/keys/owfeed-packages.pem
echo "https://repo.owfeed.org/releases/25.12/$(cat /etc/apk/arch)/packages.adb" > /etc/apk/repositories.d/owfeed-packages.list
# Keep the key and the repository across a firmware upgrade.
mkdir -p /lib/upgrade/keep.d
printf '%s\n' /etc/apk/keys/owfeed-packages.pem /etc/apk/repositories.d/owfeed-packages.list > /lib/upgrade/keep.d/owfeed-packages
apk update && apk add luci-theme-footstrap# The key file's NAME is its id — opkg looks it up by that.
wget https://repo.owfeed.org/9040356b214084da -O /etc/opkg/keys/9040356b214084da
echo "src/gz owfeed-packages https://repo.owfeed.org/releases/24.10/$(. /etc/openwrt_release; echo $DISTRIB_ARCH)" >> /etc/opkg/customfeeds.conf
# Keep the key and the repository across a firmware upgrade.
mkdir -p /lib/upgrade/keep.d
printf '%s\n' /etc/opkg/keys/9040356b214084da /etc/opkg/customfeeds.conf > /lib/upgrade/keep.d/owfeed-packages
opkg update && opkg install luci-theme-footstrapDo not install the package file directly. On 25.12
apk add ./file.apkwrites a pin on the package's content hash into/etc/apk/world, and that file survives sysupgrade — the package would never upgrade from this feed again. Add the repository and install by name.
Attended Sysupgrade will not carry these packages across.
owutforwards no custom repositories, and the sysupgrade server'srepository_allow_listis empty by default, which denies everything.
Installing the key trusts this feed for every package name. It validates an index claiming any name at all, so this feed could offer a higher version of a base package and win. Install it because you trust who publishes it.
This feed signs the index. It does not sign the packages.
That distinction is the whole of what its signature claims. apk takes its trust from the index: the index is signed, and every package is checked against the hash recorded in it. Signing the index is therefore what makes the feed installable at all, and it cannot be avoided — the authors' keys cannot do it, because only this feed can produce an index describing everything this feed carries.
Signing each package as well would put this feed's signature inside a file somebody else built. That would be a claim about an artifact rather than about the channel that carried it, and this feed does not make it. It did not write these packages and does not review them.
A package that arrives already signed by its author keeps that signature — apk signature blocks are additive and nothing here strips them. What you install is the author's file, distributed through a signed channel.
Two keys are involved because each package manager verifies only its own scheme: apk checks EC prime256v1, opkg checks usign. Both sign indexes.
One consequence, stated plainly:
apk add ./file.apkand LuCI's Upload Package need--allow-untrustedfor packages from here. That is the same position OpenWrt itself is in — its own 25.12 packages are unsigned individually, so that path already requires the flag for everything in the official feeds. Installing by name out of the index, which is the documented way and the only one that upgrades, is unaffected.
So the question is what this feed checked before it signed. The answer is narrow, and it is worth being exact about, because the signature is easy to read as a broader claim than it is.
- The release exists at the repository and tag pinned in
packages/<name>/upstream.sh. - The author's detached signature over it verifies against a public key pinned in
keys/, and the manifest names the repository and tag it claims to be from. - The bytes match the
sha256recorded here, so they have not changed since a person looked. - The resulting tree is internally coherent (
owfeed doctor) and installs on a stock OpenWrt image without--allow-untrusted(owfeed smoke).
- What the code does. No review, no audit, no analysis — of the source or of the binary.
- Whether it is safe. No security assessment of any package, its dependencies, or what it does once running.
- Whether it works, or is fit for anything.
smokeproves a package installs. It says nothing about whether it does what its author says. - Whether it is lawful where you are. Software legal in one country is not in another, and this feed makes no assessment of any jurisdiction, including yours.
- Whether its declared licence, description or metadata are true. Those are the author's assertions, carried through unchanged.
The feed's signature therefore means exactly one thing: these are the bytes this feed published, and they came from the author whose key is pinned here. It is a statement about the channel and about provenance. It is not a statement about content, quality, safety, legality or suitability, and it must not be read as one.
Nothing in this repository is rebuilt or modified. What is distributed is the author's own file, byte for byte.
The packages are other people's software. This feed did not write any of it, does not review it, and has no knowledge of what any package does beyond what its author declares. Everything is distributed as-is, with no warranty of any kind — the same terms every package's own licence already states.
Responsibility for a package rests entirely with its author — its contents, its behaviour,
its security, its lawfulness, and the truth of everything it declares about itself. The author's
repository is in the package metadata and readable on the router with apk info <name>. Questions,
bug reports and complaints about a package go to them, not here.
If you install something from this feed, you are deciding to run software written by a third party that neither you nor this feed has audited. That decision is yours, and the consequences of it are yours.
If you believe something here is unlawful or infringes your rights, see SECURITY.md for where to send that; it is acted on rather than argued with.
Putting a key in /etc/apk/keys trusts it for every package name, not only the ones above. A
feed whose key is compromised can offer a higher version of dropbear or base-files and win the
resolution, and apk has no revocation — no CRL, no expiry, no way to say a key is dead.
Install it because you trust who publishes it, not because a page told you to.
An hourly job asks each upstream for its latest release. When one appears it opens a pull request containing a version and its checksums, recomputed from the bytes the release actually served — and nothing else. CI then builds the feed, indexes it, checks it and installs it on a real OpenWrt image before it can be merged.
It proposes; it does not publish. A job that fetched whatever an upstream pushed in the last hour and signed it with this feed's key would be handing that key's authority to every upstream, and would make the checksum pins decoration: recomputed from whatever arrived, they would attest to nothing.
Where an upstream publishes a detached signature beside its artifact, that is provenance from
someone other than this feed, and the package may set AUTO_MERGE="yes" so the pull request merges
itself once the checks pass. The checks still have to pass.
Every package here declares its licence and its upstream, and both travel into the index and into
apk info on the router — a user can always find out whose software they installed.
Where a package is copyleft, its corresponding source is served from this feed, at
/sources/ — the same origin as the binary, which is
what GPLv2 §3 asks of anyone distributing one. A copyleft package with no source in the tree fails
the publish, so this is a gate rather than an intention.
Redistributing someone else's work needs more than a licence that allows it, and LEGAL.md is where this feed writes down what it read and what it decided. (Русский)
Start with the cookbook if you have not published a package before — it covers building and signing one, which is what has to happen before this feed can carry it. (Русский)
A package here is a file of values — a version, its checksums, which key signs it. There is no per-package script.
- CONTRIBUTING.md — adding a package, updating one, letting it update itself (Русский)
- RUNBOOK.md — what runs when, and what to do when something is red (Русский)
Pull requests run the whole pipeline with a throwaway key, so a fork never comes near the feed's own.
This feed is one end of a longer lifecycle: owlab is where a package is developed and proven to work, owfeed is where it is signed and indexed, and this repository decides whose keys it trusts and hands the result to routers. ECOSYSTEM.md is where the boundary between the three is written down — including why nothing is ever built here. STATUS.md says how much of this feed's side of it exists, and what is still open.