Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

As a user I want to be able to create nested namespaces #1588

Open
grzleadams opened this issue Apr 10, 2024 · 11 comments
Open

As a user I want to be able to create nested namespaces #1588

grzleadams opened this issue Apr 10, 2024 · 11 comments
Labels

Comments

@grzleadams
Copy link

I ran into a strange behavior with respect to RBAC and it's not clear to me why it's happening. Basically, it seems like more-specific role assignments are being overridden by less-specific ones. For example:

pulp container namespace create --name myorg
pulp container namespace create --name myorg/mygroup
pulp container namespace role add --user myuser --role container.containernamespace_collaborator --name myorg/mygroup
  {
    "users": [
      "myuser"
    ],
    "groups": [],
    "role": "container.containernamespace_collaborator"
  }
docker tag ubuntu:latest pulp.mydomain/myorg/mygroup/ubuntu:latest
docker push pulp.mydomain/myorg/mygroup/ubuntu:latest
  The push refers to repository [pulp.mydomain/myorg/mygroup/ubuntu]
  5498e8c22f69: Preparing 
  denied: requested access to the resource is denied
pulp container namespace role add --user myuser --role container.containernamespace_collaborator --name myorg
  {
    "users": [
      "myuser"
    ],
    "groups": [],
    "role": "container.containernamespace_collaborator"
  }
docker push pulp.mydomain/myorg/mygroup/ubuntu:latest
  The push refers to repository [pulp.mydomain/myorg/mygroup/ubuntu]
  5498e8c22f69: Pushed 
  latest: digest: sha256:351ce29c15def43c83b9c2b5579a91aabed38af52221369d325c5aa12bf9c608 size: 529

I would expect that giving a user owner to a specific namespace (in this case, myorg/mygroup) would allow them to push images to it, but they're unable to until they also have permissions for myorg. That's kind of a bummer, because I would want to give people namespaces to use under a parent namespace, without them being able to push to the parent namespace as well. Is this behavior expected?

@lubosmj
Copy link
Member

lubosmj commented Apr 11, 2024

I do not recall if this is a bug or feature. @ipanova, would you mind chiming in?

Right now, we grab the first part of the namespace and check access permissions based on it. To me, it makes sense to find the longest prefix match and do the needful.

namespace_name = path.split("/")[0]
try:
namespace = ContainerNamespace.objects.get(name=namespace_name)
except ContainerNamespace.DoesNotExist:
# Check if user is allowed to create a new namespace
return self.has_permission(None, "POST", "create", {"name": namespace_name})

@lubosmj
Copy link
Member

lubosmj commented Apr 11, 2024

pulp user role-assignment list --username myuser | jq -r ".[].role"
container.containerdistribution_creator
container.containernamespace_consumer
container.containernamespace_owner
container.containernamespace_creator
container.containernamespace_collaborator
pulp container namespace role list --name myorg/mygroup
{
  "roles": [
    {
      "role": "container.containernamespace_creator",
      "users": [
        "myuser"
      ],
      "groups": []
    },
    {
      "role": "container.containernamespace_owner",
      "users": [
        "myuser",
        "admin"
      ],
      "groups": []
    },
    {
      "role": "container.containernamespace_collaborator",
      "users": [
        "myuser"
      ],
      "groups": []
    },
    {
      "role": "container.containernamespace_consumer",
      "users": [
        "myuser"
      ],
      "groups": []
    }
  ]
}
podman push localhost:5001/myorg/mygroup/ubuntu:latest --tls-verify=false --log-level=debug
DEBU[0000] GET http://localhost:5001/v2/                
DEBU[0000] Ping http://localhost:5001/v2/ status 401    
DEBU[0000] GET http://localhost:5001/token/?account=myuser&scope=repository%3Amyorg%2Fmygroup%2Fubuntu%3Apull%2Cpush&service=localhost%3A5001 
DEBU[0000] HEAD http://localhost:5001/v2/myorg/mygroup/ubuntu/blobs/sha256:aedc3bda2944bb9bcb6c3d475bee8b460db9a9b0f3e0b33a6ed2fd1ae0f1d445 
DEBU[0000] Detected insufficient_scope error, will retry request with updated scope 
DEBU[0000] GET http://localhost:5001/token/?account=myuser&scope=repository%3Amyorg%2Fmygroup%2Fubuntu%3Apull%2Cpush&scope=repository%3Amyorg%2Fmygroup%2Fubuntu%3Apull&service=localhost%3A5001 
DEBU[0000] HEAD http://localhost:5001/v2/myorg/mygroup/ubuntu/blobs/sha256:aedc3bda2944bb9bcb6c3d475bee8b460db9a9b0f3e0b33a6ed2fd1ae0f1d445 
DEBU[0000] ... not authorized                           
DEBU[0000] Discarding non-primary errors:               
DEBU[0000]   error parsing HTTP 401 response body: unexpected end of JSON input: "" 
DEBU[0000] Looking up image "localhost:5001/myorg/mygroup/ubuntu:latest" in local containers storage 
DEBU[0000] Normalized platform linux/amd64 to {amd64 linux  [] } 
DEBU[0000] Trying "localhost:5001/myorg/mygroup/ubuntu:latest" ... 
DEBU[0000] parsed reference into "[overlay@/home/lmjachky/.local/share/containers/storage+/run/user/106504/containers]@d3782b16ccc94322a5c5a7d004192b5daa2a1ecd61c143074e36dba844408e1c" 
DEBU[0000] Found image "localhost:5001/myorg/mygroup/ubuntu:latest" as "localhost:5001/myorg/mygroup/ubuntu:latest" in local containers storage 
Error: trying to reuse blob sha256:aedc3bda2944bb9bcb6c3d475bee8b460db9a9b0f3e0b33a6ed2fd1ae0f1d445 at destination: checking whether a blob sha256:aedc3bda2944bb9bcb6c3d475bee8b460db9a9b0f3e0b33a6ed2fd1ae0f1d445 exists in localhost:5001/myorg/mygroup/ubuntu: requested access to the resource is denied

@ipanova
Copy link
Member

ipanova commented Apr 23, 2024

Namespace is always the first part until the first occurrence of / rest is repo name.
Namespace can never contain a slash, otherwise we will not be able to distinguish and split properly the namespace and nested repos.
If the code behaves differently we should add proper validation for the namespace serializer which is missing
If namespace is instantiated from within the distribution validation is in place https://github.com/pulp/pulp_container/blob/main/pulp_container/app/serializers.py#L380

@grzleadams
Copy link
Author

grzleadams commented Apr 23, 2024

If I'm understanding you correctly and namespaces are restricted to a single "level", then it feels like there's a gap in RBAC; you can only either enforce access at the namespace level or the distribution level (which you, as an admin, may or may not know beforehand). As an admin, I would like to specify access at any "level" (i.e., user A owns <myorg>, user B can contribute new images to <myorg>/<team1> but not <myorg>/<team2>, etc).

@ipanova
Copy link
Member

ipanova commented Apr 23, 2024

Depending on the registry, namespace could be nested or have a single depth ( e.g docker registry, quay)

There is a challenge when parsing the string when content is being pushed to distinguish what is repo and what is namespace e.g

podman push library/rhel/ubi

At this stage namespace, distribution and repo are created on the fly and not beforehand.

@ipanova
Copy link
Member

ipanova commented Apr 23, 2024

i found this article worth reading https://stevelasker.blog/2020/02/17/registry-namespace-repo-names/ we might want to reconsider or not certain logic

@grzleadams
Copy link
Author

Yeah it's a tough problem because the oci spec supports nested namespaces but, as you pointed out, many registries don't. Just thinking through this though, it doesn't feel like it would be a complicated thing to support; just traverse the path given and see if any matching namespaces/distributions exist.

Basically, on push or pull (since the permissions would be applied at the same levels) of image pulp.somedomain/myorg/myteam/myimage:

  1. Check if a namespace exists matching myorg.
  2. Check if a namespace exists matching myorg/myteam.
  3. Check if a distribution exists matching myorg/myteam/myimage.
    • If so, overlay the distribution and corresponding repository permissions. Granted, I don't care much about "release manager"-type roles so I don't have a use for differentiating between the distribution and repository in the first place, so maybe there's some complexity here I'm missing.

Then just overlay the permissions in all three levels and flatten to create the permissions object.

@ipanova
Copy link
Member

ipanova commented Apr 23, 2024

We can re-purpose this as RFE request to support nested namespaces and evaluate its feasibility.

@ipanova ipanova changed the title Question about RBAC and namespaces As a user I want to be able to create nested namespaces Apr 23, 2024
@ipanova
Copy link
Member

ipanova commented Apr 23, 2024

@grzleadams when it comes to RBAC there is always some complexity ;)

@grzleadams
Copy link
Author

@grzleadams when it comes to RBAC there is always some complexity ;)

And just to be completely transparent, I have given almost zero thought as to the performance implications of this... if it increases API calls by 4x then it's probably not worth it, especially if pull-through distributions can be structured to avoid name collisions entirely (which was the main use case I had for this capability and I've spent almost no time testing, so my concerns are even just hypothetical). Life's a lot easier on the sidelines :)

@lubosmj
Copy link
Member

lubosmj commented Jun 7, 2024

Might be related to #1534.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Not Started
Development

No branches or pull requests

3 participants