You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This issue tracks the full migration of the ORAS CLI from oras.land/oras-go/v2 to github.com/oras-project/oras-go/v3. The migration is broken into three phases:
Deprecation cleanup — remove duplicated internal code now first-class in v3
New feature adoption — unlock user-facing capabilities provided by v3
Motivation
oras-go v3 introduces a new module path, several breaking API renames, and new packages that provide capabilities the ORAS CLI currently either lacks entirely or implements through duplicated custom code. The primary user-facing motivation is support for the standard containers configuration file stack:
containers/image configuration files supported by oras-go v3
Registry mirrors, blocked registries, and location remapping are applied automatically on every pull — critical for air-gapped and enterprise deployments
SetReferrersCapability() — void, no longer returns error
✅ Done
Phase 2 — Deprecation Cleanup (follow-on PRs)
Remove internal code that is now first-class in oras-go v3.
#
Task
Files
Net LOC
Notes
2.1
oci.New() → oci.NewStorage() in cache
option/cache.go
−2
Fixes concurrent-write safety bug for shared ORAS_CACHE
2.2
Delete internal/cache/; use oras-go/content/cache
internal/cache/, option/cache.go
−100
Library now ships CacheReadOnlyTarget with correct oci.NewStorage() backing
2.3
Replace custom handleWarning() with remote.NewWarningLogger()
option/remote.go
−25
Requires slog→logrus bridge (~15 lines) since v3 uses *slog.Logger
2.4
Replace internal/trace/transport.go with remote.NewLoggingTransport() via ClientBuilder.Logger
internal/trace/, option/remote.go
−160
Same header scrubbing + body cap; adds request IDs for concurrent correlation
Phase 3 — New Feature Adoption (follow-on PRs)
3.1 ClientBuilder + properties.Registry in NewRepository()/NewRegistry()
Replace the 40+ line manual assembly of tls.Config → http.Transport → retry.Transport → auth.Client with ClientBuilder, which handles TLS, retry, credentials, user-agent, and debug logging in one place.
3.2 config.LoadConfigs() — Full Ecosystem Config Stack
Use config.LoadConfigs() as the baseline for registry configuration, then override with CLI flags. This is the key change that unlocks the containers config-file ecosystem:
CLI flags continue to take highest priority — no change in behavior for users who specify flags explicitly.
Capabilities unlocked at zero additional CLI surface:
Podman users: podman login-saved credentials work automatically
Enterprise/air-gapped: registries.conf mirrors tried on every pull, no config needed
Operators: per-registry CA certs from certs.d load without --ca-file
Future flags (separate PRs):
--registries-config — override path to registries.conf
--policy-file — override path to policy.json
3.3 oras.CopyError Structured Error Handling
Wrap oras.Copy() failures with *oras.CopyError to produce actionable messages distinguishing source from destination failures in oras cp, oras push, oras pull, and oras attach.
Phase 4 — Future Work (separate design required)
Capability
oras-go Package
Notes
Policy enforcement (--policy-file)
registry/remote/policy
Requires UX design for insecureAcceptAnything / reject / signedBy rules
OpenPGP signature verification
registry/remote/signature
Depends on registries.d config and lookaside store support
objects package for push/pack
objects
Higher-level alternative to PackManifest; consider for oras push simplification
Overview
This issue tracks the full migration of the ORAS CLI from
oras.land/oras-go/v2togithub.com/oras-project/oras-go/v3. The migration is broken into three phases:Motivation
oras-go v3 introduces a new module path, several breaking API renames, and new packages that provide capabilities the ORAS CLI currently either lacks entirely or implements through duplicated custom code. The primary user-facing motivation is support for the standard containers configuration file stack:
containers/image configuration files supported by oras-go v3
containers-auth.json~/.config/containers/auth.jsonconfig.json— no--registry-configflag neededcontainers-registries.conf/etc/containers/registries.confcontainers-certs.d/etc/containers/certs.d/<host>/--ca-fileflagsBeyond the config-file ecosystem, full v3 adoption also:
ORAS_CACHEpath (oci.New()is not safe for concurrent process writes)internal/cache/,internal/trace/transport.go)oras cpthat distinguish source from destination failuresPhases & Timeline
Phase 1 — Mechanical API Migration (PR #2002)
Replace all
oras.land/oras-go/v2imports withgithub.com/oras-project/oras-go/v3and update all breaking call sites.oras.land/oras-go/v2→github.com/oras-project/oras-go/v3auth.Credential{}→credentials.Credential{}auth.EmptyCredential→credentials.EmptyCredentialclient.Credential =→client.CredentialFunc =credentials.Credential(store)→store.Getcredentials.Login/Logout→remote.Login/Logoutrepo.Client/PlainHTTP/HandleWarning→repo.Registry.*repo.Reference.Repository→repo.RepositoryNameref.Reference(field) →ref.GetReference()(method)SetReferrersCapability()— void, no longer returns errorPhase 2 — Deprecation Cleanup (follow-on PRs)
Remove internal code that is now first-class in oras-go v3.
oci.New()→oci.NewStorage()in cacheoption/cache.goORAS_CACHEinternal/cache/; useoras-go/content/cacheinternal/cache/,option/cache.goCacheReadOnlyTargetwith correctoci.NewStorage()backinghandleWarning()withremote.NewWarningLogger()option/remote.go*slog.Loggerinternal/trace/transport.gowithremote.NewLoggingTransport()viaClientBuilder.Loggerinternal/trace/,option/remote.goPhase 3 — New Feature Adoption (follow-on PRs)
3.1
ClientBuilder+properties.RegistryinNewRepository()/NewRegistry()Replace the 40+ line manual assembly of
tls.Config → http.Transport → retry.Transport → auth.ClientwithClientBuilder, which handles TLS, retry, credentials, user-agent, and debug logging in one place.3.2
config.LoadConfigs()— Full Ecosystem Config StackUse
config.LoadConfigs()as the baseline for registry configuration, then override with CLI flags. This is the key change that unlocks the containers config-file ecosystem:CLI flags continue to take highest priority — no change in behavior for users who specify flags explicitly.
Capabilities unlocked at zero additional CLI surface:
podman login-saved credentials work automaticallyregistries.confmirrors tried on every pull, no config neededcerts.dload without--ca-fileFuture flags (separate PRs):
--registries-config— override path toregistries.conf--policy-file— override path topolicy.json3.3
oras.CopyErrorStructured Error HandlingWrap
oras.Copy()failures with*oras.CopyErrorto produce actionable messages distinguishing source from destination failures inoras cp,oras push,oras pull, andoras attach.Phase 4 — Future Work (separate design required)
--policy-file)registry/remote/policyinsecureAcceptAnything/reject/signedByrulesregistry/remote/signatureregistries.dconfig and lookaside store supportobjectspackage for push/packobjectsPackManifest; consider fororas pushsimplificationImplementation Order
oci.New()→oci.NewStorage()internal/cache/internal/logutil/)remote.NewWarningLogger()ClientBuilderinNewRepository()/NewRegistry()config.LoadConfigs()full config stackremote.NewLoggingTransport()viabuilder.Loggeroras.CopyErrorstructured errorsReferences