project-zot / zot

zot - A scale-out production-ready vendor-neutral OCI-native container image/artifact registry (purely based on OCI Distribution Specification)
https://zotregistry.dev
Apache License 2.0
913 stars 96 forks source link

[Feat]: Fine-grained, dynamic authZ policies #1692

Closed seniorquico closed 9 months ago

seniorquico commented 1 year ago

Is your feature request related to a problem? Please describe.

I would like to be able to manage fine-grained client access to assets stored in the registry in a fairly dynamic environment. For example, in my desired workflow, a user would come along and request access to something specific, an image or artifact & a specific tag. That request is reviewed and, if approved, the client can then get a credential (say a bearer token) that grants them short-lived access to the approved asset.

Describe the solution you'd like

I've only just started to read and learn about Zot. I'm not familiar enough to feel comfortable recommending a specific solution. But at a high level:

Specific to the workflow described above- I would implement the access request workflow independently of the registry (microservice thinking here). The "communication" between the access request workflow and the registry is communicated through something like claims in a bearer token. Either as a built-in feature or as an extensibility point, the bearer token is used to allow or deny access.

Possibilities:

Describe alternatives you've considered

Soliciting ideas!

Additional context

As I mentioned, I'm in the process of learning about Zot. If there is interest in something like this with an actionable direction, I'd be very interested in collaborating/contributing.

seniorquico commented 1 year ago

Adding another idea to the list of possibilities...

Issue #1149 is very interesting in this context. As an example, let's say I externally generate JWTs and specify the group(s) via a claim. An example configuration (adapted from the example on issue #1149) like the following might be sufficient to achieve a scenario close to the one described above:

"accessControl": {
  "$repository/*": {                <----
    "policies": [{
      "groups": ["$repository"],    <----
      "actions": ["read"]
    }], ...

It looks like support for groups was added for the LDAP and OIDC authentication providers through #1123 and #1381. Unfortunately, I don't have either of those systems available in my particular environment. I might also need to explore options for dynamic groups with something like JWTs.

rchincha commented 10 months ago

@seniorquico sounds like you have a "non-standard" authorization/identity provider - meaning other than OpenID.

seniorquico commented 10 months ago

@rchincha I can confirm our system does not use OpenID Connect or LDAP, if that's what you mean by "non-standard". We make heavy use of PKI and OAuth2 bearer tokens (but not OIDC).

I'm still learning a lot about the various OCI projects, the Distribution specs in particular. When I wrote this feature request, I was thinking about it from the context of needing to configure authorization policies in the zot configuration file, based on what I was reading in the docs. However, I've spent the last few months researching this topic, and I'm no longer convinced this feature request is desirable for zot.

I began to experiment with the Token Authentication Specification (Distribution Registry v2 authentication):

https://distribution.github.io/distribution/spec/auth/token/

I implemented an authorization microservice, and I've been able to successfully apply my fine-grained, dynamic permissions. Instead of configuring/teaching zot about every user, group, and role, this token authorization microservice allows me to provide the needed level of control with minimal configuration in zot.

@rchincha I am curious on your thoughts on this approach? It seems quite powerful, and isn't anywhere near as complex and running OIDC/LDAP services to connect with zot's current capabilities. I would be happy to draft and contribute a short piece to include with zot's documentation that outlines this approach and its pro and cons.

The only issue we've run into- the Token Authentication Specification is incompatible with chartmuseum's token spec, the current implementation choice of zot. This PR provides a hacky workaround:

https://github.com/project-zot/zot/pull/1814

Currently, it appears zot v2 (maybe v1?) are incompatible with the Token Authentication Specification and OCI-compliant clients (such as skopeo) that implement it.

seniorquico commented 9 months ago

We've been running an at-scale deployment of zot for a couple of months with the workaround in #1814 applied. Leveraging the Token Authentication Specification and zot's bearer authentication has demonstrated itself to be a highly scalable solution. There are no user/group configuration settings to have to put into zot's configuration file, and we don't need to make changes/restart the server as permission groups evolve. This has worked really well, and I think it keeps zot simpler to not have to manage permissions at-scale. I'm closing this issue as I don't think the original feature request, as worded, leads to a good solution. The bearer authentication is viable today.

Note: I opened #2149 to separately discuss the incompatibility issues and some broken use cases related to the Token Authentication Specification.

rchincha commented 9 months ago

@seniorquico we are looking at the issues you are reporting.

If you are using or planning to use zot in production, pls leave a note here: https://github.com/project-zot/zot/issues/2117

rchincha commented 9 months ago

@seniorquico I am not sure if you are aware of this work from client pov.

https://github.com/oras-project/oras

Gives the ability to push related but arbitrary things to zot, not just container images, such as SBOMs, CVE lists, and recently ML model data even. https://zotregistry.dev/v2.0.0/user-guides/user-guide-datapath/#common-tasks-using-oras-for-oci-artifacts

seniorquico commented 9 months ago

Yes! Very interesting. Thanks, @rchincha!