From 1b317c00434eaa92dc4cd3e730e540952acf08ff Mon Sep 17 00:00:00 2001 From: Shiwei Zhang Date: Thu, 26 May 2022 20:53:58 +0800 Subject: [PATCH 1/8] add outline Signed-off-by: Shiwei Zhang --- specs/registry-auth.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 specs/registry-auth.md diff --git a/specs/registry-auth.md b/specs/registry-auth.md new file mode 100644 index 000000000..90891940e --- /dev/null +++ b/specs/registry-auth.md @@ -0,0 +1,11 @@ +# Registry Authentication + +Registry access is required for pulling the manifests of the images to be verified along with their signatures as well as other advanced operations. This documentation specifies how authentication to the remote registry works and how registry credentials are stored. + +## Authentication Flow + + + +## Credential Store + + From b8b56ea306619546cf0198dbb7319c9e42e37371 Mon Sep 17 00:00:00 2001 From: Shiwei Zhang Date: Mon, 6 Jun 2022 15:58:20 +0800 Subject: [PATCH 2/8] basic auth Signed-off-by: Shiwei Zhang --- specs/registry-auth.md | 68 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/specs/registry-auth.md b/specs/registry-auth.md index 90891940e..8854e7d7d 100644 --- a/specs/registry-auth.md +++ b/specs/registry-auth.md @@ -2,10 +2,76 @@ Registry access is required for pulling the manifests of the images to be verified along with their signatures as well as other advanced operations. This documentation specifies how authentication to the remote registry works and how registry credentials are stored. -## Authentication Flow +## Communication Channel + +Although it is secure to transmit artifacts with their signatures via HTTP connections, it is RECOMMENDED to transmit via HTTPS connections for confidentiality and the authenticity of the remote server. + +Alternatively, clients can be authenticated via mutual TLS authentication (mTLS). In other words, clients connect to servers via HTTP over mTLS by presenting client certificates. In this case, authorization can be applied later without further authentication schemes. + + +## Authentication Schemes + +Notation supports [basic HTTP authentication][RFC7617] scheme and token schemes including [OAuth 2.0][RFC6749] and [Docker Registry V2 Token][token]. Clients MUST connect to the remote servers via HTTPS if any authentication scheme is applied. + +### General Flow + +```mermaid +flowchart LR; + ts[Authorization Service]; + client[Notation]; + reg[Registry]; + + client -- 1. Access resource --> reg; + reg -- 2. Challenge --> client; + client -- 3. Request for token --> ts; + ts -- 4. Grant token --> client; + client -- 5. Access with token --> reg; + reg -- 6. Response --> client; +``` + +In general, the `notation` accesses registry resources as the workflow below, which follows the workflow for [Docker Registry v2 authentication via central service](https://docs.docker.com/registry/spec/auth/token/). + +1. `notation` attempts to access the remote registry directly. If there is no authentication scheme associated with the registry, skip to *step 6*. +2. The remote registry returns `401 Unauthorized` with a [WWW-Authenticate](https://datatracker.ietf.org/doc/html/rfc7235#section-4.1) challenge, indicating the required authentication scheme. +3. `notation` requests the authorization service for a bearer token for accessing the target resource with local credentials. If the remote registry requires *basic* scheme, skip to *step 5*. +4. The authorization grants and returns a bearer token for access back to the `notation` client. +5. `notation` attempts to access the remote registry again with the obtained bearer token (or local credential for *basic* scheme) in the [Authorization](https://datatracker.ietf.org/doc/html/rfc7235#section-4.2) header. +6. The remote registry performs the requested operation and returns the response. + +Optimization might be performed to reduced the number of requests in order to reduce the overall latency for subsequent requests. + +### Basic Scheme + +`notation` follows [RFC 7617][RFC7617] for the *Basic* HTTP authentication scheme. + +If a remote registry is known to support `Basic` authentication scheme, the attempt-challenge phase (*steps 1-4*) can be skipped, and thus `notation` can access the remote registry without overhead in terms of the number of requests. + +```mermaid +flowchart LR; + client[Notation]; + reg[Registry]; + + client -- Access with credentials --> reg; + reg -- Response --> client; +``` + +### Token Scheme + + + +#### Docker + +#### OAuth 2 ## Credential Store +### Credential File + +### Credential Helper + +[RFC6749]: https://www.rfc-editor.org/rfc/rfc6749 "OAuth 2.0" +[RFC7617]: https://www.rfc-editor.org/rfc/rfc7617 "Basic Auth" +[token]: https://docs.docker.com/registry/spec/auth/jwt/ "Docker Token Authentication" \ No newline at end of file From 7f82f969fcc9b38dc05291d68eed8918f67c0f26 Mon Sep 17 00:00:00 2001 From: Shiwei Zhang Date: Mon, 6 Jun 2022 18:01:46 +0800 Subject: [PATCH 3/8] token auth Signed-off-by: Shiwei Zhang --- specs/registry-auth.md | 47 +++++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/specs/registry-auth.md b/specs/registry-auth.md index 8854e7d7d..7c19f27fb 100644 --- a/specs/registry-auth.md +++ b/specs/registry-auth.md @@ -30,22 +30,22 @@ flowchart LR; reg -- 6. Response --> client; ``` -In general, the `notation` accesses registry resources as the workflow below, which follows the workflow for [Docker Registry v2 authentication via central service](https://docs.docker.com/registry/spec/auth/token/). +In general, notation clients accesses registry resources as the workflow below, which follows the workflow for [Docker Registry v2 authentication via central service](https://docs.docker.com/registry/spec/auth/token/). -1. `notation` attempts to access the remote registry directly. If there is no authentication scheme associated with the registry, skip to *step 6*. +1. Notation attempts to access the remote registry directly. If there is no authentication scheme associated with the registry, skip to *step 6*. 2. The remote registry returns `401 Unauthorized` with a [WWW-Authenticate](https://datatracker.ietf.org/doc/html/rfc7235#section-4.1) challenge, indicating the required authentication scheme. -3. `notation` requests the authorization service for a bearer token for accessing the target resource with local credentials. If the remote registry requires *basic* scheme, skip to *step 5*. -4. The authorization grants and returns a bearer token for access back to the `notation` client. -5. `notation` attempts to access the remote registry again with the obtained bearer token (or local credential for *basic* scheme) in the [Authorization](https://datatracker.ietf.org/doc/html/rfc7235#section-4.2) header. +3. Notation requests the authorization service for a bearer token for accessing the target resource with local credentials. If the remote registry requires *basic* scheme, skip to *step 5*. +4. The authorization grants and returns a bearer token for access back to the notation client. +5. Notation attempts to access the remote registry again with the obtained bearer token (or local credential for *basic* scheme) in the [Authorization](https://datatracker.ietf.org/doc/html/rfc7235#section-4.2) header. 6. The remote registry performs the requested operation and returns the response. Optimization might be performed to reduced the number of requests in order to reduce the overall latency for subsequent requests. ### Basic Scheme -`notation` follows [RFC 7617][RFC7617] for the *Basic* HTTP authentication scheme. +Notation follows [RFC 7617][RFC7617] for the *Basic* HTTP authentication scheme. -If a remote registry is known to support `Basic` authentication scheme, the attempt-challenge phase (*steps 1-4*) can be skipped, and thus `notation` can access the remote registry without overhead in terms of the number of requests. +If a remote registry is known to support `Basic` authentication scheme, the attempt-challenge phase (*steps 1-4*) can be skipped, and thus Notation can access the remote registry without overhead in terms of the number of requests. ```mermaid flowchart LR; @@ -58,12 +58,42 @@ flowchart LR; ### Token Scheme +Notation supports two types of token schemes, [Docker][token] and [OAuth 2.0][RFC6749] where OAuth 2.0 is preferred by default. +Since token authentication schemes have two more requests per registry requests, notation client implementations SHOULD cache the token to reduce the number of requests. + +```mermaid +flowchart LR; + ts[Authorization Service]; + client[Notation]; + reg[Registry]; + + client -- 1. Access resource with cached token --> reg; + reg -- 2. Challenge if token invalidated --> client; + client -- 3. Request for a new token --> ts; + ts -- 4. Grant a new token --> client; + client -- 5. Access with a new token --> reg; + reg -- 6. Response --> client; +``` + +The workflow is updated as follows with caching. + +1. Notation attempts to access the remote registry using a cached token. If the token is valid, skip to *step 6*. +2. The remote registry returns `401 Unauthorized` with a challenge, requiring a valid token. +3. Notation requests the authorization service for a new bearer token for accessing the target resource with local credentials. +4. The authorization grants and returns a new bearer token for access back to the notation client. The client-side cache is refreshed by the newly returned token. +5. Notation attempts to access the remote registry again. +6. The remote registry performs the requested operation and returns the response. #### Docker +In the [Docker Token Authentication][token] specification, the *step 3* is implemented using a `GET` request where users are authenticated by the authorization service via `Basic` authentication scheme. Therefore, user credentials are only accepted in the form of username and password pair. + #### OAuth 2 +Notation follows the [Docker Registry v2 authentication][oauth2] specification for the [OAuth 2.0][RFC6749] framework where the *step 3* is implemented using a `POST` request. Precisely, notation supports `password` and `refresh_token` grant types. + +**Note** Refresh tokens are often known as identity tokens in the context of registry authentication. ## Credential Store @@ -74,4 +104,5 @@ flowchart LR; [RFC6749]: https://www.rfc-editor.org/rfc/rfc6749 "OAuth 2.0" [RFC7617]: https://www.rfc-editor.org/rfc/rfc7617 "Basic Auth" -[token]: https://docs.docker.com/registry/spec/auth/jwt/ "Docker Token Authentication" \ No newline at end of file +[token]: https://docs.docker.com/registry/spec/auth/jwt/ "Docker Token Authentication" +[oauth2]: https://docs.docker.com/registry/spec/auth/oauth/ "Docker Registry v2 authentication using OAuth2" \ No newline at end of file From 9c368735318dd7096b71ee505e79c0a5a674b7b4 Mon Sep 17 00:00:00 2001 From: Shiwei Zhang Date: Tue, 7 Jun 2022 00:30:44 +0800 Subject: [PATCH 4/8] cred store Signed-off-by: Shiwei Zhang --- specs/registry-auth.md | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/specs/registry-auth.md b/specs/registry-auth.md index 7c19f27fb..169c07823 100644 --- a/specs/registry-auth.md +++ b/specs/registry-auth.md @@ -95,12 +95,47 @@ Notation follows the [Docker Registry v2 authentication][oauth2] specification f **Note** Refresh tokens are often known as identity tokens in the context of registry authentication. + ## Credential Store -### Credential File +As local credentials may be required to access the remote registries, they need to be stored and accessed securely. To achieve maximum security, credential helpers are preferred so that credentials are stored in the system key chain with better protection. If credential helpers are not available, notation will fall back to credential files with proper access control. ### Credential Helper +To achieve maximum compatibility of existing systems, [docker credential helpers](https://github.com/docker/docker-credential-helpers) as long as its [protocol](https://docs.docker.com/engine/reference/commandline/login/#credential-helper-protocol) are adopted as the credential helpers for `notation`. + +The credential store can be specified globally or per registry by setting the notation config. + +```json +{ + "credHelpers": { + "registry.wabbit-networks.io": "wabbithelper", + "another.wabbit-networks.io": "foobar" + }, + "credsFile": "/absolute/path/to/auth.json", + "credsStore": "whatever" +} +``` + +**Note** The absolute path to credential file `credsFile` is used to store extra metadata by credential helper drivers such as [docker/cli](https://github.com/docker/cli/blob/master/cli/config/credentials/native_store.go). + +### Credential File + +The credential file is alternative credential store when credential helpers are not available. The default file path is + +``` +{CONFIG}/notation/auth.json +``` + +The credential file path can be altered by setting the `credsFile` field of the notation config. + +```json +{ + "credsFile": "/absolute/path/to/auth.json" +} +``` + +Since credentials are stored in plaintext, the permission of the credential file MUST be kept minimum when storing credentials. On Unix / Linux, the permission MUST be either `0600` (default) or `0400` (read-only). [RFC6749]: https://www.rfc-editor.org/rfc/rfc6749 "OAuth 2.0" [RFC7617]: https://www.rfc-editor.org/rfc/rfc7617 "Basic Auth" From 5d44e7815b8d93d35a0f5aac6e2ef2212bfbe8ae Mon Sep 17 00:00:00 2001 From: Shiwei Zhang Date: Mon, 13 Jun 2022 14:05:38 +0800 Subject: [PATCH 5/8] reword Signed-off-by: Shiwei Zhang --- specs/registry-auth.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/registry-auth.md b/specs/registry-auth.md index 169c07823..d83acb883 100644 --- a/specs/registry-auth.md +++ b/specs/registry-auth.md @@ -102,7 +102,7 @@ As local credentials may be required to access the remote registries, they need ### Credential Helper -To achieve maximum compatibility of existing systems, [docker credential helpers](https://github.com/docker/docker-credential-helpers) as long as its [protocol](https://docs.docker.com/engine/reference/commandline/login/#credential-helper-protocol) are adopted as the credential helpers for `notation`. +To achieve maximum compatibility with existing systems, [docker credential helpers](https://github.com/docker/docker-credential-helpers) and its [protocol](https://docs.docker.com/engine/reference/commandline/login/#credential-helper-protocol) are adopted as the credential helpers for `notation`. The credential store can be specified globally or per registry by setting the notation config. From 00c1acc1cd0cb921f91dce94a615fecd12158597 Mon Sep 17 00:00:00 2001 From: Shiwei Zhang Date: Tue, 21 Jun 2022 00:17:15 +0800 Subject: [PATCH 6/8] cover insecure registries Signed-off-by: Shiwei Zhang --- specs/registry-auth.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/registry-auth.md b/specs/registry-auth.md index d83acb883..b4f5fb18c 100644 --- a/specs/registry-auth.md +++ b/specs/registry-auth.md @@ -12,7 +12,7 @@ Alternatively, clients can be authenticated via mutual TLS authentication (mTLS) ## Authentication Schemes -Notation supports [basic HTTP authentication][RFC7617] scheme and token schemes including [OAuth 2.0][RFC6749] and [Docker Registry V2 Token][token]. Clients MUST connect to the remote servers via HTTPS if any authentication scheme is applied. +Notation supports [basic HTTP authentication][RFC7617] scheme and token schemes including [OAuth 2.0][RFC6749] and [Docker Registry V2 Token][token]. Clients SHOULD connect to the remote servers via HTTPS if any authentication scheme is applied. ### General Flow From 46166de311cb652666bca4ac91776c67e00cb8c8 Mon Sep 17 00:00:00 2001 From: Shiwei Zhang Date: Tue, 21 Jun 2022 13:05:19 +0800 Subject: [PATCH 7/8] defer cred file to #206 Signed-off-by: Shiwei Zhang --- specs/registry-auth.md | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/specs/registry-auth.md b/specs/registry-auth.md index b4f5fb18c..3457be84f 100644 --- a/specs/registry-auth.md +++ b/specs/registry-auth.md @@ -2,14 +2,12 @@ Registry access is required for pulling the manifests of the images to be verified along with their signatures as well as other advanced operations. This documentation specifies how authentication to the remote registry works and how registry credentials are stored. - ## Communication Channel Although it is secure to transmit artifacts with their signatures via HTTP connections, it is RECOMMENDED to transmit via HTTPS connections for confidentiality and the authenticity of the remote server. Alternatively, clients can be authenticated via mutual TLS authentication (mTLS). In other words, clients connect to servers via HTTP over mTLS by presenting client certificates. In this case, authorization can be applied later without further authentication schemes. - ## Authentication Schemes Notation supports [basic HTTP authentication][RFC7617] scheme and token schemes including [OAuth 2.0][RFC6749] and [Docker Registry V2 Token][token]. Clients SHOULD connect to the remote servers via HTTPS if any authentication scheme is applied. @@ -95,7 +93,6 @@ Notation follows the [Docker Registry v2 authentication][oauth2] specification f **Note** Refresh tokens are often known as identity tokens in the context of registry authentication. - ## Credential Store As local credentials may be required to access the remote registries, they need to be stored and accessed securely. To achieve maximum security, credential helpers are preferred so that credentials are stored in the system key chain with better protection. If credential helpers are not available, notation will fall back to credential files with proper access control. @@ -121,21 +118,7 @@ The credential store can be specified globally or per registry by setting the no ### Credential File -The credential file is alternative credential store when credential helpers are not available. The default file path is - -``` -{CONFIG}/notation/auth.json -``` - -The credential file path can be altered by setting the `credsFile` field of the notation config. - -```json -{ - "credsFile": "/absolute/path/to/auth.json" -} -``` - -Since credentials are stored in plaintext, the permission of the credential file MUST be kept minimum when storing credentials. On Unix / Linux, the permission MUST be either `0600` (default) or `0400` (read-only). +TODO: Define local credential experience without credential provider support (#206). [RFC6749]: https://www.rfc-editor.org/rfc/rfc6749 "OAuth 2.0" [RFC7617]: https://www.rfc-editor.org/rfc/rfc7617 "Basic Auth" From ce2eaf95c6fd689c06aed585be554160d40a50ea Mon Sep 17 00:00:00 2001 From: Shiwei Zhang Date: Tue, 21 Jun 2022 13:06:42 +0800 Subject: [PATCH 8/8] elaborate as suggested Signed-off-by: Shiwei Zhang --- specs/registry-auth.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/registry-auth.md b/specs/registry-auth.md index 3457be84f..39e9c8828 100644 --- a/specs/registry-auth.md +++ b/specs/registry-auth.md @@ -4,7 +4,7 @@ Registry access is required for pulling the manifests of the images to be verifi ## Communication Channel -Although it is secure to transmit artifacts with their signatures via HTTP connections, it is RECOMMENDED to transmit via HTTPS connections for confidentiality and the authenticity of the remote server. +Although it is secure to transmit artifacts with their signatures via HTTP connections as a tampered artifact can be detected through signature verification, it is RECOMMENDED to transmit via HTTPS connections for confidentiality and the authenticity of the remote server. Alternatively, clients can be authenticated via mutual TLS authentication (mTLS). In other words, clients connect to servers via HTTP over mTLS by presenting client certificates. In this case, authorization can be applied later without further authentication schemes.