From a6de19ab9d4aae13aef1dc6aff20a93abe8dc1b9 Mon Sep 17 00:00:00 2001 From: Ina Panova Date: Fri, 17 May 2024 12:27:52 +0200 Subject: [PATCH] Added more information on token auth workflow. [noissue] --- .../admin/guides/change-allowed-artifacts.md | 2 +- .../admin/guides/pull-through-caching.md | 4 - staging_docs/admin/learn/authentication.md | 216 +++++++++++++++++- staging_docs/user/guides/registry-catalog.md | 41 ++++ staging_docs/user/tutorials/00-overview.md | 15 +- 5 files changed, 268 insertions(+), 10 deletions(-) create mode 100644 staging_docs/user/guides/registry-catalog.md diff --git a/staging_docs/admin/guides/change-allowed-artifacts.md b/staging_docs/admin/guides/change-allowed-artifacts.md index 5cd117a05..552ff8277 100644 --- a/staging_docs/admin/guides/change-allowed-artifacts.md +++ b/staging_docs/admin/guides/change-allowed-artifacts.md @@ -1,4 +1,4 @@ -# Support To OCI Artifacts +# OCI Artifacts Support Pulp is not only a container registry, it also supports OCI artifacts by leveraging the config property on the image manifest. diff --git a/staging_docs/admin/guides/pull-through-caching.md b/staging_docs/admin/guides/pull-through-caching.md index ef6c92796..91efde935 100644 --- a/staging_docs/admin/guides/pull-through-caching.md +++ b/staging_docs/admin/guides/pull-through-caching.md @@ -43,7 +43,3 @@ ensures a more reliable container deployment system in production environments. generate a new repository version that incorporates both the "10" and "11" tags, automatically removing the previous version. Repositories and their content remain manageable through standard Pulp API endpoints. The repositories are read-only and public by default. - -A registry may contain several repositories which hold collections of multiple images. Each -repository is identified by its unique name. The list of names of all distributed repositories -is made available through the `_catalog` endpoint. diff --git a/staging_docs/admin/learn/authentication.md b/staging_docs/admin/learn/authentication.md index beb124333..e35070618 100644 --- a/staging_docs/admin/learn/authentication.md +++ b/staging_docs/admin/learn/authentication.md @@ -117,7 +117,7 @@ via the setting `TOKEN_EXPIRATION_TIME`. The default expiration time is `300` se Below is provided an example of the settings file: ```python -TOKEN_SERVER = "http://localhost:24817/token/" +TOKEN_SERVER = "https://puffy.example.com/token/" TOKEN_SIGNATURE_ALGORITHM = 'ES256' PUBLIC_KEY_PATH = '/tmp/public_key.pem' PRIVATE_KEY_PATH = '/tmp/private_key.pem' @@ -125,3 +125,217 @@ PRIVATE_KEY_PATH = '/tmp/private_key.pem' Restart Pulp services in order to reload the updated settings. Pulp will fetch a domain for the token server and will initialize all handlers according to that. + + +!!! note + + Standard container tooling clients like podman, skopeo and docker handle token authentication calls on + behalf of the user during pull and push operations. However, if you would like to debug registry + access or implement manual registry API calls, here are a few examples of how the token authentication + works behind the scene. + +Access the root registry endpoint to check if the token authentication was successfully configured and enabled: + +```bash + $ http 'https://puffy.example.com/v2/' + + HTTP/1.1 401 Unauthorized + Allow: GET, HEAD, OPTIONS + Connection: close + Content-Length: 58 + Content-Type: application/json + Date: Mon, 13 Jul 2020 09:56:54 GMT + Docker-Distribution-Api-Version: registry/2.0 + Server: gunicorn/20.0.4 + Vary: Accept + WWW-Authenticate: Bearer realm="https://puffy.example.com/token/",service="puffy.example.com" + X-Frame-Options: SAMEORIGIN + + { + "detail": "Authentication credentials were not provided." + } +``` + +Since the request was not authenticated, the registry returned an HTTP 401 error and in the authentication header +there are details on how to authenticate. This time send the request with the specified realm and service: + +```bash +$ http https://puffy.example.com/token/?service=puffy.example.com + +HTTP/1.1 200 OK +Allow: GET, HEAD, OPTIONS +Connection: close +Content-Length: 609 +Content-Type: application/json +Date: Mon, 13 Jul 2020 09:57:25 GMT +Server: gunicorn/20.0.4 +Vary: Accept, Cookie +X-Frame-Options: SAMEORIGIN + +{ + "access_token": , + "expires_in": 300, + "issued_at": "2020-07-13T09:57:25.601760Z", + "token": +} +``` + +The token was generated to access registry root endpoint. + +```bash +$ http --auth-type=jwt --auth= https://puffy.example.com/v2/ + +HTTP/1.1 200 OK +Allow: GET, HEAD, OPTIONS +Connection: close +Content-Length: 2 +Content-Type: application/json +Date: Mon, 13 Jul 2020 09:58:40 GMT +Docker-Distribution-Api-Version: registry/2.0 +Server: gunicorn/20.0.4 +Vary: Accept +X-Frame-Options: SAMEORIGIN + +{} +``` + +In order to access other registry endpoints, like manifests, blobs and tags, the scope needs to be provided +as well. In this context, it will be a specific repository with the according action pull or push. + +```bash +$ http https://puffy.example.com/v2/library/azure/tags/list +HTTP/1.1 401 Unauthorized +Access-Control-Expose-Headers: Correlation-ID +Allow: GET, HEAD, OPTIONS +Connection: keep-alive +Content-Length: 106 +Content-Type: application/json +Correlation-ID: c4e809f1e290478b8acfd0c9f7be7d00 +Cross-Origin-Opener-Policy: same-origin +Date: Fri, 17 May 2024 09:18:33 GMT +Docker-Distribution-Api-Version: registry/2.0 +Referrer-Policy: same-origin +Server: nginx +Vary: Accept +WWW-Authenticate: Bearer realm="https://puffy.example.com/token/",service="puffy.example.com",scope="repository:library/azure:pull" +X-Content-Type-Options: nosniff +X-Frame-Options: DENY +X-Registry-Supports-Signatures: 1 + +{ + "errors": [ + { + "code": "UNAUTHORIZED", + "detail": {}, + "message": "Authentication credentials were not provided." + } + ] +} +``` + +```bash +$ http 'https://puffy.example.com/token/?service=puffy.example.com&scope=repository:library/azure:pull' +HTTP/1.1 200 OK +Access-Control-Expose-Headers: Correlation-ID +Allow: GET, HEAD, OPTIONS +Connection: keep-alive +Content-Length: 1311 +Content-Type: application/json +Correlation-ID: 611f0ce122a54509b348ff54d5030c80 +Cross-Origin-Opener-Policy: same-origin +Date: Fri, 17 May 2024 09:20:29 GMT +Referrer-Policy: same-origin +Server: nginx +Strict-Transport-Security: max-age=15768000 +Vary: Accept +X-Content-Type-Options: nosniff +X-Frame-Options: DENY + +{ + "access_token": , + "expires_in": 300, + "issued_at": "2024-05-17T09:20:29.660984Z", + "token": +} +``` + +```bash +$ http https://puffy.example.com/v2/library/azure/tags/list --auth-type=jwt --auth= +HTTP/1.1 200 OK +Access-Control-Expose-Headers: Correlation-ID +Allow: GET, HEAD, OPTIONS +Connection: keep-alive +Content-Length: 42 +Content-Type: application/json +Correlation-ID: b944d8b6b1fc474eada8531776a2609b +Cross-Origin-Opener-Policy: same-origin +Date: Fri, 17 May 2024 09:33:04 GMT +Docker-Distribution-Api-Version: registry/2.0 +Referrer-Policy: same-origin +Server: nginx +Strict-Transport-Security: max-age=15768000 +Vary: Accept +X-Content-Type-Options: nosniff +X-Frame-Options: DENY +X-Registry-Supports-Signatures: 1 + +{ + "name": "library/azure", + "tags": [ + "latest" + ] +} +``` + +!!! note + + If the repository is private, one needs to provide basic auth credentials while + requesting the token in order to pull content from it. If no basic auth is provided, + then the generated token is for the anonymous user. + In order to push content to the registry a user always needs to be authenticated. + +```bash +$ http 'https://puffy.example.com/token/?service=puffy.example.com&scope=repository:private/azure:pull' --auth-type=basic --auth=alice:wonderland +``` + +!!! note + + Some registry endpoints, like ``_catalog`` endpoint, are not opened to anonymous/not logged-in users and + require credentials provided during the token request. Anonymous tokens will still lead to HTTP 401 insufficient scope errors. + +```bash +http 'https://puffy.example.com/token/?service=puffy.example.com&scope=registry:catalog:*' --auth-type=basic --auth=alice:wonderland +``` + +This token embeds permissions that allow to see only those repositories that Alice has access to. + +```bash +$ http https://puffy.example.com/v2/_catalog --auth-type=jwt --auth= +HTTP/1.1 200 OK +Access-Control-Expose-Headers: Correlation-ID +Allow: GET, HEAD, OPTIONS +Connection: keep-alive +Content-Length: 63 +Content-Type: application/json +Correlation-ID: f4ea6c26bcb7462099c0d5757178f7ca +Cross-Origin-Opener-Policy: same-origin +Date: Fri, 17 May 2024 09:57:11 GMT +Docker-Distribution-Api-Version: registry/2.0 +Referrer-Policy: same-origin +Server: nginx +Strict-Transport-Security: max-age=15768000 +Vary: Accept +X-Content-Type-Options: nosniff +X-Frame-Options: DENY +X-Registry-Supports-Signatures: 1 + +{ + "repositories": [ + "alice/azure", + "alice/openstack-cron" + ] +} +``` + +If you are still unsure why you are geting HTTP 401 errors with the generated token, paste its payload to https://jwt.io/ +and it will help identify whether the token contains the needed access. diff --git a/staging_docs/user/guides/registry-catalog.md b/staging_docs/user/guides/registry-catalog.md new file mode 100644 index 000000000..f297f7873 --- /dev/null +++ b/staging_docs/user/guides/registry-catalog.md @@ -0,0 +1,41 @@ +# Registry catalog + +A registry may contain several repositories which hold collections of multiple images. Each +repository is identified by its unique name. The list of names of all distributed repositories +is made available through the ``_catalog`` endpoint. + +For instance, let's assume that a new distribution of a repository with the name ``library/zoo`` +was recently created. Its name is now possible to fetch from the list of names of distributed +repositories. + +```bash +$ http https://puffy.example.com/v2/_catalog +HTTP/1.1 200 OK +Access-Control-Expose-Headers: Correlation-ID +Allow: GET, HEAD, OPTIONS +Connection: keep-alive +Content-Length: 63 +Content-Type: application/json +Correlation-ID: 1de33d4807a244f1b00c10df3fdc7a1b +Cross-Origin-Opener-Policy: same-origin +Date: Fri, 17 May 2024 10:20:25 GMT +Docker-Distribution-Api-Version: registry/2.0 +Referrer-Policy: same-origin +Server: nginx +Strict-Transport-Security: max-age=15768000 +Vary: Accept +X-Content-Type-Options: nosniff +X-Frame-Options: DENY +X-Registry-Supports-Signatures: 1 + +{ + "repositories": [ + "library/zoo", + "alice/azure", + ] +} +``` +!!! note + For the sake of simplicity of this example, there is missing required user token authentication + to this endpoint. Users will see only those repositories in the registry catalog that they have access to. + Visit [Token authentication section](site:pulp_container/docs/admin/learn/authentication.md) to learn more. diff --git a/staging_docs/user/tutorials/00-overview.md b/staging_docs/user/tutorials/00-overview.md index ebad267b0..a9c148f68 100644 --- a/staging_docs/user/tutorials/00-overview.md +++ b/staging_docs/user/tutorials/00-overview.md @@ -1,7 +1,9 @@ # Overview The Pulp Container plugin extends Pulp so that you can host your container registry and distribute containers in an on-premises environment. -You can synchronize from a range of Docker Registry HTTP API V2-compatible registries. +Pulp is a Container and Artifact Registry that implements [OCI Distribution Specification](https://github.com/opencontainers/distribution-spec/) +and [OCI Image Format Specification](https://github.com/opencontainers/image-spec). +On top of the standard registry capabilites, Pulp Registry provides additional features. For example, you can synchronize from any Container Registry that is HTTP API V2-compatible. Depending on your needs, you can perform whole or partial syncs from these remote repositories, blend content from different sources, and distribute them throughout your organization using Pulp. You can also build OCI-compatible images with Pulp Container and push them to a repository in Pulp so you can distribute private containers. @@ -13,7 +15,7 @@ If you'd like to watch a recent talk about Pulp Container and see it in action, - Synchronize container image repositories hosted on Docker-hub, Google Container Registry, Quay.io, etc., in mirror or additive mode -- Automatically creates Versioned Repositories so every operation is a restorable snapshot +- Automatically create Versioned Repositories so every operation is a restorable snapshot - Download content on-demand when requested by clients to reduce disk space - Perform docker/podman pull from a container distribution served by Pulp - Perform docker/podman push to the Pulp Registry @@ -21,6 +23,11 @@ If you'd like to watch a recent talk about Pulp Container and see it in action, - Curate container images by creating repository versions with a specific set of images - Build an OCI format image from a Containerfile and make it available from the Pulp Registry - Host content either locally or on S3 -- De-duplication of all saved content +- De-duplicate all saved content - Support disconnected and air-gapped environments with the Pulp Import/Export facility for container repositories -- Support for hosting Flatpak content in OCI format +- Host Flatpak content in OCI format +- Host Helm Charts +- Host OCI artifacts +- Sign images and host Cosign signatures, SBOMS and attestations +- Sign images and host Atomic signature type via extensions API +- Host content via pull-through caching distributions