When designing nexus-proxy
we knew we had to support both browser-based and
CLI-based flows (e.g., browsing the Nexus UI and using tools such as Maven or
Docker to upload/download artifacts). We also knew beforehand that we would need
to authenticate Nexus against
Google Cloud Identity & Access Management, but
we wanted to make this authentication optional so that nexus-proxy
could be
used in simpler scenarios.
This document starts by describing briefly a specific type of token
that nexus-proxy
uses for authentication, and proceeds into describing both
the external (i.e., from the perspective of the user) and internal flows of
nexus-proxy
, detailing what happens in each flow when authentication is
disabled or enabled. For simplicity we assume that
nexus-proxy
is reachable at https://nexus.example.com.
JSON Web Token, commonly referred to as JWT, ia a type of token used to convey arbitrary information, also known as claims in a secure way between two distinct entities (e.g., a client and a server). These claims are described in JSON and encoded using an URL-safe variant of Base64.Then, a cryptographic signature of the resulting information is computed and appended to the the encoded claims, forming a token. This token is then sent to a destination which verifies its authenticity and, in case it is authentic, decodes the claims and uses them as trusted, verified information.
NOTE: The way the signature is computed and verified depends on the algorithm being used.
nexus-proxy
uses RS256, which means that the signature is computed using an
RSA private key and the SHA-256 algorithm, and verified using the corresponding
RSA public key. The tokens generated by nexus-proxy
carry the following
claims:
uid
— The email address of the authenticated user.iat
— The timestamp at which the token was issued.exp
— The timestamp at which the token will expire.aud
— The token's intended audience, i.e., the domain names being in use.
In practice this means that a token generated by nexus-proxy
will look like
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1aWQiOiJqb2huLmRvZUBleGFtcGxlLmNv
bSIsImlhdCI6MTUwMzA1NTI3NiwiZXhwIjoxNTM0NTkxMjc2LCJhdWQiOlsiY29udGFpbmVyc
y5leGFtcGxlLmNvbSIsIm5leHVzLmV4YW1wbGUuY29tIl19.14dRJRxkwAp0iwm-XcxuVNV5S
Ixc78ipcvg_kJAjeEseeKlvpsIQxv2TEOInLGkxUhppnwpV5ZYuNrSmKP_bdHifubCdIglvP2
iK41RvVgSNmvHy8SATzeHhtPOK3EyCc9SyLPxYTfbsjqXxClqPuvzkn0QMdJRn36sJIfjAzmc
The JWT tokens generated by nexus-proxy
are valid for one year. Further
details can be found
below.
When authentication is disabled, nexus-proxy
is transparent to the user. The
following flowchart details a user's experience when browsing
https://nexus.example.com:
When authentication is enabled, nexus-proxy
requires that one authenticates
themselves against Google Cloud IAM.
The following flowchart details a user's experience when browsing https://nexus.example.com:
In order to use tools such as Maven or Docker, one must obtain a specific set of
credentials. This is necessary so that one doesn't have to use their Google
organization credentials or a manually-obtained Google authentication token in
their configuration files. As mentioned above, the credentials generated by
nexus-proxy
are JWT tokens and are valid for one year (unless organization
membership is revoked before this period).
The following flowchart details a user's experience when visiting https://nexus.example.com/cli/credentials:
One must then configure their tools to use these credentials. Detailed steps can be found here.
ATTENTION: These credentials are not renewed automatically. Whenever one's JWT expires one must obtain a new one by visiting https://nexus.example.com/cli/credentials again.
ATTENTION: Every visit to https://nexus.example.com/cli/credentials will return a different JWT, as the creation and expiration dates are encoded in the token itself. One may use different JWTs in different tools but must be aware that they will expire at different moments.
When authentication is disabled, nexus-proxy
proxies requests to Nexus and
responds to health-checks on its behalf. An health-check is any HTTP request
made to /
by user-agents matching a configurable regular expression. These
must usually be responded with 200 OK
, and nexus-proxy
ensures that.
The following flowchart details the flow of an HTTP request made to
nexus-proxy
when authentication is disabled:
When authentication is enabled, nexus-proxy
performs the following high-level
tasks:
- Responds to health-checks as described above.
- Performs an OAuth2 "authorization code" flow in order to establish a session.
- Ensure that only authenticated users can access protected resources in both in-browser and CLI flows.
- Partially implements the authentication flows of Maven and Docker repositories.
This last item is necessary because Maven and Docker expect HTTP Basic
authentication (as opposed to the Bearer Token/JWT authentication which we are
using). Also, Docker expects specific response headers at a specific endpoint,
according to the
Docker Registry HTTP API V2. As
such, and since nexus-proxy
stands between Maven/Docker and Nexus, this part
of the authentication flow had to be implemented in the proxy.
The following flowchart details the flow of an HTTP request made to
nexus-proxy
when authentication is enabled: