# Content Selectors and Docker

Should you wish to not share all Docker components across all teams, we recommend using content selectors in conjunction with access control (specifically the privileges created by content selectors) to manage access to specific content. However, the Docker format has some non-standard complexity to setting up security against the CLI and UI.

Before continuing, note that we provide the instructions in this section with the assumption that you are able to sort the security of your Docker images by name. Below, we use the word `team` in our examples where `team` is the representation of that which you are sorting. For example, it might be `sonatype/nexus` for this product/project team, or further `sonatype/nexus/docker` for the Docker-specific parts. If you are unable to do this, this page likely will not help you or your solution will be much more complex than the scenarios given.

## REST API vs. Docker Client

Content selectors match a path to the content stored inside of Nexus Repository. For Docker, this is more complex than other formats.

Any time you perform a client action using Docker client, it will use the actual path. However, if you perform an action through the Nexus Repository REST API, it matches to component name.

When writing content selectors for Docker, they should match both for path name and component name.

For example, if you want a content selector to match to hello-world, then your content selector should use the following:

`format == "docker" and path =~ "^(/v2/|/v2/library/)?(hello-world(/.*)?){0,1}$"`

## Commands

### docker login

This command requires access to the /v2/ path and can be established by creating a content selector with the search expression `path == "/v2/"`.

After creating the content selector, create a _Repository Content Selector_ privilege; in the _Actions_ section, enter "read" to grant read permissions. Assign this privilege to a role associated with appropriate users.

You will likely need to combine this with other privileges.

### docker search

This command requires access to the /v1/search path and can be established by creating a content selector with the search expression `path == "/v1/search"`.

**Warning**

This privilege gives those assigned access to search the entire repository which can be more than you have access to pull/push.

Further, this privilege does not give you access to search anything via UI, instead it is delegating search via the CLI. How to give permission to search via the UI is defined [below](https://help.sonatype.com/en/content-selectors-and-docker.html#search-ui "Search UI").

### docker pull (by team)

This command requires that the content selector path be restricted by `team`. This can be done loosely (e.g., `path =~ ".*/team/.*"`) with "contains team" or strictly (e.g., `path =^ "/v2/team/"`) with "starts with team." Note that for simpler docker packages, you can restrict using `library` too (e.g., `path =^ "/v2/library/hello-world/"`).

Any of these methods give you the ability to pull any version of components from `team`.

Here's an example content selector:

Content selectors and privileges will need created for each "team".

With security setup in this way, users trying docker pull commands by hash will get unauthorized responses because the hash does not fall in the pattern of the path defined above.

**Note**

`read` action grants permission to the Browse UI but only to manifests and tags (which match the path defined). Individual layers will not be shown.

The same will reflect in Content Selector preview results.

### docker push (by team)

Like _docker pull_, this command also requires that the content selector path be restricted by `team`. This can be done loosely (e.g. `path =~ ".*/team/.*"`) with "contains team" or strictly (e.g. `path =^ "/v2/team/"`) with "starts with team". Using the simpler `library` method from _docker pull_ (e.g. `path =^ "/v2/library/hello-world/"`) will not work.

Because the exact same paths can be used if you have _docker pull_ content selectors too, you can reuse them if you've implemented _docker pull_. However you need them distinct, you'd create a new content selector like this:

If you are combining permissions, edit your existing privilege _Actions_ to make it "`read,add,edit`" (comma-delimited with no whitespace).

If you are not combining, create a new _Repository Content Selector_ privilege with _Actions_ defined as "`add,edit`".

Then, assign the privilege to the appropriate roles.

Content selectors and privileges will need created (or combined/edited) for each team.

## Search UI

The permissions described in [Docker Search](https://help.sonatype.com/en/content-selectors-and-docker.html#docker-search "docker search") do not grant permission to the _Search_ UI. To gain permission to the _Search_ UI, the role needs to have the _nx-search-read_privilege assigned. In addition to this, to see the items restricted by path, the Action of `browse` needs to be added. You can do this by adding (comma delimited) to an existing privilege with the path for your team (e.g. `path =^ "/v2/team/"`, `path =~ ".*/team/.*"` or `path =^ "/v2/library/hello-world/"`) or by creating a new privilege then assigning that to roles.

Here's an example of the new privilege you would create:

If creating a new privilege, you would assign this privilege to roles and then the roles to users as needed. If editing the existing privilege, permissions will be granted when you save.
