oras-project / rust-oci-client

A Rust crate to interact with OCI registries
Apache License 2.0
92 stars 48 forks source link

Question: More flexible auth options? #17

Open imjasonh opened 2 years ago

imjasonh commented 2 years ago

Hello 👋 , I'm a maintainer on go-containerregistry, a fairly widely used Go client library for dealing with Docker/OCI registries and images. I'm starting to contribute to some Rust projects handling OCI images, using this crate. First of all, nice work! Thanks for sharing this!

Next, a question: Do you all have any interest in having this crate include more complex auth handling code? go-containerregistry provides pkg/authn which provides interfaces and some simple implementations for common scenarios, and support for plugging in your own auth.

The most commonly used is authn.DefaultKeychain which reads and parses the Docker config file (normally ~/.docker/config.json) to determine which auth to use for the requested registry, including basic auth configured in the config file, but it also supports cred helpers, credsStores, etc.

There's also authn.NewMultiKeychain which supports using multiple keychains, and a Google-specific google.Keychain which emulates the GCR cred helper to get auth creds using gcloud or other ambient creds in the environment. Other cloud registries can also be supported fairly easily.

So a user of the Go client could specify:

kc := authn.NewMultiKeychain(
    authn.DefaultKeychain,
    google.Keychain,
)
img, err := remote.Image(ref, remote.WithAuthFromKeychain(kc))

...which would communicate, "check for creds configured in ~/.docker/config.json, or look for ambient Google credentials, or fallback to anonymous."

Anyway, back to my question 🙃 -- is there any interest in supporting any of these sorts of things in this crate? Specifically, do you have plans to provide a mechanism for providing other RegistryAuth implementations, beyond the current Anonymous and Basic? I'd be happy to contribute either in terms of code, or code reviews, or ideas, or just commiserating over how awful everything is. But I wanted to make sure there was interest before going too far down the path.

I'm imagining something like:

let auth: RegistryAuth = RegistryAuth::Default;

or

let auth: RegistryAuth = RegistryAuth::MultiAuth(
    RegistryAuth::Default,
    some::other::crate::GoogleRegistryAuth,
)

I'm very new to Rust (as you may be able to tell from the above code snippets!), but this seems like a good opportunity to learn and contribute. Let me know what you think!

flavio commented 2 years ago

@imjasonh sorry for the delay. I think I would be happy to see such contributions.

I would personally appreciate to see something like authn.DefaultKeychain show up as a first "extension" :)

imjasonh commented 2 years ago

So I finally got some time to play around with this, and thanks to help from @hasheddan even made some progress. It's my first real Rust, so PTAL and laugh/jeer as appropriate: https://github.com/krustlet/oci-distribution/compare/main...imjasonh:docker-config

I still need to exercise this a bit more to figure out what obvious mistakes I've made, but it seemed worth sharing at least. Let me know if it looks promising and I'll send a PR when it's baked a bit more.

thomastaylor312 commented 2 years ago

@imjasonh Hey there! So the notification for this comment got totally lost in the ether (hence why I am responding...now). This actually looks real nice! There are a few rust-y things I can help walk you though if you open a PR, but this looked like a great start! If you'd like to, feel free to open a draft PR and we can review it/help from there

imjasonh commented 2 years ago

Cool, I've opened https://github.com/krustlet/oci-distribution/pull/39 and we can go from there. Full disclosure, most of my use for this existing in Rust has evaporated since March, so I might not have a strong need for it immediately.

I'd still like to push it forward, but that just means "meh let's just drop it for now" is a totally fine outcome for me. :)