Commit Graph

855 Commits

Author SHA1 Message Date
Akash Kumar bb5b77aeaa fix(sync): apply tag filters before destination mapping (#4003)
* fix(sync): apply tag filters before destination mapping

Signed-off-by: Akash Kumar <meakash7902@gmail.com>

* fix(sync): return stable pointer from getContentByUpstreamRepo

Iterate by index and return &cm.contents[i] so callers get the slice
element rather than a copy of the loop variable, matching the existing
GetContentByLocalRepo helper.

Signed-off-by: Akash Kumar <meakash7902@gmail.com>

---------

Signed-off-by: Akash Kumar <meakash7902@gmail.com>
2026-04-27 08:27:46 +03:00
Akash Kumar 9e13be8b61 fix(api): support multipart range blob pulls (#3995)
* fix(api): support multipart range blob pulls

Signed-off-by: Akash Kumar <meakash7902@gmail.com>

* fix(api): tighten multipart range response

- Drop the redundant deferred closeRangeReaders; the deferred cleanup
  registered when the slice is created already covers all paths.
- Stop copying the request Accept header into each multipart part's
  Content-Type. Accept can be a list of media ranges (e.g.
  "application/octet-stream,*/*"), which is not a valid Content-Type and
  may confuse multipart parsers. RFC 9110 lets us omit it entirely.
- Set Docker-Content-Digest on the partial-content response so range
  pulls expose the same header as a full GET.
- Drop the over-broad build tag on routes_internal_test.go; the parser
  unit test does not need any extension build tags.

Signed-off-by: Akash Kumar <meakash7902@gmail.com>

---------

Signed-off-by: Akash Kumar <meakash7902@gmail.com>
2026-04-27 08:17:08 +03:00
Akash Kumar 8905b48bb7 fix(zli): Improve zli CVE diff output (#3994)
* fix(cli): improve zli CVE diff output

Signed-off-by: Akash Kumar <meakash7902@gmail.com>

* test(api): avoid TestRoutes port collision

Signed-off-by: Akash Kumar <meakash7902@gmail.com>

* test(cli): cover CVE diff formatting helpers

Signed-off-by: Akash Kumar <meakash7902@gmail.com>

* test(search): remove redundant test case copy

Signed-off-by: Akash Kumar <meakash7902@gmail.com>

---------

Signed-off-by: Akash Kumar <meakash7902@gmail.com>
2026-04-26 22:25:10 +03:00
Ramkumar Chinchani 934b22d124 fix(security): enhance timeout configurations and body size limits fo… (#3984)
* fix(security): enhance timeout configurations and body size limits for HTTP requests

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>

* fix(tests): refactor backend result handling in proxyHTTPRequest test

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>

* fix(security): preserve ContentLength in proxied requests to prevent server hang

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>

* fix(security): preserve explicit zero-length request bodies in proxyHTTPRequest
fix(tests): add test for normalizedTimeout function to ensure default fallback

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>

* fix(security): prevent default HTTP timeout values from being set unless explicitly configured

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>

* fix(security): refactor timeout handling to use explicit checks for nil and non-positive values

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>

* fix(tests): add wait_for_event_count function to ensure expected event generation

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>

* fix(security): improve timeout handling and update error responses for large requests

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>

* fix(security): enhance HTTP timeout handling with explicit accessors and default values

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>

* fix(security): increase default API key body size and timeout values for improved performance

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>

* fix(security): unify timeout handling by replacing specific read/write timeouts with a single default timeout

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>

* fix(security): consolidate HTTP timeout accessors and enhance timeout handling

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>

* fix(security): simplify HTTP timeout accessors and set default values for read/write timeouts

Co-authored-by: Copilot <copilot@github.com>
Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>

---------

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>
Co-authored-by: Copilot <copilot@github.com>
2026-04-26 22:23:48 +03:00
Nikita Vakula 8282aef12b feat(auth): support OIDC RP-Initiated Logout (#3975)
POST /zot/auth/logout now returns an endSessionUrl in the JSON
response body when the session was established via an OIDC provider
whose discovery document advertises an endSessionEndpoint, so the
UI can navigate the browser to it and terminate the session at the
IdP in addition to clearing the local cookie.

- The OIDC callback records the provider name in the session after
  login; the github OAuth2 path is untouched.
- end_session_endpoint is read from the zitadel/oidc RelyingParty
  and validated as an absolute http(s) URL.
- post_logout_redirect_uri prefers http.externalUrl when set and
  falls back to deriving the origin from the incoming request.
- No id_token_hint is sent; client_id identifies the RP, so the
  ID token does not need to be persisted.
- Non-OIDC sessions (local/basic/LDAP/GitHub) retain the existing
  200 OK, no body behavior.

Operators must register the URI zot sends as a valid post-logout
redirect URI on the IdP client.

Ref: https://openid.net/specs/openid-connect-rpinitiated-1_0.html

Signed-off-by: Nikita Vakula <programmistov.programmist@gmail.com>
2026-04-25 23:19:29 +03:00
Marco 0eafaeb043 fix(api): recognize Docker Compose/Buildx User-Agent in v2 challenge workaround (#3992)
Docker Compose and Buildx proxy through the Docker daemon, which sends
a User-Agent starting with "docker/<version>" rather than the
"Docker-Client/<version>" string sent by direct Docker CLI pulls.
This caused compose/buildx pulls to skip the 401 challenge on
registries with mixed anonymous/authenticated access policies,
resulting in 'unauthorized' errors.

Add strings.HasPrefix(ua, "docker/") alongside the existing
Docker-Client check so daemon-proxied requests from any upstream
tool (compose, buildx, etc.) are handled correctly.

Fixes #3991
2026-04-25 08:58:22 +03:00
Andrei Aaron 9ba59559d2 fix(api): return 416 for bad upload range on PUT; fix GET upload Range at size zero (#3983)
Align closing blob upload (PUT) with the OCI Distribution Spec: invalid /
out-of-order upload ranges (ErrBadUploadRange) return 416 Requested Range Not
Satisfiable instead of 400, for both the final-chunk PutBlobChunk path and
FinishBlobUpload.

GetBlobUpload (GET upload status): fix the Range response when zero bytes have
been received—send Range: 0-0 instead of Range: 0--1, consistent with a new
session and the spec’s Location + Range upload status shape. Only map
ErrBadBlobDigest to 400 here; do not handle ErrBadUploadRange on GET (that
request carries no range; ImageStore.GetBlobUpload does not return it).

Document PUT upload failures 400 and 416 in swagger; regenerate swagger
artifacts. Update route tests (expect 416 on UpdateBlobUpload for
ErrBadUploadRange), drop the mock-only GetBlobUpload+ErrBadUploadRange case,
and assert Range: 0-0 in TestPullRange after GET on a new upload location.

Fix potential panic when parsing Content-Range (index out of range)
when accessing `tokens[0]`.

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2026-04-20 08:24:36 +03:00
Ramkumar Chinchani b47b643e05 fix(security): remove InsecureSkipVerify from metrics client (TLS-1) (#3982)
* fix(security): remove InsecureSkipVerify from metrics client (TLS-1)

Replace the unconditional InsecureSkipVerify: true TLS config in
newHTTPMetricsClient with the system cert pool (+ TLS 1.2 minimum).

Add an optional CACert field to MetricsConfig and to the exporter
ServerConfig so operators running zot with a self-signed or private
CA can point the exporter at the correct CA file instead of
disabling certificate verification entirely.

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>

* feat(metrics): add HTTPS configuration for metrics exporter

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>

* fix(security): enhance CA certificate handling in metrics client and add tests

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>

* fix(security): improve CA certificate error handling in metrics client and update tests

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>

* fix(tests): correct package name in minimal_client_test.go and simplify error declaration

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>

* fix(tests): update package name in minimal_client_test.go for consistency

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>

---------

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>
2026-04-19 08:57:24 +03:00
Ramkumar Chinchani bfc59ad120 security: suppress Allow-Credentials on wildcard CORS origin (CORS-1) (#3980)
fix(security): suppress Allow-Credentials on wildcard CORS origin (CORS-1)

Per CORS spec §3.2, Access-Control-Allow-Credentials must not be
"true" when Access-Control-Allow-Origin is the wildcard "*".

ACHeadersMiddleware (pkg/common/http_server.go) and
getUIHeadersHandler (pkg/api/routes.go) now only emit the
credentials header when an explicit, non-empty AllowOrigin is
configured.  Deployments that leave AllowOrigin blank (default
wildcard) no longer produce a contradictory header pair.

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>
2026-04-18 21:14:52 +03:00
Ramkumar Chinchani eadc9b65ed fix(security): limit API key creation body to 4 KiB (INPUT-2) (#3978)
Wrap req.Body with http.MaxBytesReader before io.ReadAll in
CreateAPIKey. Requests with bodies larger than MaxAPIKeyBodySize
(4 KiB) now return HTTP 413 instead of buffering arbitrary data.

Add the MaxAPIKeyBodySize constant, update the Swagger @Failure
annotation to document 413, and add a unit test.

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>
2026-04-18 20:39:08 +03:00
Ramkumar Chinchani 35c29b95e4 fix(security): limit manifest PUT body to 4 MiB (INPUT-1) (#3977)
Wrap request.Body with http.MaxBytesReader before io.ReadAll in
UpdateManifest. Bodies exceeding MaxManifestBodySize (4 MiB) now
return HTTP 413 with a MANIFEST_INVALID error body instead of
buffering unlimited data into memory.

Add the MaxManifestBodySize constant and a unit test that sends an
oversized body and asserts the 413 status.

Agent-Logs-Url: https://github.com/project-zot/zot/sessions/5eca86eb-9749-4cf8-9fb8-7b9ace2ba87f

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>
2026-04-17 13:10:51 -07:00
Andrei Aaron 7ceb01dcff fix(auth): add workaround for Docker client auth with mixed anonymous policies (#3868)
* fix(auth): add workaround for Docker client auth with mixed anonymous policies

Docker client fails to authenticate to protected repositories when basic auth
(htpasswd/LDAP) is used with mixed access policies (some repos anonymous,
some requiring auth). This happens because Docker determines whether to send
credentials based on the /v2/ response - if it returns 200, Docker assumes
no auth is needed anywhere.

Add `forceDockerClientAuth` config option that, when enabled, forces 401 on
/v2/ for Docker clients, triggering Docker's authentication flow.

This workaround only affects Docker clients (detected via User-Agent).
Podman and other OCI-compliant clients are unaffected.

Refs: https://github.com/opencontainers/wg-auth/blob/main/docs/implementations/moby.md

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>

* feat: remove ForceDockerClientAuth flag and use only authz policies to determine the docker specific behavior

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>

---------

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2026-04-17 09:10:02 +03:00
Andrei Aaron 9991821295 fix: Updating a repository should not result in a corrupted index.json file if disk is full (#3963)
See https://github.com/project-zot/zot/issues/3924

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2026-04-14 08:59:25 +03:00
Bachir Khiati ba8575d960 feat(api): add repository quota enforcement middleware (#3923)
Adds a configurable maximum repository count per registry instance.
When maxRepos is set on StorageConfig, manifest pushes that would create
a new repository beyond the limit are rejected with HTTP 429
TOOMANYREQUESTS. Pushes to existing repositories are always allowed.

Implemented as an always-available feature in pkg/api (not a build-tag
extension). MaxRepos is a field on StorageConfig, enabled when > 0.

- repoQuotaMiddleware on the dist-spec router intercepts manifest PUTs.
  New-repo pushes are serialized with a sync.Mutex to prevent concurrent
  requests from exceeding the limit.
- Adds CountRepos(ctx) to the MetaDB interface with efficient
  implementations: BoltDB (Stats().KeyN), Redis (HLen), DynamoDB
  (Scan with Select=COUNT).
- Config.IsQuotaEnabled() added, wired into controller.go metaDB init.
- Four integration tests (enforcement, concurrency, disabled,
  unconfigured) and backend-specific CountRepos tests for BoltDB, Redis,
  and DynamoDB.

Signed-off-by: Bachir Khiati <bachir.khiati@gmail.com>
2026-04-13 23:18:34 +03:00
Andrei Aaron 451e7b8e47 feat: Add TrivyConfig.VulnSeveritySources (Trivy's --vuln-severity-source) (#3943)
And default it to ["auto"] when unset, with an info log from applyDefaultValues.

Refactor CVE NewScanner to take *CVEConfig instead of separate DB repository
strings so the full Trivy block is available to the scanner.

Extend CLI and search tests for the new field and logged config; document
CVE/Trivy in examples/README and add examples/config-cve-trivy.json.

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2026-04-08 09:39:26 +03:00
Andrei Aaron c6289ec5ba fix: address code review comments (#3942)
* fix: address code review comments in https://github.com/project-zot/zot/pull/3885#pullrequestreview-4045836197

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>

* fix: data race in GetPort()

See https://github.com/project-zot/zot/actions/runs/24045271222/job/70126983674?pr=3942

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>

* fix(test): reuse ReadLogFileAndSearchString for auto-port log; throttle poll loop

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>

---------

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2026-04-08 00:10:54 +03:00
Ramkumar Chinchani 78c6e915dd chore: fix dependabot alerts (#3940)
Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>
2026-04-06 10:03:09 -07:00
Andrei Aaron aa742aa1c0 test: add tests for pushing manifests with non-canonical digests together with tags (#3920)
test: add tests for pushing manifests with non-cannonical digests together with tags

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2026-03-31 12:30:19 +03:00
Sebastian Thees e188f45890 fix(storage/gcs): fix double-prefixed rootdirectory and EOF handling in Walk for GCS (#3903)
* fix(storage): resolve double-prefixing issue for GCS rootdirectory

Preserve double-prefixing for S3 to maintain backward compatibility with existing data. For GCS, always use "/" as rootDir to avoid double-prefixing, as GCS rootdirectory usage is a newer feature without legacy data.

Signed-off-by: Sebastian Thees <thees@users.noreply.github.com>

* fix(gcs): handle io.EOF correctly in Walk method

Ensure io.EOF is returned unwrapped to allow proper error handling with errors.Is() upstream.

Signed-off-by: Sebastian Thees <thees@users.noreply.github.com>

* fix(storage): set sensible default ("/zot") for GCS when storageDriver.rootdirectory is unset or empty or "/"

Signed-off-by: Sebastian Thees <thees@users.noreply.github.com>

* fix(imagestore): avoid warning logs for expected cache miss scenarios

Refine logging to use debug level for expected cache misses, preventing unnecessary warnings.

Signed-off-by: Sebastian Thees <thees@users.noreply.github.com>

---------

Signed-off-by: Sebastian Thees <thees@users.noreply.github.com>
2026-03-30 14:13:40 +03:00
Andrei Aaron a5cc8ab810 feat: support pushing multiple tags for a single manifest (#3885)
* feat: support pushing multiple tags for a single manifest

See https://github.com/opencontainers/distribution-spec/pull/600

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>

* fix: constants not replaced in swagger output

Also godot mandates comments ending in dots,
which produces bad results in the swagger generated files, see the extra ". which is now fixed below:

```
diff --git a/swagger/docs.go b/swagger/docs.go
index 84b08277..fb2c45c3 100644
--- a/swagger/docs.go
+++ b/swagger/docs.go
@@ -114,7 +114,7 @@ const docTemplate = `{
                         }
                     },
                     "400": {
-                        "description": "bad request\".",
+                        "description": "bad request",
                         "schema": {
                             "type": "string"
                         }
@@ -200,7 +200,7 @@ const docTemplate = `{
                         }
                     },
                     "400": {
-                        "description": "bad request\".",
+                        "description": "bad request",
                         "schema": {
                             "type": "string"
                         }
diff --git a/swagger/swagger.json b/swagger/swagger.json
index cfeb3900..247f95fa 100644
--- a/swagger/swagger.json
+++ b/swagger/swagger.json
@@ -106,7 +106,7 @@
                         }
                     },
                     "400": {
-                        "description": "bad request\".",
+                        "description": "bad request",
                         "schema": {
                             "type": "string"
                         }
@@ -192,7 +192,7 @@
                         }
                     },
                     "400": {
-                        "description": "bad request\".",
+                        "description": "bad request",
                         "schema": {
                             "type": "string"
                         }
diff --git a/swagger/swagger.yaml b/swagger/swagger.yaml
index 57641c2f..09b30dcc 100644
--- a/swagger/swagger.yaml
+++ b/swagger/swagger.yaml
@@ -310,7 +310,7 @@ paths:
           schema:
             type: string
         "400":
-          description: bad request".
+          description: bad request
           schema:
             type: string
         "500":
@@ -366,7 +366,7 @@ paths:
           schema:
             type: string
         "400":
-          description: bad request".
+          description: bad request
           schema:
             type: string
         "500":
```

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>

---------

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2026-03-29 21:13:24 +03:00
Ramkumar Chinchani 705939aed3 feat(schema): add schema command to dump JSON Schema for zot config (#3905)
Fixes https://github.com/project-zot/zot/issues/3882

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>
2026-03-28 08:28:35 -07:00
John Wagner 8f0bf18d7e fix(search): expose LastPullTimestamp and PushedBy on index ImageSummary (#3865)
ImageIndex2ImageSummary was missing LastPullTimestamp assignment, causing
multi-arch image queries to always return null for this field. Also adds
the PushedBy field (already stored in MetaDB) to the GraphQL schema and
both conversion paths (manifest and index).

Signed-off-by: cainydev <wajo432@gmail.com>
2026-03-10 16:40:54 -07:00
Ramkumar Chinchani 2ba0525f01 chore: fix dependabot alerts (#3860)
Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>
2026-03-10 09:43:08 +02:00
Ramkumar Chinchani ace12e2a12 fix: don't skip "latest" tag authz check for update (#3847)
Reported by @1seal

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>
2026-03-08 09:42:53 +02:00
Andrei Aaron 9425ca8b7d fix(auth): prevent open redirect via callback_ui (#3844)
Validate callback_ui and default invalid values to /.
Allow absolute callback_ui only when its origin is allowlisted via http.auth.openid.callbackAllowOrigins (and externalUrl).
Add/adjust unit + controller tests and update examples/docs for relative vs allowlisted absolute redirect

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2026-03-08 08:13:16 +02:00
Andrei Aaron 6f67fcdf8f feat(sync): add SyncLegacyCosignTags config to skip syncing legacy cosign/SBOM tags when disabled (#3842)
* feat(sync): add SyncLegacyCosignTags config to skip syncing legacy cosign/SBOM tags when disabled

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>

* fix: sync on demand with referrers API should not use recursion to sync referrers of referrers

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>

* fix: add tests SyncLegacyCosignTags and changes in /referrers on demand sync

Credit for the tests goes to @jzhn see:
https://github.com/project-zot/zot/pull/3840/changes

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>

* fix: remove redundant syncRef logic which synced referrers both with the zot inner() implementation and with regctl native implementation

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>

---------

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2026-03-06 19:12:31 +02:00
Uğur Tafralı 1ff6f609b7 fix: skip OCI conversion when image is already synced #3823
* Fix #3823: skip OCI conversion when image is already synced

When syncRef determines an image is already synced, it now returns a
bool to signal the skip. syncImage checks this and returns early before
attempting OCI conversion, preventing misleading 'failed to convert
docker image to oci' errors caused by a non-existent temp directory.

* Keep syncReferrers and CommitAll running for already-synced images

Address review feedback: new referrers can be added upstream after
initial sync, so we must not skip syncReferrers. Only the OCI
conversion is guarded by the skipped flag, since converting an
already-stored image is both unnecessary and incorrect.

Signed-off-by: Ugur Tafrali <ugur.tafrali@gmail.com>

---------

Signed-off-by: Ugur Tafrali <ugur.tafrali@gmail.com>
2026-02-28 19:37:01 +02:00
Ramkumar Chinchani 01bca48e33 chore: fix dependabot alerts (#3820)
Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>
2026-02-24 08:23:49 +02:00
Andrei Aaron 5e57656bff GCS storage support (#3798)
feat(storage): add a GCS driver

test(storage): add unit tests for GCS driver

test(storage): add missing unit tests for GCS driver & resolve lint issues

fix: configuration validation for GCS Storage

test(storage): resolve panic by test due to setupGCS ignoring returned error

test(storage): add dummy gcs credentials

test: add darwin support for macos to run tests

ci: update workflows to pin gcs emulator version

lint: resolve long line lengths & formatting issues

test: move error for gcs mock earlier with an error

test: stop test using local google credentials and use mock instead

test: add missing dummy creds

test(storage): use storage-testbench for GCS, isolate GCS tests, fix driver Delete

- Switch GCS emulator from fake-gcs-server to storage-testbench in CI.
  Run the GCS emulator only in the privileged-test job; remove it from
  minimal and extended test jobs.

- Consolidate GCS tests under pkg/storage/gcs (needprivileges,linux).
  Add TestMain with HTTPS proxy and /etc/hosts so tests talk to
  storage-testbench; move GCS-specific cases from storage_test.go and
  scrub_test.go into gcs_test.go. Run GCS tests via a second privileged-test
  invocation and collect coverage in coverage-needprivileges-gcs.txt.

- Make GCS driver Delete idempotent and normalize errors. Treat
  PathNotFoundError from Delete as success so that deleting an already-gone
  path (e.g. after GC under eventual consistency) does not fail. Add
  formatErr to map 404/not found to PathNotFoundError and use it for all
  driver methods so callers get consistent storage driver errors.

- Drop GCS branches and helpers from storage_test.go and scrub_test.go so
  non-privileged tests only use local/S3; GCS is tested only in
  pkg/storage/gcs with storage-testbench.

- Set GCSMOCK_ENDPOINT without /storage/v1/, as the rest of the URL is set in tests.

- Show errors in case of failure to create bucket.

- Consolidate StorageDriverMock structs inside the pkg/test/mocks package.

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
Co-authored-by: Steven Marks <steve.marks@qomodo.io>
2026-02-18 23:41:21 -08:00
Ramkumar Chinchani 47659c11b2 feat(tls): implement dynamic TLS certificate reloading with file watching (#3792)
Fixes issue #3747

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>
2026-02-15 13:01:50 -08:00
Andrei Aaron 3454ad63dc chore: update github.com/sigstore/cosign/v3 from 3.0.2 to 3.0.4 (#3789)
Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2026-02-10 14:16:50 -08:00
Ramkumar Chinchani 67b8241a7b fix: correct typo var name mirroHostConfig (#3777)
Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>
Co-authored-by: TeCHiScy <741195+TeCHiScy@users.noreply.github.com>
2026-02-05 11:25:09 +02:00
Cody Ray 851ad012cb fix(imagestore): normalize paths to prevent panic on Windows (#3775) 2026-02-04 23:41:12 +02:00
Andrei Aaron 3c8030b2c7 fix(meta): fixes for LastUpdated and TaggedTimestamp (#3754)
1. Parse repos without metadata in ParseStorage

The timestamp check in ParseStorage was skipping repos that exist in
storage but don't have metadata. When GetRepoLastUpdated returns zero
time (no metadata), we should always parse the repo to create its
metadata. Check if metaLastUpdated is zero before comparing timestamps.
If zero, always parse regardless of storageLastUpdated.

2. Change the logic of how LastUpdated is computed in RepoSummary

It is not the latest tagged timestamp from the available images or
the last updated image created timestamp, based on whichever is the
latest.

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2026-02-03 21:10:35 +02:00
Matheus Pimenta 0e5a339f11 feat(jwt-asm): support AWS Secrets Manager for JWT verification (#3763)
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2026-02-03 09:25:38 -08:00
Matheus Pimenta b9aad15ad0 feat(jwt-exp): exp claim at the access entry level (#3761)
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2026-02-02 00:26:36 +02:00
Matheus Pimenta c8fae88e37 feat(oidc): support per-issuer CA (#3760)
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2026-02-01 23:57:27 +02:00
Andrei Aaron 3c7d5a5f1d feat: add TaggedTimestamp to ImageSummary returned by graphql API (#3731)
feat(meta): add TaggedTimestamp field and preserve during re-parsing

Add TaggedTimestamp field to track when image tags were created, exposed
through GraphQL API. Previously, when zot restarted and re-parsed storage,
ResetRepoReferences would clear all tags, causing timestamp information to
be lost and reset to the service restart time for existing images.

This change adds TaggedTimestamp support and modifies ResetRepoReferences to
selectively preserve tags that still exist in storage, maintaining their
TaggedTimestamp values. Tags that no longer exist in storage are removed as
before.

Changes:
- Add TaggedTimestamp field to GraphQL ImageSummary schema
- Update GraphQL conversion functions to populate TaggedTimestamp with
  fallback to PushTimestamp when unavailable
- Updated ResetRepoReferences interface to accept tagsToKeep parameter
- Modified ParseRepo to collect tags from storage before resetting
- Updated all backend implementations (Redis, DynamoDB, BoltDB) to preserve
  tags in tagsToKeep instead of clearing all tags
- Updated tests and mocks to match new signature

This ensures TaggedTimestamp accurately reflects when tags were originally
created, and exposes this information through the GraphQL API.

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2026-01-30 23:05:14 +02:00
Andrei Aaron e82aac8409 fix(fips): flaky fips blackbox test and add missing curves (#3732)
2 unrelated issues:
See https://github.com/project-zot/zot/actions/runs/21336958408/job/61410298444?pr=3731 for details.
Also add missing fips curves https://cs.opensource.google/go/go/+/refs/tags/go1.25.6:src/crypto/tls/defaults_fips140.go;l=33

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2026-01-26 13:45:03 +02:00
Matheus Pimenta bf619c570e Introduce support for OIDC workload identity federation (#3711)
* feat(oidc): introduce support for OIDC workload identity federation

Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>

* feat(oidc): add e2e test for bearer OIDC and a kind cluster

Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>

* feat(oidc): make OIDC workload identity federation its own feature

Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>

* feat(oidc): move errors to the errors package

Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>

* feat(oidc): fix race in cel package

Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>

* feat(oidc): compile cel expressions

Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>

---------

Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2026-01-24 21:03:53 -08:00
Andrei Aaron 088914bb05 fix: graphql playground documentation was hardcoded to an unrelated example (#3721)
Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2026-01-21 09:28:49 +02:00
Andrei Aaron 14e537a5eb chore: remove direct usage of the github.com/aws/aws-sdk-go package (aws sdk v1) (#3701)
Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2026-01-15 21:43:34 +02:00
Ramkumar Chinchani 0cac8a7ee8 chore: fix dependabot alerts (#3707)
Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>
2026-01-15 20:42:39 +02:00
Andrei Aaron d33c1e3b22 fix: now attempt to bind to the zot server socket to check if the server is running (#3703)
Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2026-01-15 20:02:15 +02:00
Andrei Aaron 7c9064574d fix: remove usage of deprecated function aws.EndpointResolverWithOptionsFunc (#3700)
Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2026-01-15 09:29:01 -08:00
Asgeir Storesund Nilsen 708adf63d4 fix: CVE-2025-30204 - golang-jwt DoS vulnerability via excessive memory allocation (#3687)
* fix: CVE-2025-30204 - golang-jwt DoS vulnerability via excessive memory
allocation

Signed-off-by: Asgeir Nilsen <asgeir@twingine.no>

* fix: linting

Signed-off-by: Asgeir Nilsen <asgeir@twingine.no>

* chore: update project-zot/mockoidc to remove golang-jwt v3

Signed-off-by: Asgeir Nilsen <asgeir@twingine.no>

* test: Add more tests for bearer tokens

Signed-off-by: Asgeir Nilsen <asgeir@twingine.no>

* fix: Rewrite tests to remove MakeAuthTestServerLegacy

Signed-off-by: Asgeir Nilsen <asgeir@twingine.no>

---------

Signed-off-by: Asgeir Nilsen <asgeir@twingine.no>
2026-01-14 11:34:58 +02:00
Andrei Aaron e2ba7c8e20 fix: pre-existing dynamodb versions table should be populated with version if it doesn't contain it already (#3699)
Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2026-01-13 13:11:40 +02:00
Ricardo Noriega ac5fbd9110 Fix typos in documentation (#3678)
docs: Fix typos in documentation

Signed-off-by: Ricardo Noriega De Soto <rnoriega@redhat.com>
2026-01-12 11:00:30 +02:00
Ramkumar Chinchani 800a545fbe chore: fix dependabot alerts (#3677)
Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>
2025-12-29 09:59:57 +02:00
Andrei Aaron 95b8d65c8a test: fix some coverage issues, refactored some of the pagination logic to accomplish this (#3674)
Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-12-23 19:06:13 +02:00