# Content Selectors not working in multi-tenant environment

**URL:** https://community.sonatype.com/t/content-selectors-not-working-in-multi-tenant-environment/8682
**Category:** Sonatype Nexus Repository
**Tags:** content-selector, nexus-v3
**Created:** [May 18, 2022, 2:38am UTC](https://community.sonatype.com/t/content-selectors-not-working-in-multi-tenant-environment/8682 "2022-05-18T02:38:43Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![matthew.rabey](https://avatars.discourse-cdn.com/v4/letter/m/e480ec/32.png) [@matthew.rabey](https://community.sonatype.com/u/matthew.rabey)
#### Post date: [May 18, 2022, 2:38am UTC](https://community.sonatype.com/t/content-selectors-not-working-in-multi-tenant-environment/8682/1 "2022-05-18T02:38:44Z")

</div>

**Overview**  
I manage a Nexus 3 OSS version (3.30.1-01) that has multiple companies uploading their dependencies to their own repositories. There are certain dependencies within their repositories that should be accessible by other companies, while keeping everything else private. I have read through all the documentation, scoured the internet for articles covering this topic, and read Nexus developer articles covering how to implement this. However, I have not been able to get Content Selectors working to solve this problem.

**Desired Result**  
When Company A adds a dependency from Company B’s hosted repository to their Maven `pom.xml` file and they have the appropriate read access, the build should complete properly as it locates the dependency in Company A’s group repository. If Company A adds a dependency from Company B’s hosted repository to their Maven `pom.xml` file they **do not** have access to, it should fail stating that Maven could not locate the dependency from Company A’s group repository.

**Repositories**

This section will give a general overview of the repositories and their contents for both Company A and Company B.

Company A has the following repositories:

```auto
companyA-maven-group
- companyA-maven-hosted (hosts all of Company A's dependencies they create)
- companyB-maven-hosted (provide read access to Company B's dependencies for filtering)
- global-maven-proxy (provides access to Maven Central)

```

Company B has the following repositories:

```auto
companyB-maven-group
- companyB-maven-hosted (hosts all of Company B's dependencies they create)
- companyA-maven-hosted (provide read access to Company A's dependencies for filtering)
- global-maven-proxy (the same as the proxy for Company A)

```

The contents of the hosted repositories are as follows:

```auto
companyA-maven-hosted
- com
  - companyA
    - dep1
      - { versions of dep1 }
    - dep2
      - { version of dep2 }

companyB-maven-hosted
- com
  - companyB
    - dep3
      - { versions of dep3 }
    - dep4
      - { versions of dep4 }

```

**RBAC**

This section will give a general overview of the RBAC content selectors, privileges, and roles created to provide the desired result.

I have created multiple roles for each LDAP group (their is an LDAP group for Company A named `company-a` and an LDAP group for Company B named `company-b`). These LDAP mappings have the following roles:

```auto
companyA-role:
- nx-component-upload
- nx-search-read
- companyA-read-maven
- companyA-write-maven
- companyA-read-maven-companyB

companyA-read-maven:
- nx-repository-view-maven2-companyA-maven-group-read
- nx-repository-view-maven2-companyA-maven-group-browse

companyA-write-maven:
- nx-repository-view-maven2-companyA-maven-hosted-*

companyA-read-maven-companyB:
- read-companyB-public-deps (this is the Content Selector privilege)

```

There are the same roles created for Company B that mirror the Company A roles swapping instances of `companyA` with `companyB` (e.g. `companyB-read-maven` and `companyB-read-maven-companyA`).

The role in question is the `companyA-read-maven-companyB` role I created. It has a Content Selector privilege (`read-companyB-public-deps`) I created with the following information:

```auto
Content Selector: companyB-public-dependencies
Repository: companyB-maven-hosted
Actions: read,browse

```

The Content Selector `companyB-public-dependencies` has the following search expression:

```auto
(format == "maven2") and (path =~ "/|/com/|/com/companyB/|/com/companyB/dep3/.*")

```

Essentially what I’m trying to do with this search expression is provide read and browse access to Company A to the `companyB/dep3` dependency (found in `companyB-maven-hosted` repository) while preventing read and browse access to the `companyB/dep4` dependency.

**The Problem**

Because `companyB-maven-hosted` is part of Company A’s `companyA-maven-group` group repository, Company A users see everything from `companyB-maven-hosted`. For example, when they use the browser and select the `companyA-maven-group` to see the contents, they will see this:

```auto
- com
  - companyB
    - dep3
      - { dep3 versions }
    - dep4
      - { dep4 versions }

```

I have attempted to change the repository that the `companyB-public-dependencies` Content Selector applies to `companyA-maven-group` instead of `companyB-maven-hosted`, but neither choice works. Regardless of what repository I apply the Content Selector to, Company A users always see all of the contents of the `companyB-maven-hosted` repository.

I _have_ been able to get this to work if I remove the `companyB-maven-hosted` repository from the `companyA-maven-group` group repository, but this requires that Company A now includes the separate repository in their Maven `settings.xml` file:

```auto
// settings.xml for Company A
...
   <repositories>
      <repository>
         <id>companyA-group</id> // this is created later in the <servers> section
         <url>https://my.company.com/repository/companyA-maven-group/</url>
      </repository>
      <repository>
         <id>companyB-hosted</id> // this is created later in the <servers> section
         <url>https://my.company.com/repository/companyB-maven-hosted/</url>
      </repository>
   </repositories>
...

```

From all that I’ve read, there should be a way to place the `companyB-maven-hosted` repository within Company A’s `companyA-maven-group` group repository and still apply the Content Selector to filter out any dependencies that should remain private. This would allow the `settings.xml` file to only point to a singular repository group and everything should be managed by Nexus. However, I am unaware of how to do this. I have seen articles covering Repository Targets, but my Nexus 3 OSS version doesn’t seem to have that appearing in the admin panel. I have surmised that Content Selectors have replaced the concept of Repository Targets. Any assistance would be much appreciated.

Thank you.

---

<div class="post-metadata">

### Author: ![mpiggott](https://avatars.discourse-cdn.com/v4/letter/m/f0a364/32.png) [@mpiggott](https://community.sonatype.com/u/mpiggott)
#### Post date: [May 18, 2022, 2:45pm UTC](https://community.sonatype.com/t/content-selectors-not-working-in-multi-tenant-environment/8682/2 "2022-05-18T14:45:30Z")

</div>

Groups don’t consider permissions of members.

---

<div class="post-metadata">

### Author: ![matthew.rabey](https://avatars.discourse-cdn.com/v4/letter/m/e480ec/32.png) [@matthew.rabey](https://community.sonatype.com/u/matthew.rabey)
#### Post date: [May 18, 2022, 3:25pm UTC](https://community.sonatype.com/t/content-selectors-not-working-in-multi-tenant-environment/8682/3 "2022-05-18T15:25:15Z")

</div>

Is there no way to control the access of specific repositories while still being part of a group? Or will it require that there be another repository URL reference in the build tools? Are there any articles written by Sonatype devs that outline “best practices” for a multi-tenant environment?

Something similar to this:  
[https://help.sonatype.com/repomanager2/repository-manager-best-practices](https://help.sonatype.com/repomanager2/repository-manager-best-practices)  
It outlines what I’m looking for in terms of Repository Targets, but there’s nothing in the Nexus OSS version I am currently using that provides me the ability to use them.

> You are then able to take the repository target and associate it with one or more repositories or repository groups. This creates new C.R.U.D. [privileges](https://help.sonatype.com/repomanager2/configuration#Configuration-ManagingPrivileges) specific to the repository or group.

---

<div class="post-metadata">

### Author: ![mpiggott](https://avatars.discourse-cdn.com/v4/letter/m/f0a364/32.png) [@mpiggott](https://community.sonatype.com/u/mpiggott)
#### Post date: [May 18, 2022, 5:58pm UTC](https://community.sonatype.com/t/content-selectors-not-working-in-multi-tenant-environment/8682/4 "2022-05-18T17:58:40Z")

</div>

At the group repository level you could try to grant read+browse permissions based on content selectors, the effectiveness of this will entirely depend on how well defined artifact naming is by both companies.

---

<div class="post-metadata">

### Author: ![matthew.rabey](https://avatars.discourse-cdn.com/v4/letter/m/e480ec/32.png) [@matthew.rabey](https://community.sonatype.com/u/matthew.rabey)
#### Post date: [May 18, 2022, 6:28pm UTC](https://community.sonatype.com/t/content-selectors-not-working-in-multi-tenant-environment/8682/5 "2022-05-18T18:28:59Z")

</div>

Thank you, I hadn’t considered controlling the read+browse permissions on the group being filtered using Content Selectors. I’d imagine the Content Selector expressions would become much more convoluted, but good to know that there is an alternative.

---

<div class="post-metadata">

### Author: ![matthew.rabey](https://avatars.discourse-cdn.com/v4/letter/m/e480ec/32.png) [@matthew.rabey](https://community.sonatype.com/u/matthew.rabey)
#### Post date: [May 18, 2022, 6:44pm UTC](https://community.sonatype.com/t/content-selectors-not-working-in-multi-tenant-environment/8682/6 "2022-05-18T18:44:08Z")

</div>

For anyone else reading this topic, the fix would be the following:

In the `companyA-read-maven` RBAC role, instead of granting unfettered read+browse access to the `companyA-maven-group` repository (via `nx-repository-view-maven2-companyA-maven-group-{read/browse}`), I would create a Content Selector that would utilize negative regular expressions to filter out any “private dependencies” Company B does not want to share with Company A. I would then apply this Content Selector privilege to the `companyA-read-maven` RBAC role to ensure that the group repository will filter out any “private dependencies” from Company B while leaving the rest visible. This would require that the Nexus Admin would need to know each and every “private depenency” from each of the companies/teams, but it is at least possible.

---

<div class="post-metadata">

### Author: ![mpiggott](https://avatars.discourse-cdn.com/v4/letter/m/f0a364/32.png) [@mpiggott](https://community.sonatype.com/u/mpiggott)
#### Post date: [May 18, 2022, 6:46pm UTC](https://community.sonatype.com/t/content-selectors-not-working-in-multi-tenant-environment/8682/7 "2022-05-18T18:46:03Z")

</div>

You should definitely be cautious with the number and complexity of the content selectors as they can have an impact on performance for certain features (e.g search, browse) that need to evaluate a large number of components at a time.

---

<div class="post-metadata">

### Author: ![matthew.rabey](https://avatars.discourse-cdn.com/v4/letter/m/e480ec/32.png) [@matthew.rabey](https://community.sonatype.com/u/matthew.rabey)
#### Post date: [May 18, 2022, 6:49pm UTC](https://community.sonatype.com/t/content-selectors-not-working-in-multi-tenant-environment/8682/8 "2022-05-18T18:49:11Z")

</div>

Makes sense. I believe we’re going to go with the approach we have now where Content Selectors are on the individual `company-maven-hosted` repositories (where the total contents will be small) and require that each company ensure they update their `settings.xml` file to include this secondary repository. Requiring that the Nexus Admin knows each and every single dependency that needs to be kept private would be a cumbersome task.
