Upgrade if you are on 0.7.0 or earlier
0.7.0 and every earlier release shipped without authentication. Its API
answered anyone who could reach the port, on a service that queues downloads
and writes into your library. If you installed from a release tarball or the
Proxmox script, you have been running an open install. This release closes
that, and the Proxmox installer now refuses to deploy a build that cannot
authenticate.
Signing in actually works now (#8)
Authentication existed in main but the browser half did not. The UI loaded,
every request it made came back 401, and the log told you to look under
Settings → General — a page behind the same gate. Nothing in the README,
.env.example or docker-compose.yml mentioned a single auth variable, so no
container template could set one.
A fresh install now shows Set your password on first visit. That claims the
install; afterwards it is a normal sign-in backed by a session cookie. Set
ROMARR_PASSWORD (or your own ROMARR_API_KEY) to claim it from the
environment instead and skip the setup screen entirely — which is what a
container template should do. X-Api-Key, Authorization: Bearer, ?apikey=,
forward-auth and TOTP are unchanged.
The Proxmox install command works (#2)
It returned 404. The script sourced community-scripts' build.func, which
resolves install/<app>.sh against its own repository — and ROMarr does not
live there, so nothing we shipped could satisfy it. The installer is now
self-contained, verifies /api/health answers before reporting success, and
every failure path says what to do next. proxmox/ct/update.sh replaces the
update path and preserves romarr.json, .env and your drop-in backends.
Collections — full sets and 1G1R you can inspect
Point ROMarr at a No-Intro or Redump DAT and it reports what a complete set
contains, what you already have, what is missing, and why each dump won its
group — with every discarded regional variant listed and a reason for each.
Change the region order and it re-answers live.
Acquisition is separate and resumable: batches with pause, resume,
retry-failures and cancel, a slice at a time, because a 3,000-title set is not
one all-or-nothing operation and should not monopolise your indexers.
1G1R previously did nothing on the DATs people actually have. Grouping
relied on cloneof, and Redump-style DATs generally declare none — a real
No-Intro GameCube datfile carries exactly one across 1,907 entries. Titles are
now grouped by normalised name where the DAT is silent, the way Igir and
RomVault do. Disc markers survive, because two discs are two things you need.
Manual Import can import
It scanned, identified and verified, then offered nothing to do about any of
it. Each row now has a platform selector and an Import button, plus bulk
import-verified.
UNKNOWN is not BAD. A ROM that is not in your DAT — homebrew, a
translation, a Pokémon hack, anything newer than your DAT — imports with no
override. Only a genuine bad dump (right size, wrong hash) is refused, and
forcing it is a separate confirmed act recorded as forced with the verdict it
overrode. Nothing is ever silently reinterpreted as verified.
Multi-ROM archives and qBittorrent 5.x
- qBittorrent 5.x answers a successful login with
204; ROMarr read that as a
rejection and never imported anything. Both shapes now work — and a failed
login is200 "Fails.", which is pinned so nobody simplifies it away. - An archive holding several cartridge ROMs had all but the best-ranked game
silently dropped. Every game is now imported.
Get Started
Answers the question the product never did: ROMarr acquires, verifies and
files — it is not an emulator and not a launcher. Shows the
Acquire → Verify → File → Scan → Play chain, checks which of your four
dependencies are configured, and says what actually plays a ROM depending on
your library.
Security
SECURITY.md covers the authentication model, filesystem and archive handling,
secret redaction, and the plugin trust boundary — including a section on what
is not protected.
ROM Hub plugins are not sandboxed. Running one runs its author's code as
ROMarr. Plugin subprocesses previously inherited ROMarr's entire environment,
including ROMARR_API_KEY, PROWLARR_API_KEY, QBITTORRENT_PASS and
LIBRARY_PASSWORD; they now get an allowlist.
Fixes found by running against a real 166,578-game library
- The generated API key was never written to disk, so it changed on every
restart and broke any script using it. - Loading DATs walked the entire library: over 600 seconds and never finished,
now 0.1s. - A library whose credentials were rejected reported "connected" while every
read403'd.401/403now says credentials rejected, per library. - Backup, restore and library export shipped with no way to reach them.
/api/v1/system/statusnever reported anything about DATs.
Full test suite: 1,003 green.