This is a (HashiCorp) Vault secrets plugin which talks to (Sonatype) Nexus Repository server and will dynamically create/revoke local user with predefined role(s). This backend can be mounted multiple times to provide access to multiple Nexus Repository servers, and work with both Pro and OSS versions.
Using this plugin, you can limit the accidental exposure window of Nexus Repository user's credentials; useful for continuous integration servers.
Important
This plugin is designed to be run on Vault servers
and could connect to Nexus Repository server(s) with high privileges
.
Therefore, DO NOT use this (or any 3rd party plugins) on critical production environment without understanding about the security risks!
Please read SECURITY section carefully before any uses.
You can find pre-built releases of the plugin here and download the latest binary file corresponding to your target OS.
If you prefer to build the plugin from sources, clone the GitHub repository locally and run the command make build
from the root of the sources directory.
Upon successful compilation, the resulting vault-plugin-secrets-nexus-repository
binary is stored in the dist/bin
directory.
Copy the plugin binary into a location of your choice; this directory must be specified as the plugin_directory
in the Vault configuration file:
plugin_directory = "path/to/plugin/directory"
Register the plugin in the Vault server's plugin catalog:
$ vault plugin register \
-sha256=$(sha256sum path/to/plugin/directory/vault-plugin-secrets-nexus-repository | cut -d " " -f 1) \
-command=vault-plugin-secrets-nexus-repository \
secret \
nexus
Caution
This inline checksum calculation above is provided for illustration purpose and does not validate your binary. It should not be used for production environment. Instead you should use the checksum provided in the release archive file as part of the releases. See Verify downloaded artifact from GitHub releases section.
You can now enable the Nexus Repository secrets plugin:
$ vault secrets enable -path nexus nexus
Note
All examples in this docs assumes that the plugin is mounted at backend path nexus
.
When upgrading, please refer to the Vault documentation for detailed instructions.
Create an "admin" user with a role with minimum privileges (refer to Nexus Repository roles docs):
nx-users-create
nx-user-delete
nx-userschangepw
or:
nx-user-all
Enable the Nexus Repository secrets engine:
$ vault secrets enable -path nexus nexus
Config secrets engine with above prepared "admin" user:
$ vault write nexus/config/admin \
url="https://nexus.myorg.domain" \
username="vault-secrets-admin" \
password="examplePassword"
(Optional, recommended) Rotate "admin" user's password so only Vault knows the password:
$ vault write -f nexus/config/rotate
Create a (Vault) role:
$ vault write nexus/roles/test \
nexus_roles="repo-a-readonly,repo-b-upload" \
user_id_template="{{ printf \"v-%s-%s-%s\" (.RoleName) (.DisplayName | truncate 64) (unix_time) | truncate 128 | lowercase }}" \
user_email="test@example.org" \
ttl=10m \
max_ttl=1h
Success! Data written to: nexus/roles/test
List roles:
$ vault list nexus/roles
Keys
----
test
Read role configs:
$ vault read nexus/roles/test
Key Value
--- -----
max_ttl 1h
name test
nexus_roles [repo-a-readonly repo-b-upload]
ttl 10m
user_email test@example.org
user_id_template {{ printf "v-%s-%s-%s" (.RoleName) (.DisplayName | truncate 64) (unix_time) | truncate 128 | lowercase }}
Request credential for the role (password truncated):
$ vault read nexus/creds/test
Key Value
--- -----
lease_id nexus/creds/test/3hwLPfGc4SQdtxUMiI0J09MQ
lease_duration 10m
lease_renewable true
email_address test@example.org
nexus_roles [repo-a-readonly repo-b-upload]
password R0QMi7RhoqqauIfERBg15Nsma2CUx9K3...
user_id v-test-token-1733114948
Command | Path |
---|---|
write | nexus/config/admin |
read | nexus/config/admin |
delete | nexus/config/admin |
Configure the parameters used to connect to the Nexus Repository server integrated with this backend.
The three main parameters: url
which is the absolute URL to the Nexus Repository server. Note that /v1/rest
is prepended by the individual calls, so do not include it in the URL here.
The second and third is username
, password
pair which is a precreated user with enough permissions to manage other users.
An optional insecure
parameter will enable bypassing the TLS connection verification with Nexus Repository server.
An optional timeout
parameter is the timeout when this secrets engine calls to Nexus Repository server.
No renewals or new tokens will be issued if the backend configuration (config/admin) is deleted.
url
(string) - Address of the Nexus Repository server instance, e.g. https://nexus.myorg.domainusername
(string) - The "admin" username to access Nexus Repository API.password
(string) - The "admin" password.insecure
(boolean) - Optional. Bypass certification verification for TLS connection with Nexus Repository API. Default tofalse
.timeout
(time duration) - Optional. Timeout for connection with Nexus Repository API. Default to30s
(30 seconds).
$ vault write nexus/config/admin \
url="https://nexus.myorg.domain" \
username="vault-secrets-admin" \
password="adminPassword" \
insecure=false \
timeout=30s
Command | Path |
---|---|
write | nexus/config/rotate |
Rotate (change) the "admin" user's password used to access Nexus Repository from this plugin.
$ vault write -f nexus/config/rotate
Command | Path |
---|---|
write | nexus/roles/:rolename |
patch | nexus/roles/:rolename |
read | nexus/roles/:rolename |
delete | nexus/roles/:rolename |
Configure the parameters used to dynamically generate Nexus Repository users by the (Vault) role.
nexus_roles
(list string) - Comma-separated string or list of predefined or precreated roles on Nexus Repository that generated users will be attatched to. Please refer to Nexus Repository roles docs for more detailed instructions.user_id_template
(string) - Optional. Template for dynamically generated user ID (is username also). Default to{{ printf "v-%s-%s-%s-%s" (.RoleName | truncate 64) (.DisplayName | truncate 64) (unix_time) (random 24) | truncate 192 | lowercase }}
. See username templating for details on how to write a custom template.user_email
(string) - Optional. Email for generated users. Default tono-one@example.org
.ttl
(int64) - Default TTL for generated user. If unset or set to0
uses the backend'sdefault_ttl
. Cannot exceedmax_ttl
.max_ttl
(int64) - Maximum TTL that a credential (and generated user's lifecycle) can be renewed for. If unset or set to0
, uses the backend'smax_ttl
. Cannot exceed backend'smax_ttl
.
$ vault write nexus/roles/test \
nexus_roles="repo-a-readonly,repo-b-upload" \
user_id_template="{{ printf \"v-%s-%s-%s\" (.RoleName) (.DisplayName | truncate 64) (unix_time) | truncate 128 | lowercase }}" \
user_email="test@example.org" \
ttl=10m \
max_ttl=1h
$ vault read nexus/roles/test
$ vault delete nexus/roles/test
Command | Path |
---|---|
read | nexus/creds/:rolename |
Get credential (dynamically generate Nexus Repository users) from a specified (Vault) role.
-
user_id
(string) - User ID of generated user. -
email_address
(string) - Email of generated user. -
nexus_roles
(list string) - List of roles on Nexus Repository that generated user is attatched to. -
password
(string) - Password of generated user.(And Vault's lease fields):
-
lease_id
(string) -
lease_duration
(time duration) -
lease_renewable
(boolean)
$ vault read nexus/creds/test
Key Value
--- -----
lease_id nexus/creds/test/b00JMCaEvlPCu5WeILCcuijR
lease_duration 10m
lease_renewable true
email_address test@example.org
nexus_roles [repo-a-readonly repo-b-upload]
password um4q4sqx5lJPpsSo8tklSKj6Ic... (password truncated)
user_id v-test-token-1733126698
Because of running on and managaging critical systems (Vault, Nexus), we all understand that this plugin can be a vulnerable part due to supply chain integrity weaknesses.
Therefore, to prove that the released binary has not been tampered with and can be securely traced back to source, the plugin is built and attested to the provenance of its release artifacts in the SLSA standard and provisionally meet Level 3 using SLSA
framework's generator and Level 2 using GitHub's artifact attestation
.
Use either or both methods below
Note
slsa-verifier
is a tool for verifying SLSA provenance that was generated by CI/CD builders. slsa-verifier verifies the provenance by verifying the cryptographic signatures on provenance to make sure it was created by the expected builder. It then verifies that various values such as the builder id, source code repository, ref (branch or tag) matches the expected values.
Follow this installation instruction to install.
Verify (e.g for the vault-plugin-secrets-nexus-repository_v1.0.0-tb1_linux-amd64.tar.gz
, version v1.0.0-tb1
, file vault-plugin-secrets-nexus-repository_v1.0.0-tb1.intoto.jsonl
also has to be downloaded from the release):
$ slsa-verifier verify-artifact \
--source-uri manhtukhang/vault-plugin-secrets-nexus-repository \
--source-tag v1.0.0-tb1 \
--provenance-path ./vault-plugin-secrets-nexus-repository_v1.0.0-tb1.intoto.jsonl \
./vault-plugin-secrets-nexus-repository_v1.0.0-tb1_linux-amd64.tar.gz
Verifying vault-plugin-secrets-nexus-repository_v0.0.1-tb1_linux-amd64.tar.gz with slsa-verifier
Verified signature against tlog entry index 155157774 at URL: https://rekor.sigstore.dev/api/v1/log/entries/108e9186e8c5677aeda7d7a4c8fb7cdb79ecaab29fe4441d8d5bd887e2e8df15d685c84350e21035
Verified build using builder "https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@refs/tags/v2.0.0" at commit 067f1fc9064d7d78d673925f78d0f81bb84c6637
Verifying artifact vault-plugin-secrets-nexus-repository_v0.0.1-tb1_linux-amd64.tar.gz: PASSED
PASSED: SLSA verification passed
Follow this installation instruction to install GitHub CLI (gh
command).
Verify (e.g for the vault-plugin-secrets-nexus-repository_v0.0.1-tb1_linux-amd64.tar.gz
):
$ gh attestation verify \
--repo manhtukhang/vault-plugin-secrets-nexus-repository \
./vault-plugin-secrets-nexus-repository_v0.0.1-tb1_linux-amd64.tar.gz
Loaded digest sha256:815378c1be24539758452a232bb10510fb89dc562cbd1c8cd5e5746847670b58 for file://vault-plugin-secrets-nexus-repository_v0.0.1-tb1_linux-amd64.tar.gz
Loaded 1 attestation from GitHub API
✓ Verification succeeded!
sha256:815378c1be24539758452a232bb10510fb89dc562cbd1c8cd5e5746847670b58 was attested by:
REPO PREDICATE_TYPE WORKFLOW
manhtukhang/vault-plugin-secrets-nexus-repository https://slsa.dev/provenance/v1 .github/workflows/release.yaml@refs/tags/v0.0.1-tb1
Note
Artifact attestations can be verified from a machine without the internet connection, please follow this step-by-step guide.
- Support OpenBao (Vault OSS fork) (it might already work but untested now).
Please open issue if you have any usecase of the following features:
- Check (and ensure) if roles in
nexus_roles
existed on Nexus Repository server when the (Vault) role is create. - Create dynamically role on Nexus Repository when (Vault) role config is created, by specified a list of Nexus privileges.
- Allow cache the previous credential (generated user) by each role (and from a same bound claim user) to avoid creating to many users with the same privileges and reduce API abusing.
- (Request your own)...