848 Commits

Author SHA1 Message Date
Andrei Aaron 08fae9104d feat: support mTLS-only authn/authz with AccessControl and allow combining mTLS with other auth mechanisms (#3624)
* feat: support mTLS-only authn/authz with AccessControl and allow combining mTLS with other auth mechanisms

Signed-off-by: Ivan Arkhipov <me@endevir.ru>

* refactor: improve authentication logic and TLS certificate generation

- Fix mTLS authentication to use only leaf certificate instead of iterating
  through all certificates in the chain
- Reject Authorization headers when corresponding auth method is disabled,
  regardless of mTLS status (security improvement)
- Simplify authentication switch statement ordering and logic
- Move ErrUserDataNotFound error handling into sessionAuthn method
- Refactor TLS certificate generation to use Options pattern with
  CertificateOptions struct for better extensibility
- Consolidate duplicate certificate generation code into helper functions
  (generateCertificate, parseCA, initializeTemplate, applyOptions)
- Rename certificate generation functions for clarity:
  - GenerateCertWithCN -> GenerateClientCert
  - GenerateSelfSignedCertWithCN -> GenerateClientSelfSignedCert
- Add support for SAN settings including email addresses in certificates
- Update tests to reflect new authentication behavior and certificate API

This commit improves both the security posture (rejecting disabled auth
methods) and code maintainability (consolidated certificate generation).

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

* fix: guard against multiple Authorization headers

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

---------

Signed-off-by: Ivan Arkhipov <me@endevir.ru>
Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
Co-authored-by: Ivan Arkhipov <me@endevir.ru>
2025-12-11 20:08:32 +02:00
Ramkumar Chinchani e7b73b6c2d chore: fix dependabot alerts (#3636)
Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>
2025-12-09 10:49:45 +02:00
Andrei Aaron 4628080fa1 fix: remove misleading error messages on successful syncs (#3619)
See: https://github.com/project-zot/zot/issues/3560#issuecomment-3594856118
What happens is:
- syncRef skips the image ("skipping image because it's already synced")
- syncReferrers doesn't sync anything
- CommitAll is still called even though nothing was synced
- The temp directory exists but is empty (no index.json, no blobs)
- CommitAll fails because index.json is missing

Let's ensure we properly check for errors, and skip the log messages if some of the cases.

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-12-09 08:11:28 +02:00
Andrei Aaron 9dfa7c3ae6 refactor(test): new apis for creating temporary files (#3605)
Replace MakeTempFile usage with MakeTempFilePath and MakeTempFileWithContent
helpers that automatically handle file lifecycle. This prevents resource
leaks by ensuring temporary files are properly closed.

Shoudld also make the tests easier to read.

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-12-05 09:54:38 +02:00
Andrei Aaron edaef52d50 fix(trivy): cleanup Trivy temporary directory (#3618)
This Trivy commit changed the way the cleanup is done for Trivy operations:
https://github.com/aquasecurity/trivy/commit/8f5b56005a4e8752976524750089dc9ea2c91e40

We need to start calling the APIs to create and cleanup the temp dir to ensure we don't leave around content in the /tmp folder

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-12-03 10:11:32 +02:00
Andrei Aaron 8226b25509 feat(config): validate storage root directories for path conflicts (#3602)
Add validation to reject configuration files where stores and substores
of the same storage type (local or S3) have root directories that are
nested within each other or identical. Stores of different types (local
vs S3) are allowed to share the same root directory since they use
different storage backends.

The validation:
- Checks all stores (default + substores) for path conflicts
- Only compares stores of the same storage type
- Reports clear error messages indicating which stores conflict and why

Add comprehensive tests covering:
- Same storage types with identical/nested paths (rejected)
- Different storage types with same/nested paths (allowed)
- Various combinations of default store and substores

Fixes issues where nested or identical root directories could cause
data corruption or routing conflicts.

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-11-29 23:55:27 +02:00
Andrei Aaron e510ab6426 Fix error handling: return nil explicitly on successful completion (#3603)
fix: error handling: return nil explicitly on successful completion

Several functions in pkg/meta/redis/redis.go were returning 'err' at the
end of successful execution paths, which could lead to incorrect error
handling when 'err' was overwritten in loops or conditionals.

Changed the following functions to return nil explicitly when all
operations succeed:
- SearchRepos: return nil instead of err after successful loop
- SearchTags: return nil instead of err after successful loop
- GetRepoMeta: return nil instead of err after successful operations
- GetImageMeta: return nil instead of err after successful operations
- GetReferrersInfo: return nil instead of err after successful loop

This ensures that when functions complete successfully, they explicitly
return nil rather than relying on the last value of err, which may have
been overwritten during execution. This fixes TestRedisUnreachable which
was failing because SearchRepos was incorrectly returning nil error when
Redis was unreachable.

See failure in: https://github.com/project-zot/zot/actions/runs/19729927463/job/56528529923?pr=3599

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-11-28 11:49:17 +02:00
Andrei Aaron cc34a6f4ef fix(meta): handle cases when substores are nested (#3598)
fix(meta): handle cases where repositories when substores are nested

Note this is a case of bad configuration: having multiple stores
in the same tree structure. Guard against it in parse.go.

Fix getAllRepos to prevent duplicate repositories in metaDB when substore
directories are nested under the default store root directory.

The fix processes substores first, then the default store, using a
map-based deduplication approach to skip repositories that have already
been added. This ensures that when both the default store and substores
contain repositories with the same name (e.g., when a substore is nested
within the default store), only one instance is added to the repository
list.

Add test TestNoDuplicateReposWithSubstoresAndNestedRepoNames to verify
the deduplication logic works correctly with nested substores.

Also update the other tests to avoid these issues in the future
this is not a vali configuration.

This is not the intended use case for substores, and it may have caused:
https://github.com/project-zot/zot/actions/runs/19665302669/job/56320640980

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-11-27 20:11:52 +02:00
Andrei Aaron 69c3a0b99b feat: explicitly log if each authentication method is enabled (#3599)
feat: explicitly log if each autentication methods is enabled

When the server starts or when the config is reloaded.
See the discussion in: https://github.com/project-zot/zot/pull/3577#issuecomment-3568505810

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-11-27 11:30:14 +02:00
Andrei Aaron e068b8dc9f chore: Enable Go jsonv2 experiment and update the trivy dependency (v0.67.2) (#3572)
It requires the encoding/json/jsontext
package which is only available when the goexperiment.jsonv2 build
tag is enabled. This was causing build constraint errors during
tests and builds.

Changes:
- Add GOEXPERIMENT=jsonv2 to Makefile export and all go build/test
  commands that use env (since env creates a fresh environment)
- Add GOEXPERIMENT=jsonv2 to GitHub workflows that use direct go
  commands (workflows using make inherit it from Makefile)

Fix other dependabot alerts.

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-11-27 09:58:37 +02:00
Ramkumar Chinchani 6452bec403 chore: fix dependabot alerts (#3595)
* chore: fix dependabot alerts

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

* ci: bump up golang to 1.25.x

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

* fix: linter errors

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

* fix: stacker and docker build files to use golang 1.25

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

---------

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>
2025-11-26 11:21:36 +02:00
Andrei Aaron 09de471774 fix(storage): enforce standard OCI blob path structure in GetNextDigestWithBlobPaths (#3594)
Require blob files to follow standard OCI image layout:
rootDir/repo/blobs/algorithm/digest

- Validate grandparent directory is ImageBlobsDir
- Validate parent directory is valid digest algorithm
- Update tests to use standard OCI structure
- Add blobPath() helper to reduce duplication and fix linting

This should reduce the number of uneeded digest computations
if other non-oci specific files are present in the layout.

Fix also a race condition when picking ports in monitoring tests.

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-11-25 11:50:48 +02:00
Andrei Aaron a296968c1a fix: multiple fixes based on recent test failures (#3582)
* fix(monitoring): fix race condition in TestPopulateStorageMetrics

Write images to filesystem before starting controller to prevent GC
from reading index.json while it's being written.

See failure:
https://github.com/project-zot/zot/actions/runs/19633819097/job/56219606041

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

* fix(sync): fix TestSignatures assertion on referrers order

Search through all referrers to find the expected OCI ref digest instead
of assuming it's at index.Manifests[1], as the order is not guaranteed.

See https://github.com/project-zot/zot/actions/runs/19630382617/job/56208492397?pr=3579

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

* fix(redis): fix error handling in GetMultipleRepoMeta

The function was returning err at the end, which could be nil even when
HGetAll should have failed, because err gets reassigned in the loop.
Changed to return nil on success path, ensuring HGetAll errors are
properly propagated. Fixes TestRedisUnreachable failure.

See https://github.com/project-zot/zot/actions/runs/19634990856/job/56223414955?pr=3582

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

* refactor(sync): simplify sync test structure and restore file permissions

Remove unnecessary nested Convey blocks and integrate error tests into
parent blocks. Add defer statements to restore file permissions after
chmod operations to prevent side effects on subsequent tests.

Fix potential root cause of https://github.com/project-zot/zot/actions/runs/19636284485/job/56227682319?pr=3579

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

---------

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-11-24 19:23:52 +02:00
mottetm 6f0e05e676 fix: sync should be disabled when enable is false (#3579)
Signed-off-by: Matthieu Mottet <m.mottet@outlook.com>
2025-11-24 16:51:56 +02:00
Andrei Aaron 3b931a3a7a fix: handle zero time values in LastUpdated sorting functions (#3580)
When GetRepoLastUpdated fails (e.g., redis: nil), it returns time.Time{}
which gets converted to &time.Time{} (not nil). The existing nil checks
in sorting functions didn't account for zero time values, which should
also be treated as "oldest" (sorted last in descending order).

This commit:
- Adds zero time checks in addition to existing nil checks
- Treats both nil and zero time values as "oldest"
- Adds comprehensive tests for zero time edge cases

Affects ImgSortByUpdateTime, RepoSortByUpdateTime, and GetExpandedRepoInfo
sort functions.

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-11-24 11:02:33 +02:00
Andrei Aaron e072aa09e2 refactor: optimize code with modern Go patterns and pre-allocation (#3576)
This commit modernizes code across multiple packages by:
- Using Go 1.18+ features (slices.IndexFunc, strings.Cut)
- Pre-allocating slices and maps with known capacity
- Consolidating defensive checks and improving code clarity
- Fixing test data and build tag issues

CLI client improvements:
- Pre-allocate slices in search functions and service methods
- Replace strings.Split with strings.Cut for username:password parsing
- Use range-based iteration instead of manual index loops

Search extension optimizations:
- Cache sort functions in pagination modules
- Pre-allocate page buffers and maps
- Consolidate defensive checks in filterBaseImages/filterDerivedImages
- Fix image bas and derived logic allowing out of sequence layers for base images
- Fix image pagination reporting images groupped by repos when sorted by update time
- Remove duplicate resolver_test.go file

Monitoring extension:
- Replace manual loops with slices.IndexFunc
- Pre-allocate bucketsFloat2String map

Sync extension:
- Pre-allocate slice in parseRegistryURLs

Test utilities:
- Fix build tags in oci_layout.go

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-11-24 09:42:45 +02:00
Andrei Aaron da426850e7 chore: update golangci-lint and fix all issues (#3575)
* chore: Update golangci-lint

Signed-off-by: Lars Francke <git@lars-francke.de>

* chore: fix all golangci-lint issues

- Remove deprecated `// +build` tags
- Fix godoclint, modernize, wsl_v5, govet, lll, gci, noctx issues
- Update linter configuration
- Modernize code to use Go 1.22+ features (for range N, slices.Contains, etc.)
- Update make check lint the privileged tests

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

---------

Signed-off-by: Lars Francke <git@lars-francke.de>
Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
Co-authored-by: Lars Francke <git@lars-francke.de>
2025-11-22 23:36:48 +02:00
Andrei Aaron 566286ae42 fix: Add HTTP client timeouts to prevent indefinite hangs in sync operations (#3574) 2025-11-22 07:57:24 +02:00
Andrei Aaron 69dd648d20 fix(sync): properly handle CommitAll errors in syncImage and skip failed temp sync dirs (#3567)
- Return CommitAll errors instead of ignoring them
- Skip ErrRepoNotFound from temp sync dirs to allow other tags to sync
- Each tag uses separate temp directory, so failures are isolated

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-11-20 09:21:48 -08:00
Ramkumar Chinchani 64829f9502 feat: allow claim mapping for user name with oidc (#3540)
* feat: allow claim mapping for user name with oidc

* feat: bats test for claim mapping

* test: fix dex config in openid mapping test

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

* test: add panva idp

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

* fix: address copilot comments

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

---------

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>
Co-authored-by: Sky Moore <i@msky.me>
2025-11-20 08:54:56 -08:00
Lars Francke 7fa53f5b0f Sync images with a background context (#3537)
feat: Sync images with a background context

This means syncs/pulls will not be cancelled anymore when the requesting client disconnects.

The timeout used can be configured per registry

Signed-off-by: Lars Francke <git@lars-francke.de>
2025-11-20 08:52:27 -08:00
Andrei Aaron 2b60e11ce4 chore: update cosign from v2 to v3 (#3561)
* chore: update cosign from v2 to v3

Also do not import cosing into zli, as it doubles the bianry size
See: https://github.com/project-zot/zot/actions/runs/19506399474/job/55833719683?pr=3561

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

* chore: privileged-test should not depend on downloaded images

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

---------

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-11-20 00:43:57 +02:00
Andrei Aaron b7ab9dab16 fix (metadb): make sure metadb statistics are initialized on image download, and minor metadb fixes for Docker v2 manifest compatibility (#3545)
fix: make sure metadb statistics are initialized on image download, and minor metadb fixes for Docker v2 manifest compatibility

Looking into potential causes of https://github.com/project-zot/zot/issues/3163

1. One possible reason is the statistics were not properly initialized in the first place because of (unknown and/or unavoidable) errors on image push.
To workaround this add logic to initialize the statistics on the call to download them.

2. Some images have the download statistics while others dont, one cause could be a bug in the logic handling manifest mediatypes in the search extension.
Add compatibility checks for Docker v2 manifest types in metadb convert functions, and more tests for covering the Docker mediatype use case.

Side fixes:
- Ensure PushedBy Statistics entries are properly initialized in SetRepoReference
- Fix and issue in the image upload test functions, they were uploading docker images with oci mediatypes in call headers

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-11-18 20:56:44 +02:00
Ramkumar Chinchani 49c15abf06 chore: fix dependabot alerts (#3555)
Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>
2025-11-18 08:46:51 +02:00
Andrei Aaron c5f37546f5 fix: show relevant error messages in case of images which cannot be scanned by Trivy (#3554)
Old message example:
```
{"time":"2025-11-17T22:29:29.434073547Z","level":"debug","message":"image is not scannable","digest":"sha256:99155f2825186175c7f7e4df4f77d5d0ba68a018603afd9c014063d4ca11c0d6","mediaType":"application/vnd.oci.image.manifest.v1+json","error":"image 'nginx@sha256:99155f2825186175c7f7e4df4f77d5d0ba68a018603afd9c014063d4ca11c0d6' scanning is not supported for given image media type","caller":"zotregistry.dev/zot/v2/pkg/extensions/search/cve/cve.go:513","func":"zotregistry.dev/zot/v2/pkg/extensions/search/cve.BaseCveInfo.GetCVESummaryForImageMedia","goroutine":1246}
```

New message example:
```
{"time":"2025-11-17T22:25:10.33273421Z","level":"debug","message":"image is not scannable","digest":"sha256:99155f2825186175c7f7e4df4f77d5d0ba68a018603afd9c014063d4ca11c0d6","mediaType":"application/vnd.oci.image.manifest.v1+json","error":"image 'nginx@sha256:99155f2825186175c7f7e4df4f77d5d0ba68a018603afd9c014063d4ca11c0d6' scanning is not supported for given media type: layer media type 'application/octet-stream'","caller":"zotregistry.dev/zot/v2/pkg/extensions/search/cve/cve.go:513","func":"zotregistry.dev/zot/v2/pkg/extensions/search/cve.BaseCveInfo.GetCVESummaryForImageMedia","goroutine":1316}
```

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-11-17 20:35:57 -08:00
Ramkumar Chinchani 1d0eadc013 fix: img-src annotation changes with zui move to vite (#3539)
https://github.com/project-zot/zui/pull/484

zui is moving to vite framework but there are some changes in the
img-src annotations which must be allowed/accounted for in zot backend.

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>
2025-11-16 01:16:22 +02:00
Andrei Aaron 008527b7bb fix: gracefully handle manifests missing from storage (prepare for sparse indexes) (#3503)
GC and scrub should not stop if a manifest or index is missing from storage.
Other similar changes are also included.

WRT metadb, the missing manifests cannot be added, and the results returned from metadb
do not include the descriptors for these manifests.

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-11-13 09:26:18 -08:00
Andrei Aaron a8a6d3be9e fix: separate cipher suites and curve preferences into FIPS and non FIPS, and use them accordingly (#3523)
See: https://github.com/project-zot/zot/actions/runs/19209741002/job/54910194536

`failed to ping registry localhost:11448: Get "https://localhost:11448/v2/": crypto/ecdh: use of X25519 is not allowed in FIPS 140-only mode`

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-11-10 23:24:59 +02:00
Andrei Aaron b64add7715 fix: deduplicate entries in referrers responses (#3524)
See: https://github.com/project-zot/zot/issues/2506

Note we are not loosing anything functionality-wise by making this change.
Initially we considered the tags are in the annotations present in the referrers
but the only annotations we set on referrers are the ones inside the manifests themselves,
not the ones in the manifest descriptors, so the tags were not presetn anyway.

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-11-10 21:08:47 +02:00
Ramkumar Chinchani 04ae0a9409 fix: add support for sha256 and sha512 in htpasswd (#3497)
feat: add support for sha256 and sha512 htpasswd formats

Fixes issue #3495

We currently support only bcrypt htpasswd hashes, however bcrypt is not
FIPS-140 approved since it uses Blowfish.

This PR adds support for sha256 and sha512 formats and enforces that
bcrypt be disabled when fips140 mode is enabled.

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>
2025-11-09 15:28:29 +02:00
Lukasz Jakimczuk aaba362b4f fix: re-introduce pagination (#3521)
* fix: re-introduce pagination

Signed-off-by: Łukasz Jakimczuk <ljakimczuk@gmail.com>

* fix: use assignment

Signed-off-by: Łukasz Jakimczuk <ljakimczuk@gmail.com>

---------

Signed-off-by: Łukasz Jakimczuk <ljakimczuk@gmail.com>
2025-11-07 08:59:06 -08:00
Mathias Bogaert 3fd69faf5d fix: support custom OAuth2 URLs for GitHub Enterprise and self-hosted providers (#3513)
- Use custom authURL/tokenURL from config instead of hardcoded github.com endpoints
- Properly configure GitHub Enterprise API base URL from auth endpoints

Fixes OAuth2 authentication with GitHub Enterprise Server and other
self-hosted OAuth2 providers.

Signed-off-by: Mathias Bogaert <mathias.bogaert@gmail.com>
2025-11-04 14:11:05 +02:00
Ravi Chamarthy fdba14b9a3 fix(log): ensure func record is correct (#3501)
The "func" field in log output is incorrect in some cases and
showing internal logging methods instead of the actual calling
function. This is happening because the caller information is
being captured statically (5 call frames) which can be different
for different call patterns.

Changes:

* Move the caller capture to the event creation
* Use deterministic skip (3 frames) for event creation
* Add test cases to verify that the caller is captured correctly

Note: tests needed to written outside convey to avoid call insertion

Signed-off-by: Ravi Chamarthy <ravi@chamarthy.dev>
2025-10-31 17:01:35 -07:00
Andrei Aaron 195f50bac5 fix: close file handle before moving file in FullBlobUpload (#3499)
Should fix a Windows specific issue where renaming a file fails if the handler is not closed.

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-10-31 22:13:44 +02:00
Andrei Aaron 79ddc32b7c chore: fix monitoring goroutine leak in tests (#3500)
Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-10-31 13:55:43 +02:00
Ramkumar Chinchani a0943eccfe chore: fix dependabot alerts (#3496)
* chore: fix dependabot alerts

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

* fix: initialize logger in ut

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

---------

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>
2025-10-30 14:21:53 -07:00
Andrei Aaron 41e10d4fe9 feat: add zot subcommand to enable testing retention policy settings (#3449)
feat: add verify-feature retention subcommand with comprehensive testing and validation

Add a `verify-feature retention` subcommand that allows users to preview and
validate retention policy changes without running the actual Zot server.
The command runs GC and retention tasks in dry-run mode for immediate feedback.

- Run verify-feature retention standalone without starting the server
- Preview retention policy decisions in dry-run mode
- Configurable GC interval override via command-line flag
- Optional timeout for task completion
- Configurable log output (stdout or file)

Basic usage:
```bash
zot verify-feature retention <config-file>
```

With log file output:
```bash
zot verify-feature retention -l /var/log/zot-retention-check.log <config-file>
```

With GC interval override (runs GC tasks every 30 seconds):
```bash
zot verify-feature retention -i 30s <config-file>
```

With timeout (wait up to 5 minutes for tasks to complete):
```bash
zot verify-feature retention -t 5m <config-file>
```

Combined flags:
```bash
zot verify-feature retention -l /var/log/zot-retention-check.log -i 1m -t 10m <config-file>
```

The command supports overriding GC settings from the config:
- `-i, --gc-interval`: Override the GC interval setting (applies to all storage paths including subpaths)

- Refactored `RunGCTasks` from `controller.go` to be reusable
- Added `checkServerRunning` validation to prevent conflicts
- Implemented signal handling for graceful shutdown
- Added configuration sanitization and logging
- Set GCMaxSchedulerDelay programmatically (not user-configurable)

Added tests for coverage on main function:
- Negative test cases (no args, bad config, GC disabled, server running)
- Both BoltDB and Redis
- Retention enabled scenarios with complex image setups
- Retention disabled scenarios
- Delete referrers functionality
- Subpaths configuration
- GC interval override validation

Run the verify-feature retention tests:
```bash
go test -v ./pkg/cli/server -run TestRetentionCheck
```

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-10-28 13:36:59 -07:00
Andrei Aaron 029f6f0a29 fix: configure cookie Secure flag based on TLS configuration (#3482)
Make the Secure flag for session cookies configurable based on Zot's
TLS settings. This allows cookies to work properly when Zot is
accessed over HTTP (without TLS).

Changes:
- Add SecureSession field to AuthConfig to allow explicit control
- Add UseSecureSession() method that returns true when TLS is
  configured, or uses SecureSession setting if provided
- Update saveUserLoggedSession() to accept and use secure parameter
- Add tests for UseSecureSession() in config_test.go
- Enhance authn tests to verify cookie Secure flag behavior
- Fix TestAuthnSessionErrors by creating new client without cookies

The logic is:
- If TLS is configured, cookies always have Secure=true
- If TLS is not configured but SecureSession is explicitly set,
  use that value
- Otherwise, default to Secure=false for HTTP-only deployments

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-10-27 17:21:21 +02:00
Andrei Aaron 22cfd9430b refactor: remove usage of goto in the image store (#2969)
Signed-off-by: Andrei Aaron <aaaron@luxoft.com>
2025-10-25 17:14:38 +03:00
Andrei Aaron a2c144693f chore: stabilize coverage in specific sync test (#3480)
Take care of https://app.codecov.io/gh/project-zot/zot/pull/3479/indirect-changes

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-10-22 12:21:29 +03:00
Andrei Aaron 1fb2b67419 fix: minor fixes based on intermittent test failures (#3465)
1. preload busybox image to fix: https://github.com/project-zot/zot/actions/runs/18614431126/job/53077015870?pr=3465
2. stabilize test coverage in by using different error type: https://app.codecov.io/gh/project-zot/zot/pull/3444/indirect-changes
3. attempt to fx an intermitent sync test failure:
Failures:

  * /home/andaaron/zot/pkg/extensions/sync/sync_test.go
  Line 4857:
  Expected: digest.Digest("sha256:dc1377539a9db8bf077100bfa3118052feb6b5c67509ca09bdd841e4ac14c4cc")
  Actual:   digest.Digest("sha256:3a3fb31a422846a680f0a07b8b666bdcb1122d912d1adca79523c7bf2715996e")
  (Should equal)!

4. fix a race condition in sync by, I don't have a link, but this is the failure:

  * zotregistry.dev/zot/pkg/extensions/sync/sync_test.go
  Line 5963:
  Expected: 1
  Actual:   2
  (Should equal)!

1426 total assertions

--- FAIL: TestOnDemandPullsOnce (0.42s)
    sync_test.go:5921: Goroutine 0: Sending request to http://127.0.0.1:36421/v2/zot-test/manifests/0.0.1
    sync_test.go:5921: Goroutine 1: Sending request to http://127.0.0.1:36421/v2/zot-test/manifests/0.0.1
    sync_test.go:5921: Goroutine 4: Sending request to http://127.0.0.1:36421/v2/zot-test/manifests/0.0.1
    sync_test.go:5921: Goroutine 3: Sending request to http://127.0.0.1:36421/v2/zot-test/manifests/0.0.1
    sync_test.go:5921: Goroutine 2: Sending request to http://127.0.0.1:36421/v2/zot-test/manifests/0.0.1
FAIL
coverage: 21.4% of statements in ./...
FAIL	zotregistry.dev/zot/pkg/extensions/sync	255.189s

5. Fix flaky coverage in https://app.codecov.io/gh/project-zot/zot/pull/3465/indirect-changes

6. Stability fix for https://github.com/project-zot/zot/actions/runs/18632536285/job/53119244557?pr=3465

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-10-19 17:59:32 -07:00
Andrei Aaron dfb5d1df54 fix: make config read/write thread safe (#3432)
* fix: make config read/write thread safe and fix some other similar issues

1. The config config has a lock, and safe methods to update and read the attributes
2. The config has methods to retrieve copies of specific attributes, such as the extyensions config, the auth config, and the authz config.
These are needed, as the config object may mutate in the middle of an auth/authz requests, and we avoid partial configuration being applied for that request.
3. Fix an issue with the monitoring server not stopping when the controller is shut down.
4. Fix an issue with the HTPasswdWatcher not stopping when the background tasks are supposed to finish.
5. Fix some tests using hardcoded ports.

Moved some of the methods which were on the main config to the auth, access control and extension configs

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-10-18 11:20:58 +03:00
Luca Muscariello 2402296e9a fix: migrate to Go module v2 for proper semantic versioning (#3462)
* fix: migrate to Go module v2 for proper semantic versioning

This change updates the module path from 'zotregistry.dev/zot' to
'zotregistry.dev/zot/v2' to comply with Go's semantic versioning rules.

According to Go's module versioning requirements, major version v2+
must include the major version in the module path. The current
module path 'zotregistry.dev/zot' only supports v0.x.x and v1.x.x
versions, making existing v2.x.x tags (like v2.1.8) unusable.

Changes:
- Updated go.mod module path to zotregistry.dev/zot/v2
- Updated all internal import paths across 280+ Go source files
- Updated configuration files (golangcilint.yaml, gqlgen.yml)
- Updated README.md Go reference badge

This fix enables proper use of existing v2.x.x Git tags and allows
external packages to import zot v2+ versions without compatibility
errors.

Resolves: Go module import compatibility for v2+ versions
Fixes: #3071
Signed-off-by: Luca Muscariello <muscariello@ieee.org>

* fix: regenerate GraphQL files with updated v2 import paths

The gqlgen tool needs to regenerate the GraphQL schema files after
the module path change to use the new v2 imports.

Signed-off-by: Luca Muscariello <muscariello@ieee.org>

---------

Signed-off-by: Luca Muscariello <muscariello@ieee.org>
2025-10-16 22:43:47 -07:00
Ramkumar Chinchani 411a3d00b5 fix: update go-redsync for fips-140 compatibility (#3451)
* fix: update go-redsync for fips-140 compatibility

Fixes issue #3445

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

* fix: address comments and add a basic push-pull test

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

* fix: address comments

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

---------

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>
2025-10-13 09:34:12 +03:00
Andrei Aaron 0d42ba2744 feat: the default retention delay is not the GC delay (#3447)
Most users don't make the difference between retention deleting untagged manifests vs GC deleting other blobs.
This causes confusion since the GC delay and the retention delay (used for untagged manifests and orphan referrers) have different defaults, and are set separately in the zot configuration.
Most users don't configrue retention policies, and they still expect untagged manifests to be deleted at GC time.

With this change, if retention delay is not specified in the config file, the value used is the GC delay.
If GC delay is also unspecified in the config file, the default GC delay is used for both.

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-10-10 14:30:29 -07:00
Vishwas Rajashekar 86af38abfc feat(sessions): add support for remote redis session store (#3345)
Description
====================
zot currently stores session cookies in memory or in a local directory.
For cases where the session cookies should be independent of the
instance where they were created such as multiple instances of zot, or a
fully stateless zot instance, there is a need to support a remote
session storage.
This change adds support for using Redis and Redis-compatible services as a
remote session driver as well as introduces a new configuration option
for it.

What has changed
=======================
- New config added under Auth config to specify configuration for
  the session driver.
- Examples README updated with details of the new Auth config.
- The config supports only 2 drivers in this change - local and redis
- Using the local driver is backwards compatible and behaves the same
  way that zot currently works for local session storage.
- Omitting this config does not result in an error. In this case, zot
  behaves as it normally does for local session storage.
- When configured, zot can use redis for persisting cookie
  information for zot UI.
- The cookie in the store is deleted on logout or after the max
  expiry time for the cookie.
- Configuration for the redis session driver accepts the same configuration
  values as that of the remote meta cache.
- A separate connection is established for the session driver. An
  existing connection for meta cache will not be re-used for the
  session driver.
- A key prefix is configurable for the redis session driver. The value will be
  converted into a string for use. If no value is provided, a default
  prefix of "zotsession" will be used.
- Redis sessions does not support hash key or encryption in this change.
- New BATS test added to verify zot behavior with Redis session store.
- Github workflow updated to install valkey-tools dependency for BATS.

Signed-off-by: Vishwas Rajashekar <dev@vrajashkr.com>
2025-10-05 10:13:38 +03:00
Andrei Aaron cbbd39745c chore: stabilize coverage for specific imagestore case (#3429)
https://app.codecov.io/gh/project-zot/zot/commit/636a6b1820088c4334b02ef5d2e61a3450c4b231/indirect-changes

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-10-04 23:40:25 -07:00
Lukasz Jakimczuk 50c7fa6dd8 feat(sync): enable regclient logs (#3363)
feat: enable regclient logs

Signed-off-by: Łukasz Jakimczuk <ljakimczuk@gmail.com>
2025-10-04 11:27:27 -07:00
Ramkumar Chinchani b1842ab9e0 fix: migrate from github.com/rs/zerolog to golang-native log/slog (#3405)
* fix: migrate from github.com/rs/zerolog to golang-native log/slog

We have been using zerolog for a really long time.
golang now has structured logging using slog.
Best to move to this in interests of long-term support.

This is a tech debt item.

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

* fix: a few changes on top

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

* fix: address comments

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

---------

Signed-off-by: Ramkumar Chinchani <rchincha.dev@gmail.com>
2025-10-03 12:34:03 -07:00
Andrei Aaron 14736b8a53 ci: more sync/local driver tests to stabilize/increase coverage (#3425)
Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-10-02 09:19:43 -07:00