Content Selectors
Content Selectors
Content selectors grant access to specific content path, or namespace, from a repository rather than the entire repository. Content selectors define what content users may access. Define a selector with a search expression to allow access to components that match the repository path.
After creating the content selector, add the selector to a custom privilege. Use the privilege to provide access to that namespace for a role, group, or user.
Content Selector > Privilege > Role > Group > User
See Manage Selector Permissions
Creating a Content Selector
- Go to Settings → Repository → Content Selectors.
- Select Create selector.
- Fill in the displayed fields. Mandatory fields are Name and Search Expression. Use the Search Expression field to build your query using
CSELsyntax.
Preview Repository
Preview the results of the search expression by selecting the Preview button. The preview only displays 10 results to limit the impact to performance.
Select a repository or grouping of repositories from the Preview Repository dropdown.
Select the Preview button.
Use the Filter option to check for a specific result.
Use the Name column to sort the results.
Select Save to create the content selector.
Content Selector Best Practices
- Write Access: Content Selectors are best used to grant
writeaccess to a team's namespaces within a repository. - Read Access: The best practice to restrict
readaccess is to move the content to a privately hosted repository and limit permissions to that repository. - Group Repositories: Permissions on a group repository may provide access to components that are not granted on the member repositories.
- Restricting Access: Content Selectors do not revoke access provided by other privileges or selectors. Use the principle of least privilege to avoid granting excessive access to private components.
- Docker Repositories: The Docker format requires special considerations when creating Content Selectors.
See Content Selectors and Docker
- Regular Expressions: Where possible, avoid the
=~operator while using==or=^instead. A common circumstance would be to replace a=~operator using a regex that defines a "starts with" pattern; using=^instead is orders of magnitude more performant. When a regular expression is unavoidable, the simpler is better.
Content Selectors in High Availability
Nexus Repository has two distinct implementations depending on the edition and deployment configuration:
Standard Implementation (CE/Pro Single Node)
Used for repository browsing and basic content queriesDistributed Search Implementation (Pro with clustering/Cloud)
Used for search functionality in clustered environments
The user interface validates regular expressions as Java Regular Expression which are further transformed into a form executed by PostgreSQL. This operation only accepts simpler POSIX regular expressions which are not performant in clustered Postgres environments.
Warning In deployments using PostgreSQL, Sonatype recommends avoiding regular expressions as much as possible to avoid crippling impacts to service performance.
For non-HA environments, you may use regular expressions in your content selectors though we recommend using the more performant solutions outlined below.
Content Selector Reference
Below are the attributes for content selectors that define path and format as values. The asset’s path must begin with a leading slash.
| Attribute | Allowed Values |
|---|---|
| path | The path of your repository content with a leading slash |
| format | The format of the content for which you query (including the format is not required and is not supported for all formats.) |
Supported Formats
Content Selectors in Sonatype Nexus Repository are supported for most repository formats. This support is of two types:
- Enhanced support: Supports content selectors beyond basic
formatandpathmatching. - Basic support: Supports filtering by
formatandpathonly.
Formats with enhanced support:
- Terraform; for example
terraform.namespace``terraform.name``terraform.provider - Maven; for example
maven.groupId``maven.artifactId``maven.version - NuGet; for example
nuget.id``nuget.version - Swift; for example
swift.scope``swift.name``swift.version
Formats with basic support:
- Cargo
- Helm
- Docker
- npm
- Raw
- Go
- Composer
- RubyGems
- Conan
- Conda
- CocoaPods
- R/CRAN
- Hugging Face
- Git LFS
- p2
- Pub
- Yum
The following formats have additional limitations:
- PyPI repositories: Content Selectors do not work for uploads to PyPI repositories. PyPI uploads use
POSTrequests to the repository root, which do not include a path in the URI, making path-based content selectors ineffective for upload operations. - APT repositories: Content selectors may not work for uploads to APT repositories as the
POSTrequest to path“/”is used for the upload. You may grant write access to the whole repository, or none of it. Other content selector paths are not applied.
Operators Allowed for HA Deployments
| Operator | Description | Performance | Example |
|---|---|---|---|
== |
Matches text exactly | Fastest | format == "raw" |
!= |
Not equals | Fast | path != "test.jar" |
=^ |
Starts with text | Fast | path =^ "/org/apache/commons/" |
and |
Match all expressions | Fast | format == "maven2" and path =^ "/org/apache/commons" |
or |
Match any expression | Fast | format == "maven2" or format == "npm" |
(expr) |
Group multiple expressions | Variable (depends on pattern) | format == "npm" or (format == "maven2" and path =^ "/org/apache/commons") |
Operators to Avoid in HA Deployments
| Operator | Description | Performance | Example |
|---|---|---|---|
=~ |
Matches a Java regular expression pattern | Slow | path =~ "^/org/apache/commons/.*" |
\- |
Escaping dashes in version ranges | Variable (depends on pattern) | path =~ "[0-9a-zA-Z\-_]" |
Reliable Patterns that are Java + POSIX Compatible
- Basic character classes: [a-zA-Z0-9], [0-9]
- Standard quantifiers: *, +, ?, {n,m}
- Anchors: ^, $Alternation: |
- Grouping: (...) (capturing groups only)
- Character escapes: \., \*, \+, \(, \)
- POSIX character classes: [[:alpha:]], [[:digit:]], [[:space:]]
High-Performance Pattern Examples
These patterns are optimized for fast database execution.
Simple Prefix Matching
Restrict access to specific organization/package paths.
path =~ "^/com/example/.*"
File Extension Filtering
Allow only JAR files, block source/documentation.
path =~ ".*\.jar$"
Combined Prefix + Extension
Company-specific JAR artifacts only.
path =~ "^/com/mycompany/.*\.jar$"
Simple Alternation
Allow multiple specific top-level packages.
path =~ "^/(com|org|net)/.*"
Poor Performance Pattern Examples
These patterns cause significant performance degradation or timeouts. We recommend avoiding these types of patterns whenever possible.
Nested Quantifiers (ReDoS)
Catastrophic exponential backtracking, database regex engine gets stuck on deeply nested paths.
// Content Selector - AVOID
path =~ "^(.*/.+)+\.jar$"
Better alternative:
path =~ ".*\.jar$"
Greedy Dot with Complex Alternation
The .* matches everything, then backtracks through entire path. Long paths require extensive backtracking to find alternation.
// Content Selector - AVOID
path =~ ".*(debug|test|sample).*\.jar$"
Better alternative:
path =~ "^.*(debug|test|sample)[^/]*\.jar$"
path =~ "^/(com|org|net|edu|gov|mil|int|arpa)/.*"
Multiple Lookaheads/Lookbehinds
Database must evaluate multiple lookahead assertions per character.
// Content Selector - AVOID
path =~ "^/(?=.*important)(?!.*test)(?!.*debug).*"
As a better alternative, use simple prefix patterns with AND/OR logic.
path =~ "^/.*important.*" && path !~ ".*test.*"
Unbounded Repetition at Start
Catastrophic performance with star height problem, (.*/)* creates exponential combinations.
// Content Selector - AVOID
path =~ "(.*/)*important/.*"
Complex Character Class Repetition
Character class matching multiplied by path depth.
// Content Selector - AVOID
path =~ "^/([a-zA-Z0-9._-]*/)+"
Better alternative:
path =~ "^/[a-zA-Z0-9._/-]+/"
Transform Poor Patterns to Good Patterns
For simple prefix matching, replace regex (=~) with starts-with (=^) operator for dramatic performance improvements.
// Replace these regex patterns:
path =~ "^/com/.*" → path =^ "/com/"
path =~ "^/org/example/.*" → path =^ "/org/example/"
path =~ "^/net/sf/.*" → path =^ "/net/sf/"
Permissions for Tree Browsing
Read access selectors should include access to tree browsing in the Repository Manager UI. The content selectors need to include permissions for the parent directories of the artifacts.
Tree browsing for Highly Available (HA) environments
format == "maven2" and (path == "/" or path == "/org/" or path == "/org/apache/" or path =^ "/org/apache/commons/")
Alternatively, if you don't mind users being able to see any directory name (just not the contents), use the following.
format== "maven2" and path =~".*/|/org/apache/commons.*"