Chore/sign backend images#8
Conversation
Close a trust gap where a registry compromise or MITM could silently replace a backend image: the gallery YAML tells LocalAI which image to pull, but until now nothing verified the bytes came from our CI. Consumer (pkg/oci/cosignverify): - New package using sigstore-go to verify keyless-cosign signatures. - OCI 1.1 referrers API + new bundle format (no legacy :tag.sig). - Policy fields: Issuer / IssuerRegex / Identity / IdentityRegex / NotBefore. NotBefore is the revocation lever — keyless Fulcio certs are ephemeral so revocation is policy-side; advancing not_before in the gallery YAML invalidates every signature predating the cutoff. - TUF trusted root cached process-wide so N backends from one gallery do 1 fetch, not N. Plumbing: - pkg/downloader: ImageVerifier interface + WithImageVerifier option threaded through DownloadFileWithContext. Verification runs between oci.GetImage and oci.ExtractOCIImage, with digest pinning via pinnedImageRef to close the TOCTOU window. Skips the verifier's HEAD when the ref is already digest-pinned. - core/config: Gallery.Verification YAML block. - core/gallery: backendDownloadOptions builds the verifier from the policy; applied on initial URI, mirrors, and tag fallbacks. - core/gallery/upgrade: the upgrade path now routes through the same options builder. A regression Ginkgo spec pins this contract — without it, UpgradeBackend silently bypassed verification. - core/cli: --require-backend-integrity (LOCALAI_REQUIRE_BACKEND_INTEGRITY) escalates missing policy / empty SHA256 from warn to hard-fail. Producer (.github/workflows/backend_merge.yml): - id-token: write at job scope (PR-fork-safe via existing event gate). - sigstore/cosign-installer@v3 pinned to v2.4.1. - After each docker buildx imagetools create, resolve the manifest list digest and run cosign sign --recursive --new-bundle-format --registry-referrers-mode=oci-1-1 against repo@digest. --recursive signs the index and every per-arch entry, matching how the consumer resolves a tag to a platform-specific manifest before verifying. Rollout: backend/index.yaml has no `verification:` block yet, so this PR is backward-compatible — installs proceed with a warning until the gallery is populated. Strict mode is opt-in. Assisted-by: claude-code:claude-opus-4-7 [Bash] [Edit] [Read] [Write] [WebSearch] [WebFetch] Signed-off-by: Richard Palethorpe <io@richiejp.com>
…ad of env The previous implementation re-exported the --require-backend-integrity CLI flag into LOCALAI_REQUIRE_BACKEND_INTEGRITY via os.Setenv, then re-read it in core/gallery via os.Getenv. This leaked process state into the gallery package and made the flag impossible to override per-call or test without touching the env. Add RequireBackendIntegrity to ApplicationConfig (with a matching WithRequireBackendIntegrity AppOption) and thread the bool through every install/upgrade path: InstallBackend, InstallBackendFromGallery, UpgradeBackend, InstallModelFromGallery, InstallExternalBackend, ApplyGalleryFromString/File, startup.InstallModels. Worker subcommands gain the same env-bound flag on WorkerFlags so distributed-worker installs honor it consistently with the worker daemon path. Add a forbidigo lint rule against os.Getenv / os.LookupEnv / os.Environ to keep the env-leak pattern from creeping back. Existing offenders (p2p, config loaders, etc.) are baseline-grandfathered by the existing new-from-merge-base: origin/master setting; targeted path exclusions cover the legitimate cases — kong CLI entry points, backend subprocesses, system capability probes, gRPC AUTH_TOKEN inheritance, test gating env vars. Assisted-by: claude-code:claude-opus-4-7 Signed-off-by: Richard Palethorpe <io@richiejp.com>
Policy Check Failed✗ 3/3 policy checks failed: • Need 2 more approval(s) (0/2) — comment LGTM or approve via review To merge this PR:
|
PR SummaryWhat Changed
Key Changes by AreaSecurity & Verification
CLI & Config
Backend Operations
CI/CD
Files Changed
Review Focus Areas
ArchitectureDesign Decisions
Scalability & Extensibility
Risks
Merge StatusNOT MERGEABLE — PR Score 44/100, below threshold (50)
|
| func processRequests(systemState *system.SystemState, modelLoader *model.ModelLoader, enforceScan, automaticallyInstallBackend bool, galleries []config.Gallery, backendGalleries []config.Gallery, requests []galleryModel, requireBackendIntegrity bool) error { | ||
| ctx := context.Background() | ||
| var err error | ||
| for _, r := range requests { | ||
| utils.ResetDownloadTimers() | ||
| if r.ID == "" { | ||
| err = installModelFromRemoteConfig(ctx, systemState, modelLoader, r.GalleryModel, utils.DisplayDownloadFunction, enforceScan, automaticallyInstallBackend, backendGalleries) | ||
| err = installModelFromRemoteConfig(ctx, systemState, modelLoader, r.GalleryModel, utils.DisplayDownloadFunction, enforceScan, automaticallyInstallBackend, backendGalleries, requireBackendIntegrity) | ||
|
|
||
| } else { | ||
| err = gallery.InstallModelFromGallery( | ||
| ctx, galleries, backendGalleries, systemState, modelLoader, r.ID, r.GalleryModel, utils.DisplayDownloadFunction, enforceScan, automaticallyInstallBackend) | ||
| ctx, galleries, backendGalleries, systemState, modelLoader, r.ID, r.GalleryModel, utils.DisplayDownloadFunction, enforceScan, automaticallyInstallBackend, requireBackendIntegrity) | ||
| } | ||
| } |
There was a problem hiding this comment.
The loop keeps processing later requests after an installation error, so return immediately on failure instead of only returning the last error.
Suggested fix
func processRequests(systemState *system.SystemState, modelLoader *model.ModelLoader, enforceScan, automaticallyInstallBackend bool, galleries []config.Gallery, backendGalleries []config.Gallery, requests []galleryModel, requireBackendIntegrity bool) error {
ctx := context.Background()
for _, r := range requests {
utils.ResetDownloadTimers()
var err error
if r.ID == "" {
err = installModelFromRemoteConfig(ctx, systemState, modelLoader, r.GalleryModel, utils.DisplayDownloadFunction, enforceScan, automaticallyInstallBackend, backendGalleries, requireBackendIntegrity)
} else {
err = gallery.InstallModelFromGallery(
ctx, galleries, backendGalleries, systemState, modelLoader, r.ID, r.GalleryModel, utils.DisplayDownloadFunction, enforceScan, automaticallyInstallBackend, requireBackendIntegrity)
}
if err != nil {
return err
}
}
return nil
}Prompt for AI assistance
Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:
You are an expert go developer with deep knowledge of security, performance, and best practices.
### Context
File: core/services/galleryop/models.go
Lines: 153-165
Issue Type: functional-high
Severity: high
Issue Description:
The loop keeps processing later requests after an installation error, so return immediately on failure instead of only returning the last error.
Current Code:
func processRequests(systemState *system.SystemState, modelLoader *model.ModelLoader, enforceScan, automaticallyInstallBackend bool, galleries []config.Gallery, backendGalleries []config.Gallery, requests []galleryModel, requireBackendIntegrity bool) error {
ctx := context.Background()
var err error
for _, r := range requests {
utils.ResetDownloadTimers()
if r.ID == "" {
err = installModelFromRemoteConfig(ctx, systemState, modelLoader, r.GalleryModel, utils.DisplayDownloadFunction, enforceScan, automaticallyInstallBackend, backendGalleries, requireBackendIntegrity)
} else {
err = gallery.InstallModelFromGallery(
ctx, galleries, backendGalleries, systemState, modelLoader, r.ID, r.GalleryModel, utils.DisplayDownloadFunction, enforceScan, automaticallyInstallBackend, requireBackendIntegrity)
}
}
return err
}
---
### Instructions
1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow go best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed
### Constraints
- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready
---
| # shellcheck disable=SC2086 | ||
| docker buildx imagetools create $tags \ | ||
| $(printf 'quay.io/go-skynet/ci-cache@sha256:%s ' *) | ||
| # Resolve the manifest-list digest (any tag points at it) so | ||
| # cosign can sign by digest. Signing by tag would leave the | ||
| # signature orphaned the next time the tag moves. | ||
| first_tag=$(jq -cr ' | ||
| .tags | map(select(startswith("quay.io/"))) | .[0] | ||
| ' <<< "$DOCKER_METADATA_OUTPUT_JSON") | ||
| digest=$(docker buildx imagetools inspect "$first_tag" --format '{{.Manifest.Digest}}') | ||
| # --recursive walks the list and signs every per-arch entry | ||
| # too — clients that resolve a tag to a platform-specific | ||
| # manifest before checking signatures need the per-arch | ||
| # signatures, not just the list-level one. | ||
| cosign sign --yes --recursive \ | ||
| --new-bundle-format \ | ||
| --registry-referrers-mode=oci-1-1 \ | ||
| "quay.io/go-skynet/local-ai-backends@${digest}" |
There was a problem hiding this comment.
The * glob is used without validating that /tmp/digests contains only sha256 filenames, so reject unexpected names before passing them to imagetools create.
Also reported at: .github/workflows/backend_merge.yml L175–L185
Suggested fix
shopt -s nullglob
digests=()
for f in *; do
[[ "$f" =~ ^[a-f0-9]{64}$ ]] || { echo "Unexpected digest file: $f"; exit 1; }
digests+=("quay.io/go-skynet/ci-cache@sha256:$f")
done
[ ${#digests[@]} -gt 0 ] || { echo "No digest files found"; exit 1; }
docker buildx imagetools create $tags "${digests[@]}"
first_tag=$(jq -cr '
.tags | map(select(startswith("quay.io/"))) | .[0]
' <<< "$DOCKER_METADATA_OUTPUT_JSON")
digest=$(docker buildx imagetools inspect "$first_tag" --format '{{.Manifest.Digest}}')
cosign sign --yes --recursive \
--new-bundle-format \
--registry-referrers-mode=oci-1-1 \
"quay.io/go-skynet/local-ai-backends@${digest}"Prompt for AI assistance
Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:
You are an expert bash developer with deep knowledge of security, performance, and best practices.
### Context
File: .github/workflows/backend_merge.yml
Lines: 141-158
Issue Type: robustness-medium
Severity: medium
Issue Description:
The `*` glob is used without validating that `/tmp/digests` contains only sha256 filenames, so reject unexpected names before passing them to `imagetools create`.
_Also reported at: `.github/workflows/backend_merge.yml` L175–L185_
Current Code:
# shellcheck disable=SC2086
docker buildx imagetools create $tags \
$(printf 'quay.io/go-skynet/ci-cache@sha256:%s ' *)
# Resolve the manifest-list digest (any tag points at it) so
# cosign can sign by digest. Signing by tag would leave the
# signature orphaned the next time the tag moves.
first_tag=$(jq -cr '
.tags | map(select(startswith("quay.io/"))) | .[0]
' <<< "$DOCKER_METADATA_OUTPUT_JSON")
digest=$(docker buildx imagetools inspect "$first_tag" --format '{{.Manifest.Digest}}')
# --recursive walks the list and signs every per-arch entry
# too — clients that resolve a tag to a platform-specific
# manifest before checking signatures need the per-arch
# signatures, not just the list-level one.
cosign sign --yes --recursive \
--new-bundle-format \
--registry-referrers-mode=oci-1-1 \
"quay.io/go-skynet/local-ai-backends@${digest}"
---
### Instructions
1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow bash best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed
### Constraints
- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready
---
| rc, err := layers[0].Uncompressed() | ||
| if err != nil { | ||
| return nil, fmt.Errorf("opening referrer blob: %w", err) | ||
| } | ||
| defer func() { _ = rc.Close() }() | ||
|
|
||
| data, err := io.ReadAll(rc) |
There was a problem hiding this comment.
The bundle blob is read with io.ReadAll without enforcing desc.Size, so cap the read to the advertised size and reject oversized artifacts.
Suggested fix
rc, err := layers[0].Uncompressed()
if err != nil {
return nil, fmt.Errorf("opening referrer blob: %w", err)
}
defer func() { _ = rc.Close() }()
if desc.Size <= 0 {
return nil, errors.New("referrer artifact has invalid size")
}
data, err := io.ReadAll(io.LimitReader(rc, desc.Size))
if err != nil {
return nil, fmt.Errorf("reading referrer blob: %w", err)
}Prompt for AI assistance
Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:
You are an expert go developer with deep knowledge of security, performance, and best practices.
### Context
File: pkg/oci/cosignverify/bundle.go
Lines: 99-105
Issue Type: security-medium
Severity: medium
Issue Description:
The bundle blob is read with io.ReadAll without enforcing desc.Size, so cap the read to the advertised size and reject oversized artifacts.
Current Code:
rc, err := layers[0].Uncompressed()
if err != nil {
return nil, fmt.Errorf("opening referrer blob: %w", err)
}
defer func() { _ = rc.Close() }()
data, err := io.ReadAll(rc)
---
### Instructions
1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow go best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed
### Constraints
- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready
---
Security Scan Summary
No critical security issues detected Scan completed in 106.6sSecurity scan powered by Codity.ai |
Greptile SummaryThis PR introduces end-to-end keyless cosign signature verification for LocalAI's OCI backend images, covering both the producer side (CI signs each pushed manifest list with
Confidence Score: 3/5Core security logic is sound but the TUF cache can lock a running server into a permanently-errored state after a single transient failure, silently disabling integrity enforcement without a process restart. The cosignverify package does the right things: manifest digest pinning before verification, artifact binding to exact bytes in memory, and the opt-in flag keeps existing deployments unaffected. The UpgradeBackend SHA256 fix is a genuine improvement. The main concern is loadTrustedMaterial's sync.Once permanently caching TUF errors: for a long-running server with --require-backend-integrity, one transient TUF fetch failure blocks all future installs for that process lifetime. pkg/oci/cosignverify/verify.go — the loadTrustedMaterial sync.Once error-caching behaviour and the stale VerifyImage doc comment; pkg/oci/cosignverify/bundle.go — single-bundle-attempt logic in bundleFromOCISignature Important Files Changed
Sequence DiagramsequenceDiagram
participant CLI as CLI / Startup
participant BD as backendDownloadOptions
participant DL as pkg/downloader URI
participant REG as OCI Registry
participant CV as cosignverify.Verifier
participant TUF as Sigstore TUF Mirror
participant REKOR as Rekor Log
CLI->>BD: InstallBackend(config, requireIntegrity)
BD->>BD: Check Gallery.Verification
alt "No verification policy + requireIntegrity=true"
BD-->>CLI: error (strict integrity)
else Verification policy present
BD->>CV: NewVerifier(policy)
BD-->>DL: WithImageVerifier(verifier)
end
DL->>REG: GetImage(url) fetch manifest
REG-->>DL: img (manifest resolved)
DL->>DL: img.Digest() pinned ref
DL->>CV: VerifyImage(pinned at digest)
CV->>TUF: loadTrustedMaterial (once per process)
TUF-->>CV: trusted_root.json
CV->>REG: Referrers(digest) locate Sigstore bundle
REG-->>CV: OCI 1.1 referrers index
CV->>REG: fetch bundle artifact layer
REG-->>CV: Sigstore bundle JSON
CV->>REKOR: verify inclusion proof (via sigstore-go)
REKOR-->>CV: verified
CV->>CV: check Fulcio cert identity (issuer + SAN regex)
CV->>CV: enforceNotBefore (if set)
CV-->>DL: nil (verified)
DL->>REG: ExtractOCIImage(img) layer pull + unpack
REG-->>DL: layers extracted to disk
Reviews (1): Last reviewed commit: "refactor(gallery): plumb RequireBackendI..." | Re-trigger Greptile |
| func (v *Verifier) loadTrustedMaterial() (root.TrustedMaterialCollection, error) { | ||
| key := trustedMaterialCacheKey{URL: v.policy.TUFRootURL, Path: v.policy.TUFCachePath} | ||
| val, _ := trustedMaterialCache.LoadOrStore(key, &trustedMaterialEntry{}) | ||
| entry := val.(*trustedMaterialEntry) | ||
| entry.once.Do(func() { | ||
| opts := tuf.DefaultOptions() | ||
| if v.policy.TUFRootURL != "" { | ||
| opts.RepositoryBaseURL = v.policy.TUFRootURL | ||
| } | ||
| if v.policy.TUFCachePath != "" { | ||
| opts.CachePath = v.policy.TUFCachePath | ||
| } | ||
| client, err := tuf.New(opts) | ||
| if err != nil { | ||
| entry.err = fmt.Errorf("cosignverify: initialising TUF client: %w", err) | ||
| return | ||
| } | ||
| trustedRootJSON, err := client.GetTarget("trusted_root.json") | ||
| if err != nil { | ||
| entry.err = fmt.Errorf("cosignverify: fetching trusted_root.json: %w", err) | ||
| return | ||
| } | ||
| tr, err := root.NewTrustedRootFromJSON(trustedRootJSON) | ||
| if err != nil { | ||
| entry.err = fmt.Errorf("cosignverify: parsing trusted root: %w", err) | ||
| return | ||
| } | ||
| entry.material = root.TrustedMaterialCollection{tr} | ||
| }) | ||
| return entry.material, entry.err |
There was a problem hiding this comment.
TUF cache permanently poisons on first error
loadTrustedMaterial stores a *trustedMaterialEntry in a sync.Map and initialises it exactly once via sync.Once. If tuf.New or client.GetTarget("trusted_root.json") fails (network blip, cold start before DNS resolves, transient Sigstore CDN hiccup), entry.err is set and the sync.Once is marked done. Every subsequent call for the same (TUFRootURL, TUFCachePath) key returns that same cached error forever for the life of the process, with no way to recover short of a restart.
For a long-running server that opts in to --require-backend-integrity, a single transient TUF failure at the moment of the first backend install permanently disables all future installs until the process is restarted. Consider storing the entry under the key only after a successful initialisation so a future call can retry.
| // VerifyImage resolves imageRef to its manifest digest, fetches the cosign | ||
| // signature attachment (the conventional `:sha256-<hex>.sig` tag), assembles | ||
| // a Sigstore bundle from the cosign annotations, and verifies that bundle | ||
| // against the configured Policy. | ||
| // | ||
| // Returns nil on the first signature in the attachment that satisfies the | ||
| // policy. Returns an error if none do, or if any part of the fetch fails. |
There was a problem hiding this comment.
The doc comment still describes the legacy cosign approach (
:sha256-<hex>.sig tag + per-annotation assembly) rather than the OCI 1.1 referrers / new-bundle-format path that this implementation actually uses.
| // VerifyImage resolves imageRef to its manifest digest, fetches the cosign | |
| // signature attachment (the conventional `:sha256-<hex>.sig` tag), assembles | |
| // a Sigstore bundle from the cosign annotations, and verifies that bundle | |
| // against the configured Policy. | |
| // | |
| // Returns nil on the first signature in the attachment that satisfies the | |
| // policy. Returns an error if none do, or if any part of the fetch fails. | |
| // VerifyImage resolves imageRef to its manifest digest, discovers the | |
| // cosign Sigstore bundle via the OCI 1.1 referrers API (new-bundle-format), | |
| // and verifies that bundle against the configured Policy using sigstore-go. | |
| // | |
| // The image ref is pinned to a digest by the caller (pkg/downloader) before | |
| // this is invoked, so the verifier skips a second HEAD and binds the bundle | |
| // directly to the manifest bytes already in memory. | |
| // | |
| // Returns nil when the bundle satisfies the policy (identity, transparency | |
| // log, SCT, and optional NotBefore). Returns an error otherwise. |
|
|
||
| var lastErr error | ||
| for _, desc := range manifest.Manifests { | ||
| if !isSigstoreBundleArtifactType(string(desc.ArtifactType)) { | ||
| continue | ||
| } | ||
| b, err := fetchBundleFromReferrer(ref, desc, opts) | ||
| if err != nil { | ||
| lastErr = err | ||
| continue | ||
| } | ||
| return b, nil | ||
| } | ||
| if lastErr != nil { | ||
| return nil, fmt.Errorf("cosignverify: no usable Sigstore bundle referrer for %s: %w", digestRef.Name(), lastErr) | ||
| } | ||
| return nil, fmt.Errorf("cosignverify: no Sigstore bundle referrer for %s (signed with --new-bundle-format?)", digestRef.Name()) | ||
| } | ||
|
|
||
| func fetchBundleFromReferrer(ref name.Reference, desc v1.Descriptor, opts []remote.Option) (*bundle.Bundle, error) { |
There was a problem hiding this comment.
First parseable bundle wins; verification failure is not retried against remaining bundles
bundleFromOCISignature returns the first referrer whose JSON parses successfully and hands it to sev.Verify in VerifyImage. If that bundle fails identity verification, VerifyImage returns an error immediately without cycling through any remaining Sigstore bundles in the referrers list. In the current CI setup this is fine, but a re-signed image with multiple bundles could fail even if a valid bundle exists later in the referrers index.
Dependency vulnerability scanning
View vulnerability details (1 items)1. brace-expansion various CVE: GHSA-f886-m6hf-6m8v
Powered by Codity.ai · Docs |
Dependency vulnerability scanning
View vulnerability details (4 items)1. pip 24.0 CVE: GHSA-4xh5-x5gv-qwph
2. pip 24.0 CVE: GHSA-6vgw-5pg2-w6jp
3. pip 24.0 CVE: GHSA-58qw-9mgm-455v
4. pip 24.0 CVE: GHSA-jp4c-xjxw-mgf9
Powered by Codity.ai · Docs |
License Compliance Scan
Weak copyleft licenses found - verify compatibility Some packages have unknown licenses - manual review required Medium Risk Licenses - 6 packages(MPL-2.0 OR Apache-2.0) (1 packages):
MPL-2.0 (5 packages):
Unknown Licenses - 155 packages
...and 135 more Powered by Codity.ai · Docs |
Code Quality Report — test-org-codity/LocalAI · PR #8Scanned: 2026-05-21 12:55 UTC | Score: 23/100 | Provider: github Executive Summary
Top Findings[CQ-LLM-002]
|
| File | Critical | High | Medium | Low | Total |
|---|---|---|---|---|---|
.agents/adding-backends.md |
0 | 0 | 0 | 2 | 2 |
.agents/backend-signing.md |
0 | 0 | 1 | 2 | 3 |
.github/workflows/backend_merge.yml |
0 | 0 | 2 | 0 | 2 |
.golangci.yml |
0 | 0 | 0 | 1 | 1 |
AGENTS.md |
0 | 0 | 0 | 1 | 1 |
core/application/startup.go |
0 | 0 | 0 | 4 | 4 |
core/backend/llm.go |
0 | 0 | 0 | 1 | 1 |
core/cli/backends.go |
0 | 0 | 0 | 6 | 6 |
core/cli/models.go |
0 | 0 | 0 | 2 | 2 |
core/cli/run.go |
0 | 0 | 0 | 1 | 1 |
core/cli/worker/worker.go |
0 | 0 | 0 | 5 | 5 |
core/cli/worker/worker_backend_common.go |
0 | 0 | 0 | 1 | 1 |
core/cli/worker/worker_llamacpp.go |
0 | 0 | 0 | 1 | 1 |
core/cli/worker/worker_mlx_common.go |
0 | 0 | 0 | 1 | 1 |
core/config/gallery.go |
0 | 0 | 0 | 1 | 1 |
core/gallery/backends.go |
0 | 0 | 0 | 7 | 7 |
core/gallery/backends_test.go |
0 | 0 | 0 | 3 | 3 |
core/gallery/models.go |
0 | 0 | 0 | 2 | 2 |
core/gallery/models_test.go |
0 | 0 | 0 | 1 | 1 |
core/gallery/upgrade.go |
0 | 0 | 0 | 3 | 3 |
core/services/galleryop/backends.go |
0 | 0 | 0 | 2 | 2 |
core/services/galleryop/managers_local.go |
0 | 0 | 0 | 1 | 1 |
core/services/galleryop/models.go |
0 | 0 | 0 | 9 | 9 |
core/services/worker/config.go |
0 | 0 | 0 | 5 | 5 |
core/services/worker/install.go |
0 | 0 | 0 | 2 | 2 |
core/startup/model_preload.go |
0 | 0 | 0 | 4 | 4 |
core/startup/model_preload_test.go |
0 | 0 | 0 | 2 | 2 |
go.mod |
0 | 0 | 0 | 6 | 6 |
go.sum |
0 | 0 | 0 | 41 | 41 |
pkg/downloader/pinned_ref_internal_test.go |
0 | 0 | 0 | 2 | 2 |
pkg/downloader/uri.go |
0 | 0 | 0 | 2 | 2 |
pkg/oci/cosignverify/bundle.go |
0 | 0 | 0 | 1 | 1 |
pkg/oci/cosignverify/notbefore_internal_test.go |
0 | 0 | 0 | 1 | 1 |
pkg/oci/cosignverify/verify_test.go |
0 | 0 | 0 | 2 | 2 |
Recommendations
- Run automated tests after applying fixes to verify no regressions.
Description
This PR fixes #
Notes for Reviewers
Signed commits