Skip to content
This repository has been archived by the owner on Jul 26, 2022. It is now read-only.

Latest commit

 

History

History
194 lines (142 loc) · 7.84 KB

design.md

File metadata and controls

194 lines (142 loc) · 7.84 KB

Design of nexus-proxy

Table of Contents

Introduction

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.

JWT Usage in nexus-proxy

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.

External Flow

Authentication Disabled

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:

nexus-proxy-external-flow-auth-disabled

Authentication Enabled

When authentication is enabled, nexus-proxy requires that one authenticates themselves against Google Cloud IAM.

Browsing the Nexus UI

The following flowchart details a user's experience when browsing https://nexus.example.com:

nexus-proxy-external-flow-ui-auth-enabled

Requesting Credentials for CLI Tools

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:

nexus-proxy-external-flow-jwt-auth-enabled

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.

Internal Flow

Authentication Disabled

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:

nexus-proxy-internal-flow-auth-disabled

Authentication Enabled

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:

nexus-proxy-internal-flow-auth-enabled