|
| 1 | +Harbor Proposal: Identity Aware proxy authentication mode |
| 2 | + |
| 3 | +Author: Sheng Jiang/shengjiang3, Eric Liu/ Date: Oct 3, 2023 |
| 4 | + |
| 5 | +## Abstract |
| 6 | + |
| 7 | +Proposes an approach to delegate Authentication decisions to external |
| 8 | +authentication authority in Harbor. |
| 9 | + |
| 10 | +## Background |
| 11 | + |
| 12 | +Currently, Harbor supports the OIDC protocol, however this means that Harbor |
| 13 | +cannot be seamlessly integrated into Single Sign-On (SSO) within an organization |
| 14 | +because Harbor must perform the code exchange for an identity token. |
| 15 | + |
| 16 | +## Proposal |
| 17 | + |
| 18 | +Add another authentication option, letting the identity provider authenticate |
| 19 | +and issue an identity token while Harbor assumes the role of an application that |
| 20 | +consumes the identity token. Harbor would act as an OIDC token verifier. The |
| 21 | +goal is to allow Harbor to plug in to any upstream OIDC identity provider |
| 22 | +allowing an SSO credential to authenticate with Harbor. |
| 23 | + |
| 24 | +### Key terms |
| 25 | + |
| 26 | +Identity Aware proxy (IAP) - A reverse proxy that provides authentication. Also |
| 27 | +known as auth proxy. Identity token (ID token) - Artifact that proves that the |
| 28 | +user has been authenticated (source). |
| 29 | + |
| 30 | +### High Level design |
| 31 | + |
| 32 | + |
| 33 | + |
| 34 | +The new authentication option allows Harbor to trust the identity tokens issued |
| 35 | +by an identity aware proxy (such as Dex). The identity aware proxy is OIDC |
| 36 | +compatible. As such, Harbor is to be configured to fetch the JWKS from the |
| 37 | +identity aware proxy and to use the JWKS to verify the ID tokens issued by the |
| 38 | +identity aware proxy. Once the token is verified and validated, Harbor can use |
| 39 | +the identity inside the ID token as the user identity. |
| 40 | + |
| 41 | +This is a slight deviation from the existing OIDC authentication mode where |
| 42 | +Harbor is directly configured to authenticate with the identity provider. |
| 43 | + |
| 44 | +### Configuration |
| 45 | + |
| 46 | +Since the new authentication mode in Harbor plays the role as an OIDC verifier, |
| 47 | +the following OIDC attributes are needed: |
| 48 | + |
| 49 | +- Name: The name of the OIDC provider. |
| 50 | +- Issuer URL: The identity provider's URL. This is used to locate the OIDC |
| 51 | + discovery document typically found at /.well-known/openid-configuration. |
| 52 | +- Expected Audiences (optional): A comma separated list of identifiers that |
| 53 | + Harbor is recognized by. The audience claim in the JWT should contain one of |
| 54 | + the audiences configured in the list. |
| 55 | +- User claim: The claim in the JWT to use as the user name. The default is the |
| 56 | + `sub` claim in the OIDC specification. |
| 57 | +- Groups claim: The claim in the JWT to locate the user’s groups. |
| 58 | +- Certificate authority data: base64 encoded PEM encoded certificate for the |
| 59 | + identity proxy. |
| 60 | +- Header name: HTTP header to get the ID token. |
| 61 | + |
| 62 | +The identity aware proxy should be able to be configured using the portal and/or |
| 63 | +the API. |
| 64 | + |
| 65 | +### Validating a token |
| 66 | + |
| 67 | + |
| 68 | + |
| 69 | +In the Identity Aware Proxy authentication mode, Harbor will look for the ID |
| 70 | +token in the Authorization header (Authorization: Bearer <JWT>). |
| 71 | + |
| 72 | +- The token will be a JWT Bearer token. |
| 73 | +- The token will be issued by the IAP after the user has authenticated through |
| 74 | + the IAP. |
| 75 | +- The token will be signed using the private key corresponding to the public |
| 76 | + keys available in the JWKS endpoint. |
| 77 | + |
| 78 | +The user contained in the ID token should only be used after verifying and |
| 79 | +validating the ID token: |
| 80 | + |
| 81 | +1. Verify the signature of the JWT using the JWKS. |
| 82 | + 1. Harbor can periodically refresh the JWKS. |
| 83 | + 1. Fetch the JWKS if a JWT with an unknown key ID is received. |
| 84 | + - Back off if the JWKS was fetched recently to prevent too many requests |
| 85 | + to the proxy. |
| 86 | + 1. Ensure that alg cannot be none. |
| 87 | +1. Validate that the token is not expired or not valid yet. |
| 88 | + - Check the exp and nbf claims. |
| 89 | +1. Validate that the token is intended for Harbor. |
| 90 | + - Check the aud claim for any of the expected audiences. |
| 91 | +1. The validated token can be used for authorization enforcement and user |
| 92 | + identification. |
| 93 | + |
| 94 | +The ID token is a short lived token so each token should be verified and |
| 95 | +validated independently. The ID token cannot be refreshed by Harbor to get a new |
| 96 | +token. |
| 97 | + |
| 98 | +### Obtaining identity from the token |
| 99 | + |
| 100 | +The identity is obtained from the token by looking for the user and groups claim |
| 101 | +specified in the Identity Aware Proxy configuration. |
| 102 | + |
| 103 | +The user claim specifies the claim in the JWT to obtain the user name from. The |
| 104 | +value in this claim is to be used to identify the user within Harbor (for |
| 105 | +example authorization policies). The user name in the user claim needs to be |
| 106 | +unique across the IAP. |
| 107 | + |
| 108 | +The groups claim specifies the claim in the JWT to obtain the groups from. The |
| 109 | +groups claim value is in the form of a list. |
| 110 | + |
| 111 | +### User access from a browser |
| 112 | + |
| 113 | + |
| 114 | + |
| 115 | +The first time Harbor sees a token for a given user claim, Harbor can on-board |
| 116 | +the user into the Harbor database (is this necessary?). The user name in the |
| 117 | +user claim is the username to onboard with. |
| 118 | + |
| 119 | +If the request has a valid bearer token, then the user should not be shown the |
| 120 | +Harbor login page and instead should be taken directly to the portal. |
| 121 | + |
| 122 | +### User access from the CLI (docker) |
| 123 | + |
| 124 | + |
| 125 | + |
| 126 | +The user flow for CLI can follow the same flow as OIDC CLI flow. The user gets |
| 127 | +the CLI secret from the UI and uses the CLI secret in the docker CLI which means |
| 128 | +that the OIDC CLI flow should also support IAP. |
| 129 | + |
| 130 | +The IAP issues ID tokens after authenticating the user credentials. The |
| 131 | +limitation is that the user must refresh the ID token in Harbor in order for the |
| 132 | +secret to remain valid since the IAP does not send the refresh token. |
| 133 | + |
| 134 | +Once the user is authenticated and accessing the UI, the user can obtain the CLI |
| 135 | +secret and use the CLI secret. |
| 136 | + |
| 137 | +## Non-Goals |
| 138 | + |
| 139 | +- Support for non-OIDC protocols such as SAML or LDAP. |
| 140 | + |
| 141 | +- Support for authorization by the identity provider. |
| 142 | + |
| 143 | +- Using access tokens from the OIDC provider. |
| 144 | + |
| 145 | +## Rationale |
| 146 | + |
| 147 | +### Alternatives |
| 148 | + |
| 149 | +#### Authentication with Kubernetes TokenReview |
| 150 | + |
| 151 | +Harbor auth proxy (link) uses Kubernetes token review to validate the token. |
| 152 | +However, Harbor auth proxy also relies on an endpoint that isn’t well |
| 153 | +documented. Since Harbor auth proxy already makes use of Kubernetes TokenReview |
| 154 | +to authenticate a token, an alternative to the Identity Aware Proxy would be |
| 155 | +support authentication via Kubernetes TokenReview as a first order option. |
| 156 | +Kubernetes TokenReview would operate as a webhook that Harbor can delegate |
| 157 | +authentication decisions to. |
| 158 | + |
| 159 | +Required configurations: |
| 160 | + |
| 161 | +- Host name: This is the Kubernetes API server evaluating the TokenReview. |
| 162 | +- Certificate: Certificate establishing the TLS connection. |
| 163 | +- Audiences (recommended): The audiences for tokens intended for Harbor. |
| 164 | + |
| 165 | +#### UI: |
| 166 | + |
| 167 | +- The token to authenticate is sent in the Authorization header as a bearer |
| 168 | + token. |
| 169 | +- The TokenReview ensures that the token is intended for Harbor by checking the |
| 170 | + audience in the token if it is provided. |
| 171 | +- The username and groups are provided in the TokenReview status upon successful |
| 172 | + authentication. |
| 173 | +- Automatically onboard the user using the username if this is the first time |
| 174 | + the user has signed in. |
| 175 | +- Skip the sign in page if the user is authenticated. |
| 176 | + |
| 177 | +#### CLI: |
| 178 | + |
| 179 | +- The docker CLI sends the token to the Token Service in the authorization basic |
| 180 | + header. |
| 181 | +- The username in the Authorization basic header is a filler string. The secret |
| 182 | + contains the token. |
| 183 | + - AWS uses a filler string for the user name: |
| 184 | + https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-cli.html |
| 185 | + - Azure also uses a filler string for the user name: |
| 186 | + https://learn.microsoft.com/en-us/azure/container-registry/container-registry-authentication?tabs=azure-cli#az-acr-login-with---expose-token |
| 187 | + |
| 188 | +### Auth Proxy using trusted headers for identification |
| 189 | + |
| 190 | +Harbor lives behind an auth proxy that authenticates access to Harbor. The |
| 191 | +mechanism authenticating access through the auth proxy is not important. |
| 192 | +However, after authenticating access, the auth proxy passes the identity of the |
| 193 | +user as a string in a configurable header (e.g- X-AuthProxy-UserName). |
| 194 | + |
| 195 | +Harbor would trust and use the user name passed in from the configurable header |
| 196 | +as the user name within Harbor. When Harbor gets a username that it has not seen |
| 197 | +before, Harbor should auto-onboard the user into the user database. |
| 198 | + |
| 199 | +Configuration options: |
| 200 | + |
| 201 | +- Header name (Required): This is the header where the username can be found. |
| 202 | +- Allowed sources (Optional): List of hosts or IPs the auth proxy requests can |
| 203 | + be forwarded from. |
| 204 | + |
| 205 | +## Trade-offs |
| 206 | + |
| 207 | +Pros of IAP: |
| 208 | + |
| 209 | +- Delegates authentication to an external identity authority. The external |
| 210 | + identity authority can manage the authentication logic so that Harbor only |
| 211 | + needs to verify and use the credentials. |
| 212 | +- Harbor explicitly verifies the identity token against the published public |
| 213 | + keys. |
| 214 | + |
| 215 | +Disadvantages of IAP: |
| 216 | + |
| 217 | +- The Harbor issued access token depends on the ID token. Short lived ID token |
| 218 | + means that the user has to authenticate often. |
| 219 | + |
| 220 | +# Compatibility |
| 221 | + |
| 222 | +This adds a new authentication method that doesn’t conflict with any existing |
| 223 | +ones. |
| 224 | + |
| 225 | +# Implementation |
| 226 | + |
| 227 | +1. Create configuration items for auth proxy configuration, and update UI to |
| 228 | + enable the configuration via Portal. |
| 229 | +1. Create a table (separate from the OIDC table) for sub, username, CLI secret. |
| 230 | +1. Add security context to handle the id token. |
0 commit comments