github artifact-keeper/artifact-keeper v1.10.2
Artifact Keeper 1.10.2

3 hours ago

Artifact Keeper 1.10.2

A security patch release on the 1.10 line. The headline is a set of API token scoping fixes: a token restricted to certain repositories could mint a new token without that restriction, and several other paths let a token's repository scope fail open. It also updates the WASM plugin runtime to wasmtime 36.0.16 for two RustSec advisories. Alongside them come a conda scan-on-upload fix and a Composer proxy fix that closes an anonymous stall of the shared metadata path. This release adds two schema migrations (235 and 237). Read the upgrade notes below before upgrading.

Security — API token scoping

A security advisory is published alongside this release; see the security advisory for affected versions and severity.

  • A repository-scoped token can no longer mint a wider token. Every token-mint endpoint checked the new token's permission scopes against the caller, but not its repository scope, so a token restricted to some repositories could mint a sibling with no repository restriction. A token minted by a restricted credential now inherits that credential's repositories, and the restricted credential cannot name a different selector for it (#4227, #4225).
  • Repository selectors fail closed. A stored selector that cannot be read, or that names a criterion the server doesn't know, now grants no repository instead of every repository. Token-creation requests refuse unknown fields, so a misspelled repo_selector can no longer mint an unrestricted token (#4227, #4226).
  • Personal tokens honour their repository selector. The web UI's Access Tokens page sent a repo_selector that the API silently dropped, so the token was minted unrestricted. The selector is now stored and enforced (#4224, #4219).
  • Deleting repositories can only narrow a token, never widen it. A token pinned to explicit repositories used to become unrestricted once all of them were deleted. It now denies every repository instead (#4265, #4271, #4228).
  • Repository-management endpoints take scopes a token can actually carry. Repository create/update, cache, upstream, routing and similar settings now require write:repositories (reads need read:repositories). Deletes need delete:repositories or delete:artifacts. Before, only session logins and admin/* tokens could call them (#4265, #4271, #3831).
  • Webhook reads match the webhook listing. Fetching a webhook by id now needs the same read access as listing it, webhook reads require read:repositories, and custom header values come back redacted as ***. An admin using a repository-scoped token is now confined to that scope in the repository and package listings too (#4265, #4271, #3901).

Security — WASM plugin runtime

  • wasmtime updated to 36.0.16. A WASM plugin guest could allocate past its host-call fuel limit through dynamic record lifting, or panic the host through a filesystem datetime overflow in WASI (RUSTSEC-2026-0314, RUSTSEC-2026-0316). No configuration change is needed (#4332).

Fixed

  • conda packages pushed natively are scanned on upload. A package published through the native conda PUT/POST routes skipped scan-on-upload and stayed ungraded until someone ran a repository scan by hand (#4167, #4159).
  • Composer can no longer stall the shared metadata proxy. Eight concurrent anonymous lookups against a public remote Composer repository could reserve the whole buffered-metadata budget and wait on each other. Until the request timeout, that stalled metadata proxying for every format (npm, PyPI, RPM, Debian and others). Each request now holds at most one slice of the budget at a time (#4170, #4162).

Upgrade notes / behavior changes

Some of these fixes intentionally refuse requests that 1.10.1 accepted. Check your automation against this list.

  • Token creation is stricter. All token-mint endpoints now reject unknown JSON fields with 400 instead of ignoring them, and malformed bodies return 400 rather than 422. An empty or non-restricting repo_selector is refused, and so is a service-account repository_ids: []. A repository-restricted token (or a session exchanged from one) that names a selector or repository_ids for the new token gets 403. With neither, the child inherits its restriction, and a restricted token whose restriction matches nothing cannot mint at all.
  • Existing selectors fail closed. A token whose stored selector is unparseable or contains an unrecognised key now reaches no repositories. Before, it was unrestricted or broader than written. Its holder sees 404 for repositories it used to reach. Re-mint it with a corrected selector. A restricted token whose repositories have all been deleted also now denies everything.
  • New scope requirements. Repository management needs write:repositories. The npm scope policy, egress proxy and upstream-test reads need read:repositories, and the upstream test also needs repository admin. Deleting a repository needs delete:repositories, and deleting an artifact or cancelling a chunked upload needs delete:artifacts. Webhook list, fetch and deliveries need read:repositories plus a read grant. The web UI's "Write" token type maps to write:artifacts, which does not cover repository management, so mint write:repositories explicitly for that.
  • Admins with a scoped token are confined. An admin presenting a repository-scoped token now sees only that scope in the repository and package listings, as search and webhooks already did.
  • Migration 237 fails fast under lock contention. It runs with a 5-second lock timeout. If the upgrade fails on a lock timeout, retry it when the table is quieter. The migration is safe to re-run. It also marks repository tokens that had already lost every repository as deny-all, using the audit log.
  • Review tokens minted by other tokens. Tokens minted through a repository-restricted token before 1.10.2 may be unrestricted, and nothing records that a token minted them. Personal tokens created with a repository scope through the web UI before this release were issued unrestricted too, and the upgrade does not fix them retroactively. Review tokens created by automation that authenticates with a restricted token, and personal tokens scoped through the UI, and rotate them. A service-account token minted with an explicit repository_ids list whose repositories were all deleted before the upgrade can't be told apart from an unrestricted one, so an administrator should review and revoke it.

The full entries are in the ## [1.10.2] section of CHANGELOG.md.

Sponsors

Thank you to our backers for supporting ongoing development:

Become a sponsor

Thank You

  • @allen0099 for reporting that repository-management endpoints required a scope no API token can carry (#3831).

Full changelog: v1.10.1...v1.10.2

Don't miss a new artifact-keeper release

NewReleases is sending notifications on new releases.