Turn it on
There is no polling loop. The feed is read when something asks for it (the dashboard, the CLI or the attention feed), and matches are recomputed only when the feed or the set of running images changes.
Signatures
With a public key configured, the signature is read from the feed location plus.sig and is the base64 of an ed25519 signature over the exact feed bytes. A missing or wrong signature rejects the whole feed and shows invalid.
A feed fetched from an http(s) URL needs the key: without APP_ADVISORY_FEED_PUBKEY it is rejected and shown as invalid.
Without a key a local file feed is labelled unsigned in the dashboard, the CLI and the API. It is still used, because you chose the source, but it is never presented as verified.
Format
versionmust be1.severityiscritical,high,mediumorlow.idis unique in the feed.- Each
affecteditem needs arepositoryand at least one ofdigests,tagsorranges, so an entry can never match a whole repository by accident. - Repositories compare after removing
docker.io/andlibrary/, sonodeanddocker.io/library/nodeare the same. - A range covers
from(inclusive, optional) up tobefore(exclusive). Tags are read by their leading dotted number, so20.2.1-alpineis20.2.1. Tags that are not versions only match throughtags. - A digest matches when the app’s last successful deploy resolved to that registry digest. Local builds have no registry digest and match by tag or range only.
Where it shows
- Attention feed: one item, “N running images match a known advisory”, critical when any match is critical.
- Security center, Checklist tab: a compact card with the feed state, signature label and per-app matches.
- CLI:
levelrail-cli security advisories listandlevelrail-cli security advisories match. - API:
GET /api/v1/security/advisories(read ability). Callers only see apps they can read.
Refresh an affected app
When an app matches an advisory and the registry holds a newer digest of the same tag, you can redeploy it on that digest:POST /api/v1/apps/{name}/advisory-refresh (deploy ability on the app) pins the newest registry digest of the app’s tag and sends it through the normal deploy path. Freeze windows, deploy policy, protected-environment approvals (--confirm returns a pending approval, nothing deploys until it is approved), release bindings (APP_RELEASE_BINDINGS), image signature enforcement and the registry digest check all still apply, and the request is audited.
It is refused when APP_ADVISORY_REFRESH_ACTION is not on, when the feed signature is not verified, when the app matches no advisory, when the registry has no newer digest than the one running, or when the registry cannot be reached. A newer digest is not proof of a fix: check that the match disappears afterwards, and move to the fixed_in version when it does not.