Use Red Hat Quay
Preface
Red Hat Quay container image registries serve as centralized hubs for storing container images. Users of Red Hat Quay can create repositories to effectively manage images and grant specific read (pull) and write (push) permissions to the repositories as deemed necessary. Administrative privileges expand these capabilities, allowing users to perform a broader set of tasks, like the ability to add users and control default settings.
This guide offers an overview of Red Hat Quay’s users and organizations, its tenancy model, and basic operations like creating and deleting users, organizations, and repositories, handling access, and interacting with tags. It includes both UI and API operations.
The following API endpoints are linked to their associated entry in the Red Hat Quay API guide. The Red Hat Quay API guide provides more information about each endpoint, such as response codes and optional query parameters.
Chapter 1. Red Hat Quay tenancy model
Before creating repositories to contain your container images in Red Hat Quay, you should consider how these repositories will be structured. With Red Hat Quay, each repository requires a connection with either an Organization or a User. This affiliation defines ownership and access control for the repositories.
1.1. Tenancy model
- Organizations provide a way of sharing repositories under a common namespace that does not belong to a single user. Instead, these repositories belong to several users in a shared setting, such as a company.
- Teams provide a way for an Organization to delegate permissions. Permissions can be set at the global level (for example, across all repositories), or on specific repositories. They can also be set for specific sets, or groups, of users.
-
Users can log in to a registry through the web UI or a by using a client like Podman and using their respective login commands, for example,
$ podman login
. Each user automatically gets a user namespace, for example,<quay-server.example.com>/<user>/<username>
, orquay.io/<username>
if you are using Quay.io. - Superusers have enhanced access and privileges through the Super User Admin Panel in the user interface. Superuser API calls are also available, which are not visible or accessible to normal users.
- Robot accounts provide automated access to repositories for non-human users like pipeline tools. Robot accounts are similar to OpenShift Container Platform Service Accounts. Permissions can be granted to a robot account in a repository by adding that account like you would another user or team.
Chapter 2. Red Hat Quay user accounts overview
A user account represents an individual with authenticated access to the platform’s features and functionalities. User accounts provide the capability to create and manage repositories, upload and retrieve container images, and control access permissions for these resources. This account is pivotal for organizing and overseeing container image management within Red Hat Quay.
You can create and delete new users on the zRed Hat Quay UI or by using the Red Hat Quay API.
2.1. Creating a user account by using the UI
Use the following procedure to create a new user for your Red Hat Quay repository using the UI.
Prerequisites
- You are logged into your Red Hat Quay deployment as a superuser.
Procedure
- Log in to your Red Hat Quay repository as the superuser.
- In the navigation pane, select your account name, and then click Super User Admin Panel.
- Click the Users icon in the column.
- Click the Create User button.
- Enter the new user’s Username and Email address, and then click the Create User button.
You are redirected to the Users page, where there is now another Red Hat Quay user.
NoteYou might need to refresh the Users page to show the additional user.
On the Users page, click the Options cogwheel associated with the new user. A drop-down menu appears, as shown in the following figure:
- Click Change Password.
Add the new password, and then click Change User Password.
The new user can now use that username and password to log in using the web UI or through their preferred container client, like Podman.
2.2. Creating a user account by using the Red Hat Quay API
Use the following procedure to create a new user for your Red Hat Quay repository by using the API.
Prerequisites
- You are logged into your Red Hat Quay deployment as a superuser.
- You have Created an OAuth access token.
-
You have set
BROWSER_API_CALLS_XHR_ONLY: false
in yourconfig.yaml
file.
Procedure
Enter the following command to create a new user using the
POST /api/v1/superuser/users/
endpoint:$ curl -X POST -H "Authorization: Bearer <bearer_token>" -H "Content-Type: application/json" -d '{ "username": "newuser", "email": "newuser@example.com" }' "https://<quay-server.example.com>/api/v1/superuser/users/"
Example output
{"username": "newuser", "email": "newuser@example.com", "password": "IJWZ8TIY301KPFOW3WEUJEVZ3JR11CY1", "encrypted_password": "9Q36xF54YEOLjetayC0NBaIKgcFFmIHsS3xTZDLzZSrhTBkxUc9FDwUKfnxLWhco6oBJV1NDBjoBcDGmsZMYPt1dSA4yWpPe/JKY9pnDcsw="}
Navigate to your Red Hat Quay registry endpoint, for example,
quay-server.example.com
and login with the username and password generated from the API call. In this scenario, the username isnewuser
and the password isIJWZ8TIY301KPFOW3WEUJEVZ3JR11CY1
. Alternatively, you can log in to the registry with the CLI. For example:$ podman login <quay-server.example.com>
Example output
username: newuser password: IJWZ8TIY301KPFOW3WEUJEVZ3JR11CY1
Optional. You can obtain a list of all users, including superusers, by using the
GET /api/v1/superuser/users/
endpoint:$ curl -X GET -H "Authorization: Bearer <bearer_token>" "https://<quay-server.example.com>/api/v1/superuser/users/"
Example output
{"users": [{"kind": "user", "name": "quayadmin", "username": "quayadmin", "email": "quay@quay.com", "verified": true, "avatar": {"name": "quayadmin", "hash": "b28d563a6dc76b4431fc7b0524bbff6b810387dac86d9303874871839859c7cc", "color": "#17becf", "kind": "user"}, "super_user": true, "enabled": true}, {"kind": "user", "name": "newuser", "username": "newuser", "email": "newuser@example.com", "verified": true, "avatar": {"name": "newuser", "hash": "f338a2c83bfdde84abe2d3348994d70c34185a234cfbf32f9e323e3578e7e771", "color": "#9edae5", "kind": "user"}, "super_user": false, "enabled": true}]}
2.3. Deleting a user by using the UI
Use the following procedure to delete a user from your Red Hat Quay repository using the UI. Note that after deleting the user, any repositories that the user had in their private account become unavailable.
In some cases, when accessing the Users tab in the Superuser Admin Panel of the Red Hat Quay UI, you might encounter a situation where no users are listed. Instead, a message appears, indicating that Red Hat Quay is configured to use external authentication, and users can only be created in that system.
This error occurs for one of two reasons:
- The web UI times out when loading users. When this happens, users are not accessible to perform any operations on.
- On LDAP authentication. When a userID is changed but the associated email is not. Currently, Red Hat Quay does not allow the creation of a new user with an old email address.
When this happens, you must delete the user using the Red Hat Quay API.
Prerequisites
- You are logged into your Red Hat Quay deployment as a superuser.
Procedure
- Log in to your Red Hat Quay repository as the superuser.
- In the navigation pane, select your account name, and then click Super User Admin Panel.
- Click the Users icon in the navigation pane.
- Click the Options cogwheel beside the user to be deleted.
- Click Delete User, and then confirm deletion by clicking Delete User.
2.4. Deleting a user by using the Red Hat Quay API
Use the following procedure to delete a user from Red Hat Quay using the API.
After deleting the user, any repositories that this user had in his private account become unavailable.
Prerequisites
- You are logged into your Red Hat Quay deployment as a superuser.
- You have Created an OAuth access token.
-
You have set
BROWSER_API_CALLS_XHR_ONLY: false
in yourconfig.yaml
file.
Procedure
Enter the following
DELETE /api/v1/superuser/users/{username}
command to delete a user from the command line:$ curl -X DELETE -H "Authorization: Bearer <insert token here>" https://<quay-server.example.com>/api/v1/superuser/users/<username>
The CLI does not return information when deleting a user from the CLI. To confirm deletion, you can check the Red Hat Quay UI by navigating to Superuser Admin Panel → Users, or by entering the following
GET /api/v1/superuser/users/
command. You can then check to see if they are present.$ curl -X GET -H "Authorization: Bearer <bearer_token>" "https://<quay-server.example.com>/api/v1/superuser/users/"
Chapter 3. Red Hat Quay organizations overview
In = Red Hat Quay an organization is a grouping of users, repositories, and teams. It provides a means to organize and manage access control and permissions within the registry. With organizations, administrators can assign roles and permissions to users and teams. Other useful information about organizations includes the following:
- You cannot have an organization embedded within another organization. To subdivide an organization, you use teams.
Organizations cannot contain users directly. You must first add a team, and then add one or more users to each team.
NoteIndividual users can be added to specific repositories inside of an organization. Consequently, those users are not members of any team on the Repository Settings page. The Collaborators View on the Teams and Memberships page shows users who have direct access to specific repositories within the organization without needing to be part of that organization specifically.
- Teams can be set up in organizations as just members who use the repositories and associated images, or as administrators with special privileges for managing the Organization.
Users can create their own organization to share repositories of container images. This can be done through the Red Hat Quay UI, or by the Red Hat Quay API if you have an OAuth token.
3.1. Creating an organization by using the UI
Use the following procedure to create a new organization by using the UI.
Procedure
- Log in to your Red Hat Quay registry.
- Click Organization in the navigation pane.
- Click Create Organization.
-
Enter an Organization Name, for example,
testorg
. - Enter an Organization Email.
- Click Create.
Now, your example organization should populate under the Organizations page.
3.2. Creating an organization by using the Red Hat Quay API
Use the following procedure to create a new organization using the Red Hat Quay API.
Prerequisites
- You have Created an OAuth access token.
-
You have set
BROWSER_API_CALLS_XHR_ONLY: false
in yourconfig.yaml
file.
Procedure
Enter the following command to create a new organization using the
POST /api/v1/organization/
endpoint:$ curl -X POST -H "Authorization: Bearer <bearer_token>" -H "Content-Type: application/json" -d '{ "name": "<new_organization_name>" }' "https://<quay-server.example.com>/api/v1/organization/"
Example output
"Created"
3.3. Organization settings
With = Red Hat Quay, some basic organization settings can be adjusted by using the UI. This includes adjusting general settings, such as the e-mail address associated with the organization, and time machine settings, which allows administrators to adjust when a tag is garbage collected after it is permanently deleted.
Use the following procedure to alter your organization settings by using the v2 UI.
Procedure
- On the v2 UI, click Organizations.
-
Click the name of the organization that you will create the robot account for, for example,
test-org
. - Click the Settings tab.
- Optional. Enter the email address associated with the organization.
Optional. Set the allotted time for the Time Machine feature to one of the following:
- A few seconds
- A day
- 7 days
- 14 days
- A month
- Click Save.
3.4. Deleting an organization by using the UI
Use the following procedure to delete an organization using the v2 UI.
Procedure
-
On the Organizations page, select the name of the organization you want to delete, for example,
testorg
. - Click the More Actions drop down menu.
Click Delete.
NoteOn the Delete page, there is a Search input box. With this box, users can search for specific organizations to ensure that they are properly scheduled for deletion. For example, if a user is deleting 10 organizations and they want to ensure that a specific organization was deleted, they can use the Search input box to confirm said organization is marked for deletion.
- Confirm that you want to permanently delete the organization by typing confirm in the box.
Click Delete.
After deletion, you are returned to the Organizations page.
NoteYou can delete more than one organization at a time by selecting multiple organizations, and then clicking More Actions → Delete.
3.5. Deleting an organization by using the Red Hat Quay API
Use the following procedure to delete an organization using the Red Hat Quay API.
Prerequisites
- You have Created an OAuth access token.
-
You have set
BROWSER_API_CALLS_XHR_ONLY: false
in yourconfig.yaml
file.
Procedure
Enter the following command to delete an organization using the
DELETE /api/v1/organization/{orgname}
endpoint:$ curl -X DELETE \ -H "Authorization: Bearer <bearer_token>" \ "https://<quay-server.example.com>/api/v1/organization/<organization_name>"
The CLI does not return information when deleting an organization from the CLI. To confirm deletion, you can check the Red Hat Quay UI, or you can enter the
GET /api/v1/organization/{orgname}
command to see if details are returned for the deleted organization:$ curl -X GET \ -H "Authorization: Bearer <bearer_token>" \ "<quay-server.example.com>/api/v1/organization/<organization_name>"
Example output
{"detail": "Not Found", "error_message": "Not Found", "error_type": "not_found", "title": "not_found", "type": "http://<quay-server.example.com>/api/v1/error/not_found", "status": 404}
Chapter 4. Red Hat Quay repository overview
A repository provides a central location for storing a related set of container images. These images can be used to build applications along with their dependencies in a standardized format.
Repositories are organized by namespaces. Each namespace can have multiple repositories. For example, you might have a namespace for your personal projects, one for your company, or one for a specific team within your organization.
Red Hat Quay provides users with access controls for their repositories. Users can make a repository public, meaning that anyone can pull, or download, the images from it, or users can make it private, restricting access to authorized users or teams.
There are three ways to create a repository in Red Hat Quay: by pushing an image with the relevant podman
command, by using the Red Hat Quay UI, or by using the Red Hat Quay API. Similarly, repositories can be deleted by using the UI or the proper API endpoint.
4.1. Creating a repository by using the UI
Use the following procedure to create a repository using the Red Hat Quay UI.
Procedure
Use the following procedure to create a repository using the v2 UI.
Procedure
- Click Repositories on the navigation pane.
- Click Create Repository.
Select a namespace, for example, quayadmin, and then enter a Repository name, for example,
testrepo
.ImportantDo not use the following words in your repository name: *
build
*trigger
*tag
When these words are used for repository names, users are unable access the repository, and are unable to permanently delete the repository. Attempting to delete these repositories returns the following error:
Failed to delete repository <repository_name>, HTTP404 - Not Found.
Click Create.
Now, your example repository should populate under the Repositories page.
- Optional. Click Settings → Repository visibility → Make private to set the repository to private.
4.2. Creating a repository by using Podman
With the proper credentials, you can push an image to a repository using Podman that does not yet exist in your Red Hat Quay instance. Pushing an image refers to the process of uploading a container image from your local system or development environment to a container registry like Red Hat Quay. After pushing an image to your registry, a repository is created. If you push an image through the command-line interface (CLI) without first creating a repository on the UI, the created repository is set to Private.
Use the following procedure to create an image repository by pushing an image.
Prerequisites
-
You have download and installed the
podman
CLI. - You have logged into your registry.
- You have pulled an image, for example, busybox.
Procedure
Pull a sample page from an example registry. For example:
$ sudo podman pull busybox
Example output
Trying to pull docker.io/library/busybox... Getting image source signatures Copying blob 4c892f00285e done Copying config 22667f5368 done Writing manifest to image destination Storing signatures 22667f53682a2920948d19c7133ab1c9c3f745805c14125859d20cede07f11f9
Tag the image on your local system with the new repository and image name. For example:
$ sudo podman tag docker.io/library/busybox quay-server.example.com/quayadmin/busybox:test
Push the image to the registry. Following this step, you can use your browser to see the tagged image in your repository.
$ sudo podman push --tls-verify=false quay-server.example.com/quayadmin/busybox:test
Example output
Getting image source signatures Copying blob 6b245f040973 done Copying config 22667f5368 done Writing manifest to image destination Storing signatures
4.3. Creating a repository by using the API
Use the following procedure to create an image repository using the Red Hat Quay API.
Prerequisites
- You have Created an OAuth access token.
-
You have set
BROWSER_API_CALLS_XHR_ONLY: false
in yourconfig.yaml
file.
Procedure
Enter the following command to create a repository using the
POST /api/v1/repository
endpoint:$ curl -X POST \ -H "Authorization: Bearer <bearer_token>" \ -H "Content-Type: application/json" \ -d '{ "repository": "<new_repository_name>", "visibility": "<private>", "description": "<This is a description of the new repository>." }' \ "https://quay-server.example.com/api/v1/repository"
Example output
{"namespace": "quayadmin", "name": "<new_repository_name>", "kind": "image"}
4.4. Deleting a repository by using the UI
You can delete a repository directly on the UI.
Prerequisites
- You have created a repository.
Procedure
-
On the Repositories page of the v2 UI, check the box of the repository that you want to delete, for example,
quayadmin/busybox
. - Click the Actions drop-down menu.
- Click Delete.
Type confirm in the box, and then click Delete.
After deletion, you are returned to the Repositories page.
4.5. Deleting a repository by using the Red Hat Quay API
Use the following procedure to delete a repository using the Red Hat Quay API.
Prerequisites
- You have Created an OAuth access token.
-
You have set
BROWSER_API_CALLS_XHR_ONLY: false
in yourconfig.yaml
file.
Procedure
Enter the following command to delete a repository using the
DELETE /api/v1/repository/{repository}
endpoint:$ curl -X DELETE -H "Authorization: Bearer <bearer_token>" "<quay-server.example.com>/api/v1/repository/<namespace>/<repository_name>"
The CLI does not return information when deleting a repository from the CLI. To confirm deletion, you can check the Red Hat Quay UI, or you can enter the following
GET /api/v1/repository/{repository}
command to see if details are returned for the deleted repository:$ curl -X GET -H "Authorization: Bearer <bearer_token>" "<quay-server.example.com>/api/v1/repository/<namespace>/<repository_name>"
Example output
{"detail": "Not Found", "error_message": "Not Found", "error_type": "not_found", "title": "not_found", "type": "http://quay-server.example.com/api/v1/error/not_found", "status": 404}
Chapter 5. Red Hat Quay Robot Account overview
Robot Accounts are used to set up automated access to the repositories in your Red Hat Quay registry. They are similar to OpenShift Container Platform service accounts.
Setting up a Robot Account results in the following:
- Credentials are generated that are associated with the Robot Account.
- Repositories and images that the Robot Account can push and pull images from are identified.
- Generated credentials can be copied and pasted to use with different container clients, such as Docker, Podman, Kubernetes, Mesos, and so on, to access each defined repository.
Each Robot Account is limited to a single user namespace or Organization. For example, the Robot Account could provide access to all repositories for the user quayadmin
. However, it cannot provide access to repositories that are not in the user’s list of repositories.
Robot Accounts can be created using the Red Hat Quay UI, or through the CLI using the Red Hat Quay API. After creation, Red Hat Quay administrators can leverage more advanced features with Robot Accounts, such as keyless authentication.
5.1. Creating a robot account by using the UI
Use the following procedure to create a robot account using the v2 UI.
Procedure
- On the v2 UI, click Organizations.
-
Click the name of the organization that you will create the robot account for, for example,
test-org
. - Click the Robot accounts tab → Create robot account.
-
In the Provide a name for your robot account box, enter a name, for example,
robot1
. The name of your Robot Account becomes a combination of your username plus the name of the robot, for example,quayadmin+robot1
Optional. The following options are available if desired:
- Add the robot account to a team.
- Add the robot account to a repository.
- Adjust the robot account’s permissions.
On the Review and finish page, review the information you have provided, then click Review and finish. The following alert appears: Successfully created robot account with robot name: <organization_name> + <robot_name>.
Alternatively, if you tried to create a robot account with the same name as another robot account, you might receive the following error message: Error creating robot account.
- Optional. You can click Expand or Collapse to reveal descriptive information about the robot account.
- Optional. You can change permissions of the robot account by clicking the kebab menu → Set repository permissions. The following message appears: Successfully updated repository permission.
Optional. You can click the name of your robot account to obtain the following information:
- Robot Account: Select this obtain the robot account token. You can regenerate the token by clicking Regenerate token now.
- Kubernetes Secret: Select this to download credentials in the form of a Kubernetes pull secret YAML file.
-
Podman: Select this to copy a full
podman login
command line that includes the credentials. -
Docker Configuration: Select this to copy a full
docker login
command line that includes the credentials.
5.2. Creating a robot account by using the Red Hat Quay API
Use the following procedure to create a robot account using the Red Hat Quay API.
Prerequisites
- You have Created an OAuth access token.
-
You have set
BROWSER_API_CALLS_XHR_ONLY: false
in yourconfig.yaml
file.
Procedure
Enter the following command to create a new robot account for an organization using the
PUT /api/v1/organization/{orgname}/robots/{robot_shortname}
endpoint:$ curl -X PUT -H "Authorization: Bearer <bearer_token>" "https://<quay-server.example.com>/api/v1/organization/<organization_name>/robots/<robot_name>"
Example output
{"name": "orgname+robot-name", "created": "Fri, 10 May 2024 15:11:00 -0000", "last_accessed": null, "description": "", "token": "<example_secret>", "unstructured_metadata": null}
Enter the following command to create a new robot account for the current user with the
PUT /api/v1/user/robots/{robot_shortname}
endpoint:$ curl -X PUT -H "Authorization: Bearer <bearer_token>" "https://<quay-server.example.com>/api/v1/user/robots/<robot_name>"
Example output
{"name": "quayadmin+robot-name", "created": "Fri, 10 May 2024 15:24:57 -0000", "last_accessed": null, "description": "", "token": "<example_secret>", "unstructured_metadata": null}
5.3. Bulk managing robot account repository access
Use the following procedure to manage, in bulk, robot account repository access by using the Red Hat Quay v2 UI.
Prerequisites
- You have created a robot account.
- You have created multiple repositories under a single organization.
Procedure
- On the Red Hat Quay v2 UI landing page, click Organizations in the navigation pane.
- On the Organizations page, select the name of the organization that has multiple repositories. The number of repositories under a single organization can be found under the Repo Count column.
- On your organization’s page, click Robot accounts.
- For the robot account that will be added to multiple repositories, click the kebab icon → Set repository permissions.
On the Set repository permissions page, check the boxes of the repositories that the robot account will be added to. For example:
- Set the permissions for the robot account, for example, None, Read, Write, Admin.
- Click save. An alert that says Success alert: Successfully updated repository permission appears on the Set repository permissions page, confirming the changes.
- Return to the Organizations → Robot accounts page. Now, the Repositories column of your robot account shows the number of repositories that the robot account has been added to.
5.4. Disabling robot accounts by using the UI
Red Hat Quay administrators can manage robot accounts by disallowing users to create new robot accounts.
Robot accounts are mandatory for repository mirroring. Setting the ROBOTS_DISALLOW
configuration field to true
breaks mirroring configurations. Users mirroring repositories should not set ROBOTS_DISALLOW
to true
in their config.yaml
file. This is a known issue and will be fixed in a future release of Red Hat Quay.
Use the following procedure to disable robot account creation.
Prerequisites
- You have created multiple robot accounts.
Procedure
Update your
config.yaml
field to add theROBOTS_DISALLOW
variable, for example:ROBOTS_DISALLOW: true
- Restart your Red Hat Quay deployment.
Verification: Creating a new robot account
- Navigate to your Red Hat Quay repository.
- Click the name of a repository.
- In the navigation pane, click Robot Accounts.
- Click Create Robot Account.
-
Enter a name for the robot account, for example,
<organization-name/username>+<robot-name>
. -
Click Create robot account to confirm creation. The following message appears:
Cannot create robot account. Robot accounts have been disabled. Please contact your administrator.
Verification: Logging into a robot account
On the command-line interface (CLI), attempt to log in as one of the robot accounts by entering the following command:
$ podman login -u="<organization-name/username>+<robot-name>" -p="KETJ6VN0WT8YLLNXUJJ4454ZI6TZJ98NV41OE02PC2IQXVXRFQ1EJ36V12345678" <quay-server.example.com>
The following error message is returned:
Error: logging into "<quay-server.example.com>": invalid username/password
You can pass in the
log-level=debug
flag to confirm that robot accounts have been deactivated:$ podman login -u="<organization-name/username>+<robot-name>" -p="KETJ6VN0WT8YLLNXUJJ4454ZI6TZJ98NV41OE02PC2IQXVXRFQ1EJ36V12345678" --log-level=debug <quay-server.example.com>
... DEBU[0000] error logging into "quay-server.example.com": unable to retrieve auth token: invalid username/password: unauthorized: Robot accounts have been disabled. Please contact your administrator.
5.5. Regenerating a robot account token by using the Red Hat Quay API
Use the following procedure to regenerate a robot account token using the Red Hat Quay API.
Prerequisites
- You have Created an OAuth access token.
-
You have set
BROWSER_API_CALLS_XHR_ONLY: false
in yourconfig.yaml
file.
Procedure
Enter the following command to regenerate a robot account token for an organization using the
POST /api/v1/organization/{orgname}/robots/{robot_shortname}/regenerate
endpoint:$ curl -X POST \ -H "Authorization: Bearer <bearer_token>" \ "<quay-server.example.com>/api/v1/organization/<orgname>/robots/<robot_shortname>/regenerate"
Example output
{"name": "test-org+test", "created": "Fri, 10 May 2024 17:46:02 -0000", "last_accessed": null, "description": "", "token": "<example_secret>"}
Enter the following command to regenerate a robot account token for the current user with the
POST /api/v1/user/robots/{robot_shortname}/regenerate
endpoint:$ curl -X POST \ -H "Authorization: Bearer <bearer_token>" \ "<quay-server.example.com>/api/v1/user/robots/<robot_shortname>/regenerate"
Example output
{"name": "quayadmin+test", "created": "Fri, 10 May 2024 14:12:11 -0000", "last_accessed": null, "description": "", "token": "<example_secret>"}
5.6. Deleting a robot account by using the UI
Use the following procedure to delete a robot account using the Red Hat Quay UI.
Procedure
- Log into your Red Hat Quay registry:
- Click the name of the Organization that has the robot account.
- Click Robot accounts.
- Check the box of the robot account to be deleted.
- Click the kebab menu.
- Click Delete.
-
Type
confirm
into the textbox, then click Delete.
5.7. Deleting a robot account by using the Red Hat Quay API
Use the following procedure to delete a robot account using the Red Hat Quay API.
Prerequisites
- You have Created an OAuth access token.
-
You have set
BROWSER_API_CALLS_XHR_ONLY: false
in yourconfig.yaml
file.
Procedure
Enter the following command to delete a robot account for an organization using the
DELETE /api/v1/organization/{orgname}/robots/{robot_shortname}
endpoint:curl -X DELETE \ -H "Authorization: Bearer <bearer_token>" \ "<quay-server.example.com>/api/v1/organization/<organization_name>/robots/<robot_shortname>"
The CLI does not return information when deleting a robot account with the API. To confirm deletion, you can check the Red Hat Quay UI, or you can enter the following
GET /api/v1/organization/{orgname}/robots
command to see if details are returned for the robot account:$ curl -X GET -H "Authorization: Bearer <bearer_token>" "https://<quay-server.example.com>/api/v1/organization/<organization_name>/robots"
Example output
{"robots": []}
Enter the following command to delete a robot account for the current user with the
DELETE /api/v1/user/robots/{robot_shortname}
endpoint:$ curl -X DELETE \ -H "Authorization: Bearer <bearer_token>" \ "<quay-server.example.com>/api/v1/user/robots/<robot_shortname>"
The CLI does not return information when deleting a robot account for the current user with the API. To confirm deletion, you can check the Red Hat Quay UI, or you can enter the following
GET /api/v1/user/robots/{robot_shortname}
command to see if details are returned for the robot account:$ curl -X GET \ -H "Authorization: Bearer <bearer_token>" \ "<quay-server.example.com>/api/v1/user/robots/<robot_shortname>"
Example output
{"message":"Could not find robot with specified username"}
5.8. Keyless authentication with robot accounts
In previous versions of Red Hat Quay, robot account tokens were valid for the lifetime of the token unless deleted or regenerated. Tokens that do not expire have security implications for users who do not want to store long-term passwords or manage the deletion, or regeneration, or new authentication tokens.
With Red Hat Quay 3, Red Hat Quay administrators are provided the ability to exchange external OIDC token for short-lived, or ephemeral robot account tokens with either Red Hat Single Sign-On (based on the Keycloak project) or Microsoft Entra ID. This allows robot accounts to leverage tokens that last one hour, which are are refreshed regularly and can be used to authenticate individual transactions.
This feature greatly enhances the security of your Red Hat Quay registry by mitigating the possibility of robot token exposure by removing the tokens after one hour.
Configuring keyless authentication with robot accounts is a multi-step procedure that requires setting a robot federation, generating an OAuth2 token from your OIDC provider, and exchanging the OAuth2 token for a robot account access token.
5.8.1. Generating an OAuth2 token with Red Hat Sign Sign-On
The following procedure shows you how to generate an OAuth2 token using Red Hat Single Sign-On. Depending on your OIDC provider, these steps will vary.
Procedure
On the Red Hat Single Sign-On UI:
- Click Clients and then the name of the application or service that can request authentication of a user.
On the Settings page of your client, ensure that the following options are set or enabled:
- Client ID
- Valid redirect URI
- Client authentication
- Authorization
- Standard flow
Direct access grants
NoteSettings can differ depending on your setup.
- On the Credentials page, store the Client Secret for future use.
-
On the Users page, click Add user and enter a username, for example,
service-account-quaydev
. Then, click Create. - Click the name of of the user, for example service-account-quaydev on the Users page.
- Click the Credentials tab → Set password → and provide a password for the user. If warranted, you can make this password temporary by selecting the Temporary option.
Click the Realm settings tab → OpenID Endpoint Configuration. Store the
/protocol/openid-connect/token
endpoint. For example:http://localhost:8080/realms/master/protocol/openid-connect/token
On a web browser, navigate to the following URL:
http://<keycloak_url>/realms/<realm_name>/protocol/openid-connect/auth?response_type=code&client_id=<client_id>
- When prompted, log in with the service-account-quaydev user and the temporary password you set. Complete the login by providing the required information and setting a permanent password if necessary.
You are redirected to the URI address provided for your client. For example:
https://localhost:3000/cb?session_state=5c9bce22-6b85-4654-b716-e9bbb3e755bc&iss=http%3A%2F%2Flocalhost%3A8080%2Frealms%2Fmaster&code=ea5b76eb-47a5-4e5d-8f71-0892178250db.5c9bce22-6b85-4654-b716-e9bbb3e755bc.cdffafbc-20fb-42b9-b254-866017057f43
Take note of the
code
provided in the address. For example:code=ea5b76eb-47a5-4e5d-8f71-0892178250db.5c9bce22-6b85-4654-b716-e9bbb3e755bc.cdffafbc-20fb-42b9-b254-866017057f43
NoteThis is a temporary code that can only be used one time. If necessary, you can refresh the page or revisit the URL to obtain another code.
On your terminal, use the following
curl -X POST
command to generate a temporary OAuth2 access token:$ curl -X POST "http://localhost:8080/realms/master/protocol/openid-connect/token" 1 -H "Content-Type: application/x-www-form-urlencoded" \ -d "client_id=quaydev" 2 -d "client_secret=g8gPsBLxVrLo2PjmZkYBdKvcB9C7fmBz" 3 -d "grant_type=authorization_code" -d "code=ea5b76eb-47a5-4e5d-8f71-0892178250db.5c9bce22-6b85-4654-b716-e9bbb3e755bc.cdffafbc-20fb-42b9-b254-866017057f43" 4
Example output
{"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJTVmExVHZ6eDd2cHVmc1dkZmc1SHdua1ZDcVlOM01DN1N5T016R0QwVGhVIn0...", "expires_in":60,"refresh_expires_in":1800,"refresh_token":"eyJhbGciOiJIUzUxMiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJiNTBlZTVkMS05OTc1LTQwMzUtYjNkNy1lMWQ5ZTJmMjg0MTEifQ.oBDx6B3pUkXQO8m-M3hYE7v-w25ak6y70CQd5J8f5EuldhvTwpWrC1K7yOglvs09dQxtq8ont12rKIoCIi4WXw","token_type":"Bearer","not-before-policy":0,"session_state":"5c9bce22-6b85-4654-b716-e9bbb3e755bc","scope":"profile email"}
-
Store the
access_token
from the previously step, as it will be exchanged for a Red Hat Quay robot account token in the following procedure.
5.8.2. Setting up a robot account federation by using the Red Hat Quay v2 UI
The following procedure shows you how to set up a robot account federation by using the Red Hat Quay v2 UI. This procedure uses Red Hat Single Sign-On, which is based on the Keycloak project. These steps, and the information used to set up a robot account federation, will vary depending on your OIDC provider.
Prerequisites
-
You have created an organization. The following example uses
fed_test
. -
You have created a robot account. The following example uses
fest_test+robot1
. - You have configured a OIDC for your Red Hat Quay deployment. The following example uses Red Hat Single Sign-On.
Procedure
On the Red Hat Single Sign-On main page:
-
Select the appropriate realm that is authenticated for use with Red Hat Quay. Store the issuer URL, for example,
https://keycloak-auth-realm.quayadmin.org/realms/quayrealm
. - Click Users → the name of the user to be linked with the robot account for authentication. You must use the same user account that you used when generating the OAuth2 access token.
On the Details page, store the ID of the user, for example,
449e14f8-9eb5-4d59-a63e-b7a77c75f770
.NoteThe information collected in this step will vary depending on your OIDC provider. For example, with Red Hat Single Sign-On, the ID of a user is used as the Subject to set up the robot account federation in a subsequent step. For a different OIDC provider, like Microsoft Entra ID, this information is stored as the Subject.
-
Select the appropriate realm that is authenticated for use with Red Hat Quay. Store the issuer URL, for example,
On your Red Hat Quay registry:
- Navigate to Organizations and click the name of your organization, for example, fed_test.
- Click Robot Accounts.
- Click the menu kebab → Set robot federation.
- Click the + symbol.
In the popup window, include the following information:
-
Issuer URL:
https://keycloak-auth-realm.quayadmin.org/realms/quayrealm
. For Red Hat Single Sign-On, this is the the URL of your Red Hat Single Sign-On realm. This might vary depending on your OIDC provider. -
Subject:
449e14f8-9eb5-4d59-a63e-b7a77c75f770
. For Red Hat Single Sign-On, the Subject is the ID of your Red Hat Single Sign-On user. This varies depending on your OIDC provider. For example, if you are using Microsoft Entra ID, the Subject will be the Subject or your Entra ID user.
-
Issuer URL:
- Click Save.
5.8.3. Exchanging an OAuth2 access token for a Red Hat Quay robot account token
The following procedure leverages the access token
generated in the previous procedure to create a new Red Hat Quay robot account token. The new Red Hat Quay robot account token is used for authentication between your OIDC provider and Red Hat Quay.
The following example uses a Python script to exchange the OAuth2 access token for a Red Hat Quay robot account token.
Prerequisites
-
You have the
python3
CLI tool installed.
Procedure
Save the following Python script in a
.py
file, for example,robot_fed_token_auth.py
import requests import os TOKEN=os.environ.get('TOKEN') robot_user = "fed-test+robot1" def get_quay_robot_token(fed_token): URL = "https://<quay-server.example.com>/oauth2/federation/robot/token" response = requests.get(URL, auth=(robot_user,fed_token)) 1 print(response) print(response.text) if __name__ == "__main__": get_quay_robot_token(TOKEN)
- 1
- If your Red Hat Quay deployment is using custom SSL/TLS certificates, the response must be
response = requests.get(URL,auth=(robot_user,fed_token),verify=False)
, which includes theverify=False
flag.
Export the OAuth2 access token as
TOKEN
. For example:$ export TOKEN = eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJTVmExVHZ6eDd2cHVmc1dkZmc1SHdua1ZDcVlOM01DN1N5T016R0QwVGhVIn0...
Run the
robot_fed_token_auth.py
script by entering the following command:$ python3 robot_fed_token_auth.py
Example output
<Response [200]> {"token": "291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6InByb2ZpbGUgZW1haWwiLCJlbWFpbF92ZXJpZ..."}
ImportantThis token expires after one hour. After one hour, a new token must be generated.
Export the robot account access token as
QUAY_TOKEN
. For example:$ export QUAY_TOKEN=291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6InByb2ZpbGUgZW1haWwiLCJlbWFpbF92ZXJpZ
5.8.4. Pushing and pulling images
After you have generated a new robot account access token and exported it, you can log in and the robot account using the access token and push and pull images.
Prerequisites
- You have exported the OAuth2 access token into a new robot account access token.
Procedure
Log in to your Red Hat Quay registry using the
fest_test+robot1
robot account and theQUAY_TOKEN
access token. For example:$ podman login <quay-server.example.com> -u fed_test+robot1 -p $QUAY_TOKEN
Pull an image from a Red Hat Quay repository for which the robot account has the proper permissions. For example:
$ podman pull <quay-server.example.com/<repository_name>/<image_name>>
Example output
Getting image source signatures Copying blob 900e6061671b done Copying config 8135583d97 done Writing manifest to image destination Storing signatures 8135583d97feb82398909c9c97607159e6db2c4ca2c885c0b8f590ee0f9fe90d 0.57user 0.11system 0:00.99elapsed 68%CPU (0avgtext+0avgdata 78716maxresident)k 800inputs+15424outputs (18major+6528minor)pagefaults 0swaps
Attempt to pull an image from a Red Hat Quay repository for which the robot account does not have the proper permissions. For example:
$ podman pull <quay-server.example.com/<different_repository_name>/<image_name>>
Example output
Error: initializing source docker://quay-server.example.com/example_repository/busybox:latest: reading manifest in quay-server.example.com/example_repository/busybox: unauthorized: access to the requested resource is not authorized
After one hour, the credentials for this robot account are set to expire. Afterwards, you must generate a new access token for this robot account.
Chapter 6. Access management for Red Hat Quay
As a Red Hat Quay user, you can create your own repositories and make them accessible to other users that are part of your instance. Alternatively, you can create an organization and associate a set of repositories directly to that organization, referred to as an organization repository.
Organization repositories differ from basic repositories in that the organization is intended to set up shared repositories through groups of users. In Red Hat Quay, groups of users can be either Teams, or sets of users with the same permissions, or individual users. You can also allow access to user repositories and organization repositories by creating credentials associated with Robot Accounts. Robot Accounts make it easy for a variety of container clients, such as Docker or Podman, to access your repositories without requiring that the client have a Red Hat Quay user account.
6.1. Red Hat Quay teams overview
In Red Hat Quay a team is a group of users with shared permissions, allowing for efficient management and collaboration on projects. Teams can help streamline access control and project management within organizations and repositories. They can be assigned designated permissions and help ensure that members have the appropriate level of access to their repositories based on their roles and responsibilities.
6.1.1. Creating a team by using the UI
When you create a team for your organization you can select the team name, choose which repositories to make available to the team, and decide the level of access to the team.
Use the following procedure to create a team for your organization repository.
Prerequisites
- You have created an organization.
Procedure
- On the Red Hat Quay v2 UI, click the name of an organization.
- On your organization’s page, click Teams and membership.
- Click the Create new team box.
- In the Create team popup window, provide a name for your new team.
- Optional. Provide a description for your new team.
- Click Proceed. A new popup window appears.
Optional. Add this team to a repository, and set the permissions to one of the following:
- None. Team members have no permission to the repository.
- Read. Team members can view and pull from the repository.
- Write. Team members can read (pull) from and write (push) to the repository.
- Admin. Full access to pull from, and push to, the repository, plus the ability to do administrative tasks associated with the repository.
- Optional. Add a team member or robot account. To add a team member, enter the name of their Red Hat Quay account.
- Review and finish the information, then click Review and Finish. The new team appears under the Teams and membership page.
6.1.2. Creating a team by using the API
When you create a team for your organization with the API you can select the team name, choose which repositories to make available to the team, and decide the level of access to the team.
Use the following procedure to create a team for your organization repository.
Prerequisites
- You have created an organization.
- You have Created an OAuth access token.
-
You have set
BROWSER_API_CALLS_XHR_ONLY: false
in yourconfig.yaml
file.
Procedure
Enter the following
PUT /api/v1/organization/{orgname}/team/{teamname}
command to create a team for your organization:$ curl -k -X PUT -H 'Accept: application/json' -H 'Content-Type: application/json' -H "Authorization: Bearer <bearer_token>" --data '{"role": "creator"}' https://<quay-server.example.com>/api/v1/organization/<organization_name>/team/<team_name>
Example output
{"name": "example_team", "description": "", "can_view": true, "role": "creator", "avatar": {"name": "example_team", "hash": "dec209fd7312a2284b689d4db3135e2846f27e0f40fa126776a0ce17366bc989", "color": "#e7ba52", "kind": "team"}, "new_team": true}
6.1.3. Managing a team by using the UI
After you have created a team, you can use the UI to manage team members, set repository permissions, delete the team, or view more general information about the team.
6.1.3.1. Adding users to a team by using the UI
With administrative privileges to an Organization, you can add users and robot accounts to a team. When you add a user, Red Hat Quay sends an email to that user. The user remains pending until they accept the invitation.
Use the following procedure to add users or robot accounts to a team.
Procedure
- On the Red Hat Quay landing page, click the name of your Organization.
- In the navigation pane, click Teams and Membership.
- Select the menu kebab of the team that you want to add users or robot accounts to. Then, click Manage team members.
- Click Add new member.
In the textbox, enter information for one of the following:
- A username from an account on the registry.
- The email address for a user account on the registry.
The name of a robot account. The name must be in the form of <organization_name>+<robot_name>.
NoteRobot Accounts are immediately added to the team. For user accounts, an invitation to join is mailed to the user. Until the user accepts that invitation, the user remains in the INVITED TO JOIN state. After the user accepts the email invitation to join the team, they move from the INVITED TO JOIN list to the MEMBERS list for the Organization.
- Click Add member.
6.1.3.2. Setting a team role by using the UI
After you have created a team, you can set the role of that team within the Organization.
Prerequisites
- You have created a team.
Procedure
- On the Red Hat Quay landing page, click the name of your Organization.
- In the navigation pane, click Teams and Membership.
Select the TEAM ROLE drop-down menu, as shown in the following figure:
For the selected team, choose one of the following roles:
- Admin. Full administrative access to the organization, including the ability to create teams, add members, and set permissions.
- Member. Inherits all permissions set for the team.
- Creator. All member permissions, plus the ability to create new repositories.
6.1.3.2.1. Managing team members and repository permissions
Use the following procedure to manage team members and set repository permissions.
On the Teams and membership page of your organization, you can also manage team members and set repository permissions.
- Click the kebab menu, and select one of the following options:
- Manage Team Members. On this page, you can view all members, team members, robot accounts, or users who have been invited. You can also add a new team member by clicking Add new member.
Set repository permissions. On this page, you can set the repository permissions to one of the following:
- None. Team members have no permission to the repository.
- Read. Team members can view and pull from the repository.
- Write. Team members can read (pull) from and write (push) to the repository.
- Admin. Full access to pull from, and push to, the repository, plus the ability to do administrative tasks associated with the repository.
- Delete. This popup windows allows you to delete the team by clicking Delete.
6.1.3.2.2. Viewing additional information about a team
Use the following procedure to view general information about the team.
Procedure
On the Teams and membership page of your organization, you can click the one of the following options to reveal more information about teams, members, and collaborators:
- Team View. This menu shows all team names, the number of members, the number of repositories, and the role for each team.
- Members View. This menu shows all usernames of team members, the teams that they are part of, the repository permissions of the user.
- Collaborators View. This menu shows repository collaborators. Collaborators are users that do not belong to any team in the organization, but who have direct permissions on one or more repositories belonging to the organization.
6.1.4. Managing a team by using the Red Hat Quay API
After you have created a team, you can use the API to obtain information about team permissions or team members, add, update, or delete team members (including by email), or delete an organization team.
The following procedures show you how to how to manage a team using the Red Hat Quay API.
6.1.4.1. Managing team members and repository permissions by using the API
Use the following procedures to add a member to a team (by direct invite or by email), or to remove a member from a team.
Prerequisites
- You have Created an OAuth access token.
-
You have set
BROWSER_API_CALLS_XHR_ONLY: false
in yourconfig.yaml
file.
Procedure
Enter the
PUT /api/v1/organization/{orgname}/team/{teamname}/members/{membername}
command to add or invite a member to an existing team:$ curl -X PUT \ -H "Authorization: Bearer <your_access_token>" \ "<quay-server.example.com>/api/v1/organization/<organization_name>/team/<team_name>/members/<member_name>"
Example output
{"name": "testuser", "kind": "user", "is_robot": false, "avatar": {"name": "testuser", "hash": "d51d17303dc3271ac3266fb332d7df919bab882bbfc7199d2017a4daac8979f0", "color": "#5254a3", "kind": "user"}, "invited": false}
Enter the
DELETE /api/v1/organization/{orgname}/team/{teamname}/members/{membername}
command to remove a member of a team:$ curl -X DELETE \ -H "Authorization: Bearer <your_access_token>" \ "<quay-server.example.com>/api/v1/organization/<organization_name>/team/<team_name>/members/<member_name>"
This command does not an output in the CLI. To ensure that a member has been deleted, you can enter the
GET /api/v1/organization/{orgname}/team/{teamname}/members
command and ensure that the member is not returned in the output.$ curl -X GET \ -H "Authorization: Bearer <your_access_token>" \ "<quay-server.example.com>/api/v1/organization/<organization_name>/team/<team_name>/members"
Example output
{"name": "owners", "members": [{"name": "quayadmin", "kind": "user", "is_robot": false, "avatar": {"name": "quayadmin", "hash": "b28d563a6dc76b4431fc7b0524bbff6b810387dac86d9303874871839859c7cc", "color": "#17becf", "kind": "user"}, "invited": false}, {"name": "test-org+test", "kind": "user", "is_robot": true, "avatar": {"name": "test-org+test", "hash": "aa85264436fe9839e7160bf349100a9b71403a5e9ec684d5b5e9571f6c821370", "color": "#8c564b", "kind": "robot"}, "invited": false}], "can_edit": true}
You can enter the
PUT /api/v1/organization/{orgname}/team/{teamname}/invite/{email}
command to invite a user, by email address, to an existing team:$ curl -X PUT \ -H "Authorization: Bearer <your_access_token>" \ "<quay-server.example.com>/api/v1/organization/<organization_name>/team/<team_name>/invite/<email>"
You can enter the
DELETE /api/v1/organization/{orgname}/team/{teamname}/invite/{email}
command to delete the invite of an email address to join a team. For example:$ curl -X DELETE \ -H "Authorization: Bearer <your_access_token>" \ "<quay-server.example.com>/api/v1/organization/<organization_name>/team/<team_name>/invite/<email>"
6.1.4.2. Setting the role of a team within an organization by using the API
Use the following procedure to view and set the role a team within an organization using the API.
Prerequisites
- You have Created an OAuth access token.
-
You have set
BROWSER_API_CALLS_XHR_ONLY: false
in yourconfig.yaml
file.
Procedure
Enter the following
GET /api/v1/organization/{orgname}/team/{teamname}/permissions
command to return a list of repository permissions for the organization’s team. Note that your team must have been added to a repository for this command to return information.$ curl -X GET \ -H "Authorization: Bearer <your_access_token>" \ "<quay-server.example.com>/api/v1/organization/<organization_name>/team/<team_name>/permissions"
Example output
{"permissions": [{"repository": {"name": "api-repo", "is_public": true}, "role": "admin"}]}
You can create or update a team within an organization to have a specified role of admin, member, or creator using the
PUT /api/v1/organization/{orgname}/team/{teamname}
command. For example:$ curl -X PUT \ -H "Authorization: Bearer <your_access_token>" \ -H "Content-Type: application/json" \ -d '{ "role": "<role>" }' \ "<quay-server.example.com>/api/v1/organization/<organization_name>/team/<team_name>"
Example output
{"name": "testteam", "description": "", "can_view": true, "role": "creator", "avatar": {"name": "testteam", "hash": "827f8c5762148d7e85402495b126e0a18b9b168170416ed04b49aae551099dc8", "color": "#ff7f0e", "kind": "team"}, "new_team": false}
6.1.4.3. Deleting a team within an organization by using the API
Use the following procedure to delete a team within an organization by using the API.
Prerequisites
- You have Created an OAuth access token.
-
You have set
BROWSER_API_CALLS_XHR_ONLY: false
in yourconfig.yaml
file.
Procedure
You can delete a team within an organization by entering the
DELETE /api/v1/organization/{orgname}/team/{teamname}
command:$ curl -X DELETE \ -H "Authorization: Bearer <your_access_token>" \ "<quay-server.example.com>/api/v1/organization/<organization_name>/team/<team_name>"
This command does not return output in the CLI.
6.2. Creating and managing default permissions by using the UI
Default permissions define permissions that should be granted automatically to a repository when it is created, in addition to the default of the repository’s creator. Permissions are assigned based on the user who created the repository.
Use the following procedure to create default permissions using the Red Hat Quay v2 UI.
Procedure
- Click the name of an organization.
- Click Default permissions.
- Click Create default permissions. A toggle drawer appears.
Select either Anyone or Specific user to create a default permission when a repository is created.
If selecting Anyone, the following information must be provided:
- Applied to. Search, invite, or add a user/robot/team.
- Permission. Set the permission to one of Read, Write, or Admin.
If selecting Specific user, the following information must be provided:
- Repository creator. Provide either a user or robot account.
- Applied to. Provide a username, robot account, or team name.
- Permission. Set the permission to one of Read, Write, or Admin.
- Click Create default permission. A confirmation box appears, returning the following alert: Successfully created default permission for creator.
6.3. Creating and managing default permissions by using the API
Use the following procedures to manage default permissions using the Red Hat Quay API.
Prerequisites
- You have Created an OAuth access token.
-
You have set
BROWSER_API_CALLS_XHR_ONLY: false
in yourconfig.yaml
file.
Procedure
Enter the following command to create a default permission with the
POST /api/v1/organization/{orgname}/prototypes
endpoint:$ curl -X POST -H "Authorization: Bearer <bearer_token>" -H "Content-Type: application/json" --data '{ "role": "<admin_read_or_write>", "delegate": { "name": "<username>", "kind": "user" }, "activating_user": { "name": "<robot_name>" } }' https://<quay-server.example.com>/api/v1/organization/<organization_name>/prototypes
Example output
{"activating_user": {"name": "test-org+test", "is_robot": true, "kind": "user", "is_org_member": true, "avatar": {"name": "test-org+test", "hash": "aa85264436fe9839e7160bf349100a9b71403a5e9ec684d5b5e9571f6c821370", "color": "#8c564b", "kind": "robot"}}, "delegate": {"name": "testuser", "is_robot": false, "kind": "user", "is_org_member": false, "avatar": {"name": "testuser", "hash": "f660ab912ec121d1b1e928a0bb4bc61b15f5ad44d5efdc4e1c92a25e99b8e44a", "color": "#6b6ecf", "kind": "user"}}, "role": "admin", "id": "977dc2bc-bc75-411d-82b3-604e5b79a493"}
Enter the following command to update a default permission using the
PUT /api/v1/organization/{orgname}/prototypes/{prototypeid}
endpoint, for example, if you want to change the permission type. You must include the ID that was returned when you created the policy.$ curl -X PUT \ -H "Authorization: Bearer <bearer_token>" \ -H "Content-Type: application/json" \ --data '{ "role": "write" }' \ https://<quay-server.example.com>/api/v1/organization/<organization_name>/prototypes/<prototypeid>
Example output
{"activating_user": {"name": "test-org+test", "is_robot": true, "kind": "user", "is_org_member": true, "avatar": {"name": "test-org+test", "hash": "aa85264436fe9839e7160bf349100a9b71403a5e9ec684d5b5e9571f6c821370", "color": "#8c564b", "kind": "robot"}}, "delegate": {"name": "testuser", "is_robot": false, "kind": "user", "is_org_member": false, "avatar": {"name": "testuser", "hash": "f660ab912ec121d1b1e928a0bb4bc61b15f5ad44d5efdc4e1c92a25e99b8e44a", "color": "#6b6ecf", "kind": "user"}}, "role": "write", "id": "977dc2bc-bc75-411d-82b3-604e5b79a493"}
You can delete the permission by entering the
DELETE /api/v1/organization/{orgname}/prototypes/{prototypeid}
command:curl -X DELETE \ -H "Authorization: Bearer <bearer_token>" \ -H "Accept: application/json" \ https://<quay-server.example.com>/api/v1/organization/<organization_name>/prototypes/<prototype_id>
This command does not return an output. Instead, you can obtain a list of all permissions by entering the
GET /api/v1/organization/{orgname}/prototypes
command:$ curl -X GET \ -H "Authorization: Bearer <bearer_token>" \ -H "Accept: application/json" \ https://<quay-server.example.com>/api/v1/organization/<organization_name>/prototypes
Example output
{"prototypes": []}
6.4. Adjusting access settings for a repository by using the UI
Use the following procedure to adjust access settings for a user or robot account for a repository using the v2 UI.
Prerequisites
- You have created a user account or robot account.
Procedure
- Log into Red Hat Quay.
- On the v2 UI, click Repositories.
-
Click the name of a repository, for example,
quayadmin/busybox
. - Click the Settings tab.
Optional. Click User and robot permissions. You can adjust the settings for a user or robot account by clicking the dropdown menu option under Permissions. You can change the settings to Read, Write, or Admin.
- Read. The User or Robot Account can view and pull from the repository.
- Write. The User or Robot Account can read (pull) from and write (push) to the repository.
- Admin. The User or Robot account has access to pull from, and push to, the repository, plus the ability to do administrative tasks associated with the repository.
6.5. Adjusting access settings for a repository by using the API
Use the following procedure to adjust access settings for a user or robot account for a repository by using the API.
Prerequisites
- You have created a user account or robot account.
- You have Created an OAuth access token.
-
You have set
BROWSER_API_CALLS_XHR_ONLY: false
in yourconfig.yaml
file.
Procedure
Enter the following
PUT /api/v1/repository/{repository}/permissions/user/{username}
command to change the permissions of a user:$ curl -X PUT \ -H "Authorization: Bearer <bearer_token>" \ -H "Content-Type: application/json" \ -d '{"role": "admin"}' \ https://<quay-server.example.com>/api/v1/repository/<namespace>/<repository>/permissions/user/<username>
Example output
{"role": "admin", "name": "quayadmin+test", "is_robot": true, "avatar": {"name": "quayadmin+test", "hash": "ca9afae0a9d3ca322fc8a7a866e8476dd6c98de543decd186ae090e420a88feb", "color": "#8c564b", "kind": "robot"}}
To delete the current permission, you can enter the
DELETE /api/v1/repository/{repository}/permissions/user/{username}
command:$ curl -X DELETE \ -H "Authorization: Bearer <bearer_token>" \ -H "Accept: application/json" \ https://<quay-server.example.com>/api/v1/repository/<namespace>/<repository>/permissions/user/<username>
This command does not return any output in the CLI. Instead, you can check that the permissions were deleted by entering the
GET /api/v1/repository/{repository}/permissions/user/
command:$ curl -X GET \ -H "Authorization: Bearer <bearer_token>" \ -H "Accept: application/json" \ https://<quay-server.example.com>/api/v1/repository/<namespace>/<repository>/permissions/user/<username>/
Example output
{"message":"User does not have permission for repo."}
Chapter 7. Image tags overview
An image tag refers to a label or identifier assigned to a specific version or variant of a container image. Container images are typically composed of multiple layers that represent different parts of the image. Image tags are used to differentiate between different versions of an image or to provide additional information about the image.
Image tags have the following benefits:
- Versioning and Releases: Image tags allow you to denote different versions or releases of an application or software. For example, you might have an image tagged as v1.0 to represent the initial release and v1.1 for an updated version. This helps in maintaining a clear record of image versions.
- Rollbacks and Testing: If you encounter issues with a new image version, you can easily revert to a previous version by specifying its tag. This is helpful during debugging and testing phases.
- Development Environments: Image tags are beneficial when working with different environments. You might use a dev tag for a development version, qa for quality assurance testing, and prod for production, each with their respective features and configurations.
- Continuous Integration/Continuous Deployment (CI/CD): CI/CD pipelines often utilize image tags to automate the deployment process. New code changes can trigger the creation of a new image with a specific tag, enabling seamless updates.
- Feature Branches: When multiple developers are working on different features or bug fixes, they can create distinct image tags for their changes. This helps in isolating and testing individual features.
- Customization: You can use image tags to customize images with different configurations, dependencies, or optimizations, while keeping track of each variant.
- Security and Patching: When security vulnerabilities are discovered, you can create patched versions of images with updated tags, ensuring that your systems are using the latest secure versions.
- Dockerfile Changes: If you modify the Dockerfile or build process, you can use image tags to differentiate between images built from the previous and updated Dockerfiles.
Overall, image tags provide a structured way to manage and organize container images, enabling efficient development, deployment, and maintenance workflows.
7.1. Viewing image tag information by using the UI
Use the following procedure to view image tag information using the v2 UI.
Prerequisites
- You have pushed an image tag to a repository.
Procedure
- On the v2 UI, click Repositories.
- Click the name of a repository.
Click the name of a tag. You are taken to the Details page of that tag. The page reveals the following information:
- Name
- Repository
- Digest
- Vulnerabilities
- Creation
- Modified
- Size
- Labels
- How to fetch the image tag
- Click Security Report to view the tag’s vulnerabilities. You can expand an advisory column to open up CVE data.
- Click Packages to view the tag’s packages.
- Click the name of the repository to return to the Tags page.
7.2. Viewing image tag information by using the API
Use the following procedure to view image tag information by using the API
Prerequisites
- You have pushed an image tag to a Red Hat Quay repository.
- You have Created an OAuth access token.
-
You have set
BROWSER_API_CALLS_XHR_ONLY: false
in yourconfig.yaml
file.
Procedure
To obtain tag information, you must use the
GET /api/v1/repository/{repository}
API endpoint and pass in theincludeTags
parameter. For example:$ curl -X GET \ -H "Authorization: Bearer <bearer_token>" \ -H "Accept: application/json" \ https://<quay-server.example.com>/api/v1/repository/<namespace>/<repository_name>?includeTags=true
Example output
{"namespace": "quayadmin", "name": "busybox", "kind": "image", "description": null, "is_public": false, "is_organization": false, "is_starred": false, "status_token": "d8f5e074-690a-46d7-83c8-8d4e3d3d0715", "trust_enabled": false, "tag_expiration_s": 1209600, "is_free_account": true, "state": "NORMAL", "tags": {"example": {"name": "example", "size": 2275314, "last_modified": "Tue, 14 May 2024 14:48:51 -0000", "manifest_digest": "sha256:57583a1b9c0a7509d3417387b4f43acf80d08cdcf5266ac87987be3f8f919d5d"}, "test": {"name": "test", "size": 2275314, "last_modified": "Tue, 14 May 2024 14:04:48 -0000", "manifest_digest": "sha256:57583a1b9c0a7509d3417387b4f43acf80d08cdcf5266ac87987be3f8f919d5d"}}, "can_write": true, "can_admin": true}
Alternatively, you can use the
GET /api/v1/repository/{repository}/tag/
endpoint. For example:$ curl -X GET \ -H "Authorization: Bearer <bearer_token>" \ -H "Accept: application/json" \ https://<quay-server.example.com>/api/v1/repository/<namespace>/<repository_name>/tag/
Example output
{"tags": [{"name": "test-two", "reversion": true, "start_ts": 1718737153, "manifest_digest": "sha256:57583a1b9c0a7509d3417387b4f43acf80d08cdcf5266ac87987be3f8f919d5d", "is_manifest_list": false, "size": 2275314, "last_modified": "Tue, 18 Jun 2024 18:59:13 -0000"}, {"name": "test-two", "reversion": false, "start_ts": 1718737029, "end_ts": 1718737153, "manifest_digest": "sha256:0cd3dd6236e246b349e63f76ce5f150e7cd5dbf2f2f1f88dbd734430418dbaea", "is_manifest_list": false, "size": 2275317, "last_modified": "Tue, 18 Jun 2024 18:57:09 -0000", "expiration": "Tue, 18 Jun 2024 18:59:13 -0000"}, {"name": "test-two", "reversion": false, "start_ts": 1718737018, "end_ts": 1718737029, "manifest_digest": "sha256:0cd3dd6236e246b349e63f76ce5f150e7cd5dbf2f2f1f88dbd734430418dbaea", "is_manifest_list": false, "size": 2275317, "last_modified": "Tue, 18 Jun 2024 18:56:58 -0000", "expiration": "Tue, 18 Jun 2024 18:57:09 -0000"}, {"name": "sample_tag", "reversion": false, "start_ts": 1718736147, "manifest_digest": "sha256:57583a1b9c0a7509d3417387b4f43acf80d08cdcf5266ac87987be3f8f919d5d", "is_manifest_list": false, "size": 2275314, "last_modified": "Tue, 18 Jun 2024 18:42:27 -0000"}, {"name": "test-two", "reversion": false, "start_ts": 1717680780, "end_ts": 1718737018, "manifest_digest": "sha256:57583a1b9c0a7509d3417387b4f43acf80d08cdcf5266ac87987be3f8f919d5d", "is_manifest_list": false, "size": 2275314, "last_modified": "Thu, 06 Jun 2024 13:33:00 -0000", "expiration": "Tue, 18 Jun 2024 18:56:58 -0000"}, {"name": "tag-test", "reversion": false, "start_ts": 1717680378, "manifest_digest": "sha256:57583a1b9c0a7509d3417387b4f43acf80d08cdcf5266ac87987be3f8f919d5d", "is_manifest_list": false, "size": 2275314, "last_modified": "Thu, 06 Jun 2024 13:26:18 -0000"}, {"name": "example", "reversion": false, "start_ts": 1715698131, "manifest_digest": "sha256:57583a1b9c0a7509d3417387b4f43acf80d08cdcf5266ac87987be3f8f919d5d", "is_manifest_list": false, "size": 2275314, "last_modified": "Tue, 14 May 2024 14:48:51 -0000"}], "page": 1, "has_additional": false}
7.3. Adding a new image tag to an image by using the UI
You can add a new tag to an image in Red Hat Quay.
Procedure
- On the Red Hat Quay v2 UI dashboard, click Repositories in the navigation pane.
- Click the name of a repository that has image tags.
- Click the menu kebab, then click Add new tag.
Enter a name for the tag, then, click Create tag.
The new tag is now listed on the Repository Tags page.
7.4. Adding a new tag to an image tag to an image by using the API
You can add a new tag, or restore an old one, to an image by using the API.
Prerequisites
- You have Created an OAuth access token.
-
You have set
BROWSER_API_CALLS_XHR_ONLY: false
in yourconfig.yaml
file.
Procedure
You can change which image a tag points to or create a new tag by using the
PUT /api/v1/repository/{repository}/tag/{tag}
command:$ curl -X PUT \ -H "Authorization: Bearer <bearer_token>" \ -H "Content-Type: application/json" \ --data '{ "manifest_digest": "<manifest_digest>" }' \ https://<quay-server.example.com>/api/v1/repository/<namespace>/<repository_name>/tag/<tag>
Example output
"Updated"
You can restore a repository tag to its previous image by using the
POST /api/v1/repository/{repository}/tag/{tag}/restore
command. For example:$ curl -X POST \ -H "Authorization: Bearer <bearer_token>" \ -H "Content-Type: application/json" \ --data '{ "manifest_digest": <manifest_digest> }' \ quay-server.example.com/api/v1/repository/quayadmin/busybox/tag/test/restore
Example output
{}
To see a list of tags after creating a new tag you can use the
GET /api/v1/repository/{repository}/tag/
command. For example:$ curl -X GET \ -H "Authorization: Bearer <bearer_token>" \ -H "Accept: application/json" \ https://<quay-server.example.com>/api/v1/repository/<namespace>/<repository_name>/tag
Example output
{"tags": [{"name": "test", "reversion": false, "start_ts": 1716324069, "manifest_digest": "sha256:57583a1b9c0a7509d3417387b4f43acf80d08cdcf5266ac87987be3f8f919d5d", "is_manifest_list": false, "size": 2275314, "last_modified": "Tue, 21 May 2024 20:41:09 -0000"}, {"name": "example", "reversion": false, "start_ts": 1715698131, "manifest_digest": "sha256:57583a1b9c0a7509d3417387b4f43acf80d08cdcf5266ac87987be3f8f919d5d", "is_manifest_list": false, "size": 2275314, "last_modified": "Tue, 14 May 2024 14:48:51 -0000"}, {"name": "example", "reversion": false, "start_ts": 1715697708, "end_ts": 1715698131, "manifest_digest": "sha256:57583a1b9c0a7509d3417387b4f43acf80d08cdcf5266ac87987be3f8f919d5d", "is_manifest_list": false, "size": 2275314, "last_modified": "Tue, 14 May 2024 14:41:48 -0000", "expiration": "Tue, 14 May 2024 14:48:51 -0000"}, {"name": "test", "reversion": false, "start_ts": 1715695488, "end_ts": 1716324069, "manifest_digest": "sha256:57583a1b9c0a7509d3417387b4f43acf80d08cdcf5266ac87987be3f8f919d5d", "is_manifest_list": false, "size": 2275314, "last_modified": "Tue, 14 May 2024 14:04:48 -0000", "expiration": "Tue, 21 May 2024 20:41:09 -0000"}, {"name": "test", "reversion": false, "start_ts": 1715631517, "end_ts": 1715695488, "manifest_digest": "sha256:57583a1b9c0a7509d3417387b4f43acf80d08cdcf5266ac87987be3f8f919d5d", "is_manifest_list": false, "size": 2275314, "last_modified": "Mon, 13 May 2024 20:18:37 -0000", "expiration": "Tue, 14 May 2024 14:04:48 -0000"}], "page": 1, "has_additional": false}
7.5. Adding and managing labels by using the UI
Administrators can add and manage labels for tags by using the following procedure.
Procedure
- On the v2 UI dashboard, click Repositories in the navigation pane.
- Click the name of a repository that has image tags.
- Click the menu kebab for an image and select Edit labels.
- In the Edit labels window, click Add new label.
Enter a label for the image tag using the
key=value
format, for example,com.example.release-date=2023-11-14
.NoteThe following error is returned when failing to use the
key=value
format:Invalid label format, must be key value separated by =
.- Click the whitespace of the box to add the label.
- Optional. Add a second label.
-
Click Save labels to save the label to the image tag. The following notification is returned:
Created labels successfully
. - Optional. Click the same image tag’s menu kebab → Edit labels → X on the label to remove it; alternatively, you can edit the text. Click Save labels. The label is now removed or edited.
7.6. Adding and managing labels by using the API
Red Hat Quay administrators can add and manage labels for tags with the API by using the following procedure.
Prerequisites
- You have Created an OAuth access token.
-
You have set
BROWSER_API_CALLS_XHR_ONLY: false
in yourconfig.yaml
file.
Procedure
Use the
GET /api/v1/repository/{repository}/manifest/{manifestref}
command to retrieve the details of a specific manifest in a repository:$ curl -X GET \ -H "Authorization: Bearer <bearer_token>" \ -H "Accept: application/json" \ https://<quay-server.example.com>/api/v1/repository/<repository>/manifest/<manifestref>
Use the
GET /api/v1/repository/{repository}/manifest/{manifestref}/labels
command to retrieve a list of labels for a specific manifest:$ curl -X GET \ -H "Authorization: Bearer <bearer_token>" \ -H "Accept: application/json" \ https://<quay-server.example.com>/api/v1/repository/<repository>/manifest/<manifestref>/labels
Example output
{"labels": [{"id": "e9f717d2-c1dd-4626-802d-733a029d17ad", "key": "org.opencontainers.image.url", "value": "https://github.com/docker-library/busybox", "source_type": "manifest", "media_type": "text/plain"}, {"id": "2d34ec64-4051-43ad-ae06-d5f81003576a", "key": "org.opencontainers.image.version", "value": "1.36.1-glibc", "source_type": "manifest", "media_type": "text/plain"}]}
Use the
GET /api/v1/repository/{repository}/manifest/{manifestref}/labels/{labelid}
command to obtain information about a specific manifest:$ curl -X GET \ -H "Authorization: Bearer <bearer_token>" \ -H "Accept: application/json" \ https://<quay-server.example.com>/api/v1/repository/<repository>/manifest/<manifestref>/labels/<label_id>
Example output
{"id": "e9f717d2-c1dd-4626-802d-733a029d17ad", "key": "org.opencontainers.image.url", "value": "https://github.com/docker-library/busybox", "source_type": "manifest", "media_type": "text/plain"}
You can add an additional label to a manifest in a given repository with the
POST /api/v1/repository/{repository}/manifest/{manifestref}/labels
command. For example:$ curl -X POST \ -H "Authorization: Bearer <bearer_token>" \ -H "Content-Type: application/json" \ --data '{ "key": "<key>", "value": "<value>", "media_type": "<media_type>" }' \ https://<quay-server.example.com>/api/v1/repository/<repository>/manifest/<manifestref>/labels
Example output
{"label": {"id": "346593fd-18c8-49db-854f-4cb1fb76ff9c", "key": "example-key", "value": "example-value", "source_type": "api", "media_type": "text/plain"}}
You can delete a label using the
DELETE /api/v1/repository/{repository}/manifest/{manifestref}/labels/{labelid}
command:$ curl -X DELETE \ -H "Authorization: Bearer <bearer_token>" \ https://<quay-server.example.com>/api/v1/repository/<repository>/manifest/<manifestref>/labels/<labelid>
This command does not return output in the CLI. You can use one of the commands above to ensure that it was successfully removed.
7.7. Setting tag expirations
Image tags can be set to expire from a Red Hat Quay repository at a chosen date and time using the tag expiration feature. This feature includes the following characteristics:
- When an image tag expires, it is deleted from the repository. If it is the last tag for a specific image, the image is also set to be deleted.
- Expiration is set on a per-tag basis. It is not set for a repository as a whole.
- After a tag is expired or deleted, it is not immediately removed from the registry. This is contingent upon the allotted time designed in the time machine feature, which defines when the tag is permanently deleted, or garbage collected. By default, this value is set at 14 days, however the administrator can adjust this time to one of multiple options. Up until the point that garbage collection occurs, tags changes can be reverted.
The Red Hat Quay superuser has no special privilege related to deleting expired images from user repositories. There is no central mechanism for the superuser to gather information and act on user repositories. It is up to the owners of each repository to manage expiration and the deletion of their images.
Tag expiration can be set up in one of two ways:
-
By setting the
quay.expires-after=
label in the Dockerfile when the image is created. This sets a time to expire from when the image is built. By selecting an expiration date on the Red Hat Quay UI. For example:
Setting tag expirations can help automate the cleanup of older or unused tags, helping to reduce storage space.
7.7.1. Setting tag expiration from a repository
Procedure
- On the Red Hat Quay v2 UI dashboard, click Repositories in the navigation pane.
- Click the name of a repository that has image tags.
- Click the menu kebab for an image and select Change expiration.
- Optional. Alternatively, you can bulk add expiration dates by clicking the box of multiple tags, and then select Actions → Set expiration.
-
In the Change Tags Expiration window, set an expiration date, specifying the day of the week, month, day of the month, and year. For example,
Wednesday, November 15, 2023
. Alternatively, you can click the calendar button and manually select the date. -
Set the time, for example,
2:30 PM
. -
Click Change Expiration to confirm the date and time. The following notification is returned:
Successfully set expiration for tag test to Nov 15, 2023, 2:26 PM
. On the Red Hat Quay v2 UI Tags page, you can see when the tag is set to expire. For example:
7.7.2. Setting tag expiration from a Dockerfile
You can add a label, for example, quay.expires-after=20h
to an image tag by using the docker label
command to cause the tag to automatically expire after the time that is indicated. The following values for hours, days, or weeks are accepted:
-
1h
-
2d
-
3w
Expiration begins from the time that the image is pushed to the registry.
Procedure
Enter the following
docker label
command to add a label to the desired image tag. The label should be in the formatquay.expires-after=20h
to indicate that the tag should expire after 20 hours. Replace 20h with the desired expiration time. For example:$ docker label quay.expires-after=20h quay-server.example.com/quayadmin/<image>:<tag>
7.7.3. Setting tag expirations by using the API
Image tags can be set to expire by using the API.
Prerequisites
- You have Created an OAuth access token.
-
You have set
BROWSER_API_CALLS_XHR_ONLY: false
in yourconfig.yaml
file.
Procedure
You can set when an image a tag expires by using the
PUT /api/v1/repository/{repository}/tag/{tag}
command and passing in the expiration field:$ curl -X PUT \ -H "Authorization: Bearer <bearer_token>" \ -H "Content-Type: application/json" \ --data '{ "manifest_digest": "<manifest_digest>" }' \ https://<quay-server.example.com>/api/v1/repository/<namespace>/<repository_name>/tag/<tag>
Example output
"Updated"
7.8. Fetching an image by tag or digest
Red Hat Quay offers multiple ways of pulling images using Docker and Podman clients.
Procedure
- Navigate to the Tags page of a repository.
- Under Manifest, click the Fetch Tag icon.
When the popup box appears, users are presented with the following options:
- Podman Pull (by tag)
- Docker Pull (by tag)
- Podman Pull (by digest)
Docker Pull (by digest)
Selecting any one of the four options returns a command for the respective client that allows users to pull the image.
Click Copy Command to copy the command, which can be used on the command-line interface (CLI). For example:
$ podman pull quay-server.example.com/quayadmin/busybox:test2
7.9. Viewing Red Hat Quay tag history by using the UI
Red Hat Quay offers a comprehensive history of images and their respective image tags.
Procedure
- On the Red Hat Quay v2 UI dashboard, click Repositories in the navigation pane.
- Click the name of a repository that has image tags.
Click Tag History. On this page, you can perform the following actions:
- Search by tag name
- Select a date range
- View tag changes
- View tag modification dates and the time at which they were changed
7.10. Viewing Red Hat Quay tag history by using the API
Red Hat Quay offers a comprehensive history of images and their respective image tags.
Prerequisites
- You have Created an OAuth access token.
-
You have set
BROWSER_API_CALLS_XHR_ONLY: false
in yourconfig.yaml
file.
Procedure
Enter the following command to view tag history by using the
GET /api/v1/repository/{repository}/tag/
command and passing in one of the following queries:- onlyActiveTags=<true/false>: Filters to only include active tags.
- page=<number>: Specifies the page number of results to retrieve.
- limit=<number>: Limits the number of results per page.
specificTag=<tag_name>: Filters the tags to include only the tag with the specified name.
$ curl -X GET \ -H "Authorization: Bearer <bearer_token>" \ -H "Accept: application/json" \ "https://<quay-server.example.com>/api/v1/repository/<namespace>/<repository>/tag/?onlyActiveTags=true&page=1&limit=10"
Example output
{"tags": [{"name": "test-two", "reversion": false, "start_ts": 1717680780, "manifest_digest": "sha256:57583a1b9c0a7509d3417387b4f43acf80d08cdcf5266ac87987be3f8f919d5d", "is_manifest_list": false, "size": 2275314, "last_modified": "Thu, 06 Jun 2024 13:33:00 -0000"}, {"name": "tag-test", "reversion": false, "start_ts": 1717680378, "manifest_digest": "sha256:57583a1b9c0a7509d3417387b4f43acf80d08cdcf5266ac87987be3f8f919d5d", "is_manifest_list": false, "size": 2275314, "last_modified": "Thu, 06 Jun 2024 13:26:18 -0000"}, {"name": "example", "reversion": false, "start_ts": 1715698131, "manifest_digest": "sha256:57583a1b9c0a7509d3417387b4f43acf80d08cdcf5266ac87987be3f8f919d5d", "is_manifest_list": false, "size": 2275314, "last_modified": "Tue, 14 May 2024 14:48:51 -0000"}], "page": 1, "has_additional": false}
By using the
specificTag=<tag_name>
query, you can filter results for a specific tag. For example:$ curl -X GET -H "Authorization: Bearer <bearer_token>" -H "Accept: application/json" "<quay-server.example.com>/api/v1/repository/quayadmin/busybox/tag/?onlyActiveTags=true&page=1&limit=20&specificTag=test-two"
Example output
{"tags": [{"name": "test-two", "reversion": true, "start_ts": 1718737153, "manifest_digest": "sha256:57583a1b9c0a7509d3417387b4f43acf80d08cdcf5266ac87987be3f8f919d5d", "is_manifest_list": false, "size": 2275314, "last_modified": "Tue, 18 Jun 2024 18:59:13 -0000"}], "page": 1, "has_additional": false}
7.11. Deleting an image tag
Deleting an image tag removes that specific version of the image from the registry.
To delete an image tag, use the following procedure.
Procedure
-
On the Repositories page of the v2 UI, click the name of the image you want to delete, for example,
quay/admin/busybox
. - Click the More Actions drop-down menu.
Click Delete.
NoteIf desired, you could click Make Public or Make Private.
- Type confirm in the box, and then click Delete.
After deletion, you are returned to the Repositories page.
NoteDeleting an image tag can be reverted based on the amount of time allotted assigned to the time machine feature. For more information, see "Reverting tag changes".
7.12. Deleting an image by using the API
You can delete an old image tag by using the API.
Prerequisites
- You have Created an OAuth access token.
-
You have set
BROWSER_API_CALLS_XHR_ONLY: false
in yourconfig.yaml
file.
Procedure
You can delete an image tag by using the
DELETE /api/v1/repository/{repository}/tag/{tag}
command:$ curl -X DELETE \ -H "Authorization: Bearer <bearer_token>" \ https://<quay-server.example.com>/api/v1/repository/<namespace>/<repository_name>/tag/<tag>
This command does not return output in the CLI. Continue on to the next step to return a list of tags.
To see a list of tags after deleting a tag, you can use the
GET /api/v1/repository/{repository}/tag/
command. For example:$ curl -X GET \ -H "Authorization: Bearer <bearer_token>" \ -H "Accept: application/json" \ https://<quay-server.example.com>/api/v1/repository/<namespace>/<repository_name>/tag
Example output
{"tags": [{"name": "test", "reversion": false, "start_ts": 1716324069, "manifest_digest": "sha256:57583a1b9c0a7509d3417387b4f43acf80d08cdcf5266ac87987be3f8f919d5d", "is_manifest_list": false, "size": 2275314, "last_modified": "Tue, 21 May 2024 20:41:09 -0000"}, {"name": "example", "reversion": false, "start_ts": 1715698131, "manifest_digest": "sha256:57583a1b9c0a7509d3417387b4f43acf80d08cdcf5266ac87987be3f8f919d5d", "is_manifest_list": false, "size": 2275314, "last_modified": "Tue, 14 May 2024 14:48:51 -0000"}, {"name": "example", "reversion": false, "start_ts": 1715697708, "end_ts": 1715698131, "manifest_digest": "sha256:57583a1b9c0a7509d3417387b4f43acf80d08cdcf5266ac87987be3f8f919d5d", "is_manifest_list": false, "size": 2275314, "last_modified": "Tue, 14 May 2024 14:41:48 -0000", "expiration": "Tue, 14 May 2024 14:48:51 -0000"}, {"name": "test", "reversion": false, "start_ts": 1715695488, "end_ts": 1716324069, "manifest_digest": "sha256:57583a1b9c0a7509d3417387b4f43acf80d08cdcf5266ac87987be3f8f919d5d", "is_manifest_list": false, "size": 2275314, "last_modified": "Tue, 14 May 2024 14:04:48 -0000", "expiration": "Tue, 21 May 2024 20:41:09 -0000"}, {"name": "test", "reversion": false, "start_ts": 1715631517, "end_ts": 1715695488, "manifest_digest": "sha256:57583a1b9c0a7509d3417387b4f43acf80d08cdcf5266ac87987be3f8f919d5d", "is_manifest_list": false, "size": 2275314, "last_modified": "Mon, 13 May 2024 20:18:37 -0000", "expiration": "Tue, 14 May 2024 14:04:48 -0000"}], "page": 1, "has_additional": false}
7.13. Reverting tag changes by using the UI
Red Hat Quay offers a comprehensive time machine feature that allows older images tags to remain in the repository for set periods of time so that they can revert changes made to tags. This feature allows users to revert tag changes, like tag deletions.
Procedure
- On the Repositories page of the v2 UI, click the name of the image you want to revert.
- Click the Tag History tab.
- Find the point in the timeline at which image tags were changed or removed. Next, click the option under Revert to restore a tag to its image.
7.14. Reverting tag changes by using the API
Red Hat Quay offers a comprehensive time machine feature that allows older images tags to remain in the repository for set periods of time so that they can revert changes made to tags. This feature allows users to revert tag changes, like tag deletions.
Prerequisites
- You have Created an OAuth access token.
-
You have set
BROWSER_API_CALLS_XHR_ONLY: false
in yourconfig.yaml
file.
Procedure
You can restore a repository tag to its previous image by using the
POST /api/v1/repository/{repository}/tag/{tag}/restore
command. For example:$ curl -X POST \ -H "Authorization: Bearer <bearer_token>" \ -H "Content-Type: application/json" \ --data '{ "manifest_digest": <manifest_digest> }' \ quay-server.example.com/api/v1/repository/quayadmin/busybox/tag/test/restore
Example output
{}
To see a list of tags after restoring an old tag you can use the
GET /api/v1/repository/{repository}/tag/
command. For example:$ curl -X GET \ -H "Authorization: Bearer <bearer_token>" \ -H "Accept: application/json" \ https://<quay-server.example.com>/api/v1/repository/<namespace>/<repository_name>/tag
Example output
{"tags": [{"name": "test", "reversion": false, "start_ts": 1716324069, "manifest_digest": "sha256:57583a1b9c0a7509d3417387b4f43acf80d08cdcf5266ac87987be3f8f919d5d", "is_manifest_list": false, "size": 2275314, "last_modified": "Tue, 21 May 2024 20:41:09 -0000"}, {"name": "example", "reversion": false, "start_ts": 1715698131, "manifest_digest": "sha256:57583a1b9c0a7509d3417387b4f43acf80d08cdcf5266ac87987be3f8f919d5d", "is_manifest_list": false, "size": 2275314, "last_modified": "Tue, 14 May 2024 14:48:51 -0000"}, {"name": "example", "reversion": false, "start_ts": 1715697708, "end_ts": 1715698131, "manifest_digest": "sha256:57583a1b9c0a7509d3417387b4f43acf80d08cdcf5266ac87987be3f8f919d5d", "is_manifest_list": false, "size": 2275314, "last_modified": "Tue, 14 May 2024 14:41:48 -0000", "expiration": "Tue, 14 May 2024 14:48:51 -0000"}, {"name": "test", "reversion": false, "start_ts": 1715695488, "end_ts": 1716324069, "manifest_digest": "sha256:57583a1b9c0a7509d3417387b4f43acf80d08cdcf5266ac87987be3f8f919d5d", "is_manifest_list": false, "size": 2275314, "last_modified": "Tue, 14 May 2024 14:04:48 -0000", "expiration": "Tue, 21 May 2024 20:41:09 -0000"}, {"name": "test", "reversion": false, "start_ts": 1715631517, "end_ts": 1715695488, "manifest_digest": "sha256:57583a1b9c0a7509d3417387b4f43acf80d08cdcf5266ac87987be3f8f919d5d", "is_manifest_list": false, "size": 2275314, "last_modified": "Mon, 13 May 2024 20:18:37 -0000", "expiration": "Tue, 14 May 2024 14:04:48 -0000"}], "page": 1, "has_additional": false}
Chapter 8. Viewing and exporting logs
Activity logs are gathered for all repositories and namespace in Red Hat Quay.
Viewing usage logs of Red Hat Quay. can provide valuable insights and benefits for both operational and security purposes. Usage logs might reveal the following information:
- Resource Planning: Usage logs can provide data on the number of image pulls, pushes, and overall traffic to your registry.
- User Activity: Logs can help you track user activity, showing which users are accessing and interacting with images in the registry. This can be useful for auditing, understanding user behavior, and managing access controls.
- Usage Patterns: By studying usage patterns, you can gain insights into which images are popular, which versions are frequently used, and which images are rarely accessed. This information can help prioritize image maintenance and cleanup efforts.
- Security Auditing: Usage logs enable you to track who is accessing images and when. This is crucial for security auditing, compliance, and investigating any unauthorized or suspicious activity.
- Image Lifecycle Management: Logs can reveal which images are being pulled, pushed, and deleted. This information is essential for managing image lifecycles, including deprecating old images and ensuring that only authorized images are used.
- Compliance and Regulatory Requirements: Many industries have compliance requirements that mandate tracking and auditing of access to sensitive resources. Usage logs can help you demonstrate compliance with such regulations.
- Identifying Abnormal Behavior: Unusual or abnormal patterns in usage logs can indicate potential security breaches or malicious activity. Monitoring these logs can help you detect and respond to security incidents more effectively.
- Trend Analysis: Over time, usage logs can provide trends and insights into how your registry is being used. This can help you make informed decisions about resource allocation, access controls, and image management strategies.
There are multiple ways of accessing log files:
- Viewing logs through the web UI.
- Exporting logs so that they can be saved externally.
- Accessing log entries using the API.
To access logs, you must have administrative privileges for the selected repository or namespace.
A maximum of 100 log results are available at a time via the API. To gather more results that that, you must use the log exporter feature described in this chapter.
8.1. Viewing usage logs
Logs can provide valuable information about the way that your registry is being used. Logs can be viewed by Organization, repository, or namespace on the v2 UI by using the following procedure.
Procedure
- Log in to your Red Hat Quay registry.
- Navigate to an Organization, repository, or namespace for which you are an administrator of.
Click Logs.
- Optional. Set the date range for viewing log entries by adding dates to the From and To boxes.
-
Optional. Export the logs by clicking Export. You must enter an email address or a valid callback URL that starts with
http://
orhttps://
. This process can take an hour depending on how many logs there are.
8.2. Viewing usage logs by using the API
Logs can be viewed by Organization or repository by using the API. They can also be aggregated (grouped), or listed with more detailed. Logs can also be viewed by user, a specific date range, or by page.
8.2.1. Viewing aggregated logs
Aggregated logs can be viewed by Organization, repository, a specific user, or the current user. You can also pass in optional commands like performer
, starttime/endtime
, and next_page
to filter results.
Prerequisites
- You have Created an OAuth access token.
-
You have set
BROWSER_API_CALLS_XHR_ONLY: false
in yourconfig.yaml
file.
Procedure
Use the
GET /api/v1/user/aggregatelogs
API endpoint to return the aggregated (or grouped) logs for the current user:$ curl -X GET \ -H "Authorization: Bearer <bearer_token>" \ -H "Accept: application/json" \ "https://<quay-server.example.com>/api/v1/user/aggregatelogs"
Example output
{"aggregated": [{"kind": "create_tag", "count": 1, "datetime": "Tue, 18 Jun 2024 00:00:00 -0000"}, {"kind": "manifest_label_add", "count": 1, "datetime": "Tue, 18 Jun 2024 00:00:00 -0000"}, {"kind": "push_repo", "count": 2, "datetime": "Tue, 18 Jun 2024 00:00:00 -0000"}, {"kind": "revert_tag", "count": 1, "datetime": "Tue, 18 Jun 2024 00:00:00 -0000"}]}
You can also pass in the
performer
andstarttime/endtime
queries to obtain aggregated logs for a specific user between a specific time period. For example:$ curl -X GET \ -H "Authorization: Bearer <bearer_token>" \ -H "Accept: application/json" \ "<quay-server.example.com>/api/v1/user/aggregatelogs?performer=<username>&starttime=<MM/DD/YYYY>&endtime=<MM/DD/YYYY>"
Aggregated logs can also be viewed by Organization by using the
GET /api/v1/organization/{orgname}/aggregatelogs
. For example:$ curl -X GET \ -H "Authorization: Bearer <bearer_token>" \ -H "Accept: application/json" \ "<quay-server.example.com>/api/v1/organization/{orgname}/aggregatelogs"
Aggregated logs can also be viewed by repository by using the
GET /api/v1/repository/{repository}/aggregatelogs
command. The following example includes thestarttime/endtime
fields:$ curl -X GET \ -H "Authorization: Bearer <bearer_token>" \ -H "Accept: application/json" \ "<quay-server.example.com>/api/v1/repository/<repository_name>/<namespace>/aggregatelogs?starttime=2024-01-01&endtime=2024-06-18""
8.2.2. Viewing detailed logs
Detailed logs can be viewed by Organization, repository, a specific user, or the current user. You can also pass in optional fields like performer
, starttime/endtime
, and next_page
to filter results.
Procedure
Use the
GET /api/v1/user/logs
API endpoint to return a list of log entries for a user. For example:$ curl -X GET -H "Authorization: Bearer <bearer_token>" -H "Accept: application/json" "<quay-server.example.com>/api/v1/user/logs"
You can also pass in the
performer
andstartime/endtime
queries to obtain logs for a specific user between a specific time period. For example:$ curl -X GET -H "Authorization: Bearer <bearer_token>" -H "Accept: application/json" "http://quay-server.example.com/api/v1/user/logs?performer=quayuser&starttime=01/01/2024&endtime=06/18/2024"
Example output
--- {"start_time": "Mon, 01 Jan 2024 00:00:00 -0000", "end_time": "Wed, 19 Jun 2024 00:00:00 -0000", "logs": [{"kind": "revert_tag", "metadata": {"username": "quayuser", "repo": "busybox", "tag": "test-two", "manifest_digest": "sha256:57583a1b9c0a7509d3417387b4f43acf80d08cdcf5266ac87987be3f8f919d5d"}, "ip": "192.168.1.131", "datetime": "Tue, 18 Jun 2024 18:59:13 -0000", "performer": {"kind": "user", "name": "quayuser", "is_robot": false, "avatar": {"name": "quayuser", "hash": "b28d563a6dc76b4431fc7b0524bbff6b810387dac86d9303874871839859c7cc", "color": "#17becf", "kind": "user"}}}, {"kind": "push_repo", "metadata": {"repo": "busybox", "namespace": "quayuser", "user-agent": "containers/5.30.1 (github.com/containers/image)", "tag": "test-two", "username": "quayuser", } ---
Use the
GET /api/v1/organization/{orgname}/logs
endpoint to return logs for a specified organization:$ curl -X GET \ -H "Authorization: Bearer <bearer_token>" \ -H "Accept: application/json" \ "http://<quay-server.example.com>/api/v1/organization/{orgname}/logs"
Use the
GET /api/v1/repository/{repository}/logs
endpoint to return logs for a specified repository:$ curl -X GET \ -H "Authorization: Bearer <bearer_token>" \ -H "Accept: application/json" \ "http://<quay-server.example.com>/api/v1/repository/{repository}/logs"
8.3. Exporting repository logs by using the UI
You can obtain a larger number of log files and save them outside of the Red Hat Quay database by using the Export Logs feature. This feature has the following benefits and constraints:
- You can choose a range of dates for the logs you want to gather from a repository.
- You can request that the logs be sent to you by an email attachment or directed to a callback URL.
- To export logs, you must be an administrator of the repository or namespace.
- 30 days worth of logs are retained for all users.
- Export logs only gathers log data that was previously produced. It does not stream logging data.
- Your Red Hat Quay instance must be configured for external storage for this feature. Local storage does not work for exporting logs.
- When logs are gathered and made available to you, you should immediately copy that data if you want to save it. By default, the data expires after one hour.
Use the following procedure to export logs.
Procedure
- Select a repository for which you have administrator privileges.
- Click the Logs tab.
- Optional. If you want to specify specific dates, enter the range in the From and to boxes.
Click the Export Logs button. An Export Usage Logs pop-up appears, as shown
- Enter an email address or callback URL to receive the exported log. For the callback URL, you can use a URL to a specified domain, for example, <webhook.site>.
- Select Confirm to start the process for gather the selected log entries. Depending on the amount of logging data being gathered, this can take anywhere from a few minutes to several hours to complete.
When the log export is completed, the one of following two events happens:
- An email is received, alerting you to the available of your requested exported log entries.
- A successful status of your log export request from the webhook URL is returned. Additionally, a link to the exported data is made available for you to delete to download the logs.
The URL points to a location in your Red Hat Quay external storage and is set to expire within one hour. Make sure that you copy the exported logs before the expiration time if you intend to keep your logs.
8.4. Exporting logs by using the API
Detailed logs can be exported to a callback URL or to an email address.
Prerequisites
- You have Created an OAuth access token.
-
You have set
BROWSER_API_CALLS_XHR_ONLY: false
in yourconfig.yaml
file.
Procedure
Use the
POST /api/v1/user/exportlogs
endpoint to export logs for the current user:$ curl -X POST \ -H "Authorization: Bearer <bearer_token>" \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -d '{ "starttime": "<MM/DD/YYYY>", "endtime": "<MM/DD/YYYY>", "callback_email": "your.email@example.com" }' \ "http://<quay-server.example.com>/api/v1/user/exportlogs"
Example output
{"export_id": "6a0b9ea9-444c-4a19-9db8-113201c38cd4"}
Use the
POST /api/v1/organization/{orgname}/exportlogs
endpoint to export logs for an Organization:$ curl -X POST \ -H "Authorization: Bearer <bearer_token>" \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -d '{ "starttime": "<MM/DD/YYYY>", "endtime": "<MM/DD/YYYY>", "callback_email": "org.logs@example.com" }' \ "http://<quay-server.example.com>/api/v1/organization/{orgname}/exportlogs"
Use the
POST /api/v1/repository/{repository}/exportlogs
endpoint to export logs for a repository:$ curl -X POST \ -H "Authorization: Bearer <bearer_token>" \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -d '{ "starttime": "2024-01-01", "endtime": "2024-06-18", "callback_url": "http://your-callback-url.example.com" }' \ "http://<quay-server.example.com>/api/v1/repository/{repository}/exportlogs"
Chapter 9. Clair security scans
Clair security scanner is not enabled for Red Hat Quay by default. To enable Clair, see Clair on Red Hat Quay.
Clair security scans can be viewed on the UI, or by the API.
Procedure
- Navigate to a repository and click Tags in the navigation pane. This page shows the results of the security scan.
- To reveal more information about multi-architecture images, click See Child Manifests to see the list of manifests in extended view.
- Click a relevant link under See Child Manifests, for example, 1 Unknown to be redirected to the Security Scanner page.
- The Security Scanner page provides information for the tag, such as which CVEs the image is susceptible to, and what remediation options you might have available.
Image scanning only lists vulnerabilities found by Clair security scanner. What users do about the vulnerabilities are uncovered is up to said user. Red Hat Quay superusers do not act on found vulnerabilities.
9.1. Viewing Clair security scans by using the UI
You can view Clair security scans on the UI.
Procedure
- Navigate to a repository and click Tags in the navigation pane. This page shows the results of the security scan.
- To reveal more information about multi-architecture images, click See Child Manifests to see the list of manifests in extended view.
- Click a relevant link under See Child Manifests, for example, 1 Unknown to be redirected to the Security Scanner page.
- The Security Scanner page provides information for the tag, such as which CVEs the image is susceptible to, and what remediation options you might have available.
Image scanning only lists vulnerabilities found by Clair security scanner. What users do about the vulnerabilities are uncovered is up to said user. Red Hat Quay superusers do not act on found vulnerabilities.
9.2. View Clair security scans by using the API
You can view Clair security scans by using the API.
Procedure
Use the
GET /api/v1/repository/{repository}/manifest/{manifestref}/security
endpoint to retrieve security information about a specific manifest in a repository. For example:$ curl -X GET \ -H "Authorization: Bearer <bearer_token>" \ -H "Accept: application/json" \ "https://quay-server.example.com/api/v1/repository/<namespace>/<repository>/manifest/<manifest_digest>/security?vulnerabilities=<true_or_false>"
Example output
{"status": "queued", "data": null}
Chapter 10. Notifications overview
Red Hat Quay supports adding notifications to a repository for various events that occur in the repository’s lifecycle.
10.1. Notification actions
Notifications are added to the Events and Notifications section of the Repository Settings page. They are also added to the Notifications window, which can be found by clicking the bell icon in the navigation pane of Red Hat Quay.
Red Hat Quay notifications can be setup to be sent to a User, Team, or the entire organization.
Notifications can be delivered by one of the following methods.
E-mail notifications
E-mails are sent to specified addresses that describe the specified event. E-mail addresses must be verified on a per-repository basis.
Webhook POST notifications
An HTTP POST
call is made to the specified URL with the event’s data. For more information about event data, see "Repository events description".
When the URL is HTTPS, the call has an SSL client certificate set from Red Hat Quay. Verification of this certificate proves that the call originated from Red Hat Quay. Responses with the status code in the 2xx
range are considered successful. Responses with any other status code are considered failures and result in a retry of the webhook notification.
Flowdock notifications
Posts a message to Flowdock.
Hipchat notifications
Posts a message to HipChat.
Slack notifications
Posts a message to Slack.
10.2. Creating notifications by using the UI
Use the following procedure to add notifications.
Prerequisites
- You have created a repository.
- You have administrative privileges for the repository.
Procedure
- Navigate to a repository on Red Hat Quay.
- In the navigation pane, click Settings.
- In the Events and Notifications category, click Create Notification to add a new notification for a repository event. The Create notification popup box appears.
On the Create repository popup box, click the When this event occurs box to select an event. You can select a notification for the following types of events:
- Push to Repository
- Image build failed
- Image build queued
- Image build started
- Image build success
- Image build cancelled
- Image expiry trigger
After you have selected the event type, select the notification method. The following methods are supported:
- Quay Notification
- E-mail Notification
- Webhook POST
- Flowdock Team Notification
- HipChat Room Notification
Slack Notification
Depending on the method that you choose, you must include additional information. For example, if you select E-mail, you are required to include an e-mail address and an optional notification title.
- After selecting an event and notification method, click Create Notification.
10.2.1. Creating an image expiration notification
Image expiration event triggers can be configured to notify users through email, Slack, webhooks, and so on, and can be configured at the repository level. Triggers can be set for images expiring in any amount of days, and can work in conjunction with the auto-pruning feature.
Image expiration notifications can be set by using the Red Hat Quay v2 UI or by using the createRepoNotification
API endpoint.
Prerequisites
-
FEATURE_GARBAGE_COLLECTION: true
is set in yourconfig.yaml
file. -
Optional.
FEATURE_AUTO_PRUNE: true
is set in yourconfig.yaml
file.
Procedure
- On the Red Hat Quay v2 UI, click Repositories.
- Select the name of a repository.
- Click Settings → Events and notifications.
- Click Create notification. The Create notification popup box appears.
- Click the Select event… box, then click Image expiry trigger.
-
In the When the image is due to expiry in days box, enter the number of days before the image’s expiration when you want to receive an alert. For example, use
1
for 1 day. In the Select method… box, click one of the following:
- Webhook POST
- Flowdock Team Notification
- HipChat Room Notification
- Slack Notification
-
Depending on which method you chose, include the necessary data. For example, if you chose Webhook POST, include the
Webhook URL
. - Optional. Provide a POST JSON body template.
- Optional. Provide a Title for your notification.
- Click Submit. You are returned to the Events and notifications page, and the notification now appears.
Optional. You can set the
NOTIFICATION_TASK_RUN_MINIMUM_INTERVAL_MINUTES
variable in your config.yaml file. with this field set, if there are any expiring images notifications will be sent automatically. By default, this is set to300
, or 5 hours, however it can be adjusted as warranted.NOTIFICATION_TASK_RUN_MINIMUM_INTERVAL_MINUTES: 300 1
- 1
- By default, this field is set to
300
, or 5 hours.
Verification
Click the menu kebab → Test Notification. The following message is returned:
Test Notification Queued A test version of this notification has been queued and should appear shortly
Depending on which method you chose, check your e-mail, webhook address, Slack channel, and so on. The information sent should look similar to the following example:
{ "repository": "sample_org/busybox", "namespace": "sample_org", "name": "busybox", "docker_url": "quay-server.example.com/sample_org/busybox", "homepage": "http://quay-server.example.com/repository/sample_org/busybox", "tags": [ "latest", "v1" ], "expiring_in": "1 days" }
10.3. Creating notifications by using the API
Use the following procedure to add notifications.
Prerequisites
- You have created a repository.
- You have administrative privileges for the repository.
- You have Created an OAuth access token.
-
You have set
BROWSER_API_CALLS_XHR_ONLY: false
in yourconfig.yaml
file.
Procedure
Enter the following
POST /api/v1/repository/{repository}/notification
command to create a notification on your repository:$ curl -X POST \ -H "Authorization: Bearer <bearer_token>" \ -H "Content-Type: application/json" \ --data '{ "event": "<event>", "method": "<method>", "config": { "<config_key>": "<config_value>" }, "eventConfig": { "<eventConfig_key>": "<eventConfig_value>" } }' \ https://<quay-server.example.com>/api/v1/repository/<namespace>/<repository_name>/notification/
This command does not return output in the CLI. Instead, you can enter the following
GET /api/v1/repository/{repository}/notification/{uuid}
command to obtain information about the repository notification:{"uuid": "240662ea-597b-499d-98bb-2b57e73408d6", "title": null, "event": "repo_push", "method": "quay_notification", "config": {"target": {"name": "quayadmin", "kind": "user", "is_robot": false, "avatar": {"name": "quayadmin", "hash": "b28d563a6dc76b4431fc7b0524bbff6b810387dac86d9303874871839859c7cc", "color": "#17becf", "kind": "user"}}}, "event_config": {}, "number_of_failures": 0}
You can test your repository notification by entering the following
POST /api/v1/repository/{repository}/notification/{uuid}/test
command:$ curl -X POST \ -H "Authorization: Bearer <bearer_token>" \ https://<quay-server.example.com>/api/v1/repository/<repository>/notification/<uuid>/test
Example output
{}
You can reset repository notification failures to 0 by entering the following
POST /api/v1/repository/{repository}/notification/{uuid}
command:$ curl -X POST \ -H "Authorization: Bearer <bearer_token>" \ https://<quay-server.example.com>/api/v1/repository/<repository>/notification/<uuid>
Enter the following
DELETE /api/v1/repository/{repository}/notification/{uuid}
command to delete a repository notification:$ curl -X DELETE \ -H "Authorization: Bearer <bearer_token>" \ https://<quay-server.example.com>/api/v1/repository/<namespace>/<repository_name>/notification/<uuid>
This command does not return output in the CLI. Instead, you can enter the following
GET /api/v1/repository/{repository}/notification/
command to retrieve a list of all notifications:$ curl -X GET -H "Authorization: Bearer <bearer_token>" -H "Accept: application/json" https://<quay-server.example.com>/api/v1/repository/<namespace>/<repository_name>/notification
Example output
{"notifications": []}
10.4. Repository events description
The following sections detail repository events.
Repository Push
A successful push of one or more images was made to the repository:
{ "name": "repository", "repository": "dgangaia/test", "namespace": "dgangaia", "docker_url": "quay.io/dgangaia/test", "homepage": "https://quay.io/repository/dgangaia/repository", "updated_tags": [ "latest" ] }
Dockerfile Build Queued
The following example is a response from a Dockerfile Build that has been queued into the Build system.
Responses can differ based on the use of optional attributes.
{ "build_id": "296ec063-5f86-4706-a469-f0a400bf9df2", "trigger_kind": "github", //Optional "name": "test", "repository": "dgangaia/test", "namespace": "dgangaia", "docker_url": "quay.io/dgangaia/test", "trigger_id": "38b6e180-9521-4ff7-9844-acf371340b9e", //Optional "docker_tags": [ "master", "latest" ], "repo": "test", "trigger_metadata": { "default_branch": "master", "commit": "b7f7d2b948aacbe844ee465122a85a9368b2b735", "ref": "refs/heads/master", "git_url": "git@github.com:dgangaia/test.git", "commit_info": { //Optional "url": "https://github.com/dgangaia/test/commit/b7f7d2b948aacbe844ee465122a85a9368b2b735", "date": "2019-03-06T12:48:24+11:00", "message": "adding 5", "author": { //Optional "username": "dgangaia", "url": "https://github.com/dgangaia", //Optional "avatar_url": "https://avatars1.githubusercontent.com/u/43594254?v=4" //Optional }, "committer": { "username": "web-flow", "url": "https://github.com/web-flow", "avatar_url": "https://avatars3.githubusercontent.com/u/19864447?v=4" } } }, "is_manual": false, "manual_user": null, "homepage": "https://quay.io/repository/dgangaia/test/build/296ec063-5f86-4706-a469-f0a400bf9df2" }
Dockerfile Build started
The following example is a response from a Dockerfile Build that has been queued into the Build system.
Responses can differ based on the use of optional attributes.
{ "build_id": "a8cc247a-a662-4fee-8dcb-7d7e822b71ba", "trigger_kind": "github", //Optional "name": "test", "repository": "dgangaia/test", "namespace": "dgangaia", "docker_url": "quay.io/dgangaia/test", "trigger_id": "38b6e180-9521-4ff7-9844-acf371340b9e", //Optional "docker_tags": [ "master", "latest" ], "build_name": "50bc599", "trigger_metadata": { //Optional "commit": "50bc5996d4587fd4b2d8edc4af652d4cec293c42", "ref": "refs/heads/master", "default_branch": "master", "git_url": "git@github.com:dgangaia/test.git", "commit_info": { //Optional "url": "https://github.com/dgangaia/test/commit/50bc5996d4587fd4b2d8edc4af652d4cec293c42", "date": "2019-03-06T14:10:14+11:00", "message": "test build", "committer": { //Optional "username": "web-flow", "url": "https://github.com/web-flow", //Optional "avatar_url": "https://avatars3.githubusercontent.com/u/19864447?v=4" //Optional }, "author": { //Optional "username": "dgangaia", "url": "https://github.com/dgangaia", //Optional "avatar_url": "https://avatars1.githubusercontent.com/u/43594254?v=4" //Optional } } }, "homepage": "https://quay.io/repository/dgangaia/test/build/a8cc247a-a662-4fee-8dcb-7d7e822b71ba" }
Dockerfile Build successfully completed
The following example is a response from a Dockerfile Build that has been successfully completed by the Build system.
This event occurs simultaneously with a Repository Push event for the built image or images.
{ "build_id": "296ec063-5f86-4706-a469-f0a400bf9df2", "trigger_kind": "github", //Optional "name": "test", "repository": "dgangaia/test", "namespace": "dgangaia", "docker_url": "quay.io/dgangaia/test", "trigger_id": "38b6e180-9521-4ff7-9844-acf371340b9e", //Optional "docker_tags": [ "master", "latest" ], "build_name": "b7f7d2b", "image_id": "sha256:0339f178f26ae24930e9ad32751d6839015109eabdf1c25b3b0f2abf8934f6cb", "trigger_metadata": { "commit": "b7f7d2b948aacbe844ee465122a85a9368b2b735", "ref": "refs/heads/master", "default_branch": "master", "git_url": "git@github.com:dgangaia/test.git", "commit_info": { //Optional "url": "https://github.com/dgangaia/test/commit/b7f7d2b948aacbe844ee465122a85a9368b2b735", "date": "2019-03-06T12:48:24+11:00", "message": "adding 5", "committer": { //Optional "username": "web-flow", "url": "https://github.com/web-flow", //Optional "avatar_url": "https://avatars3.githubusercontent.com/u/19864447?v=4" //Optional }, "author": { //Optional "username": "dgangaia", "url": "https://github.com/dgangaia", //Optional "avatar_url": "https://avatars1.githubusercontent.com/u/43594254?v=4" //Optional } } }, "homepage": "https://quay.io/repository/dgangaia/test/build/296ec063-5f86-4706-a469-f0a400bf9df2", "manifest_digests": [ "quay.io/dgangaia/test@sha256:2a7af5265344cc3704d5d47c4604b1efcbd227a7a6a6ff73d6e4e08a27fd7d99", "quay.io/dgangaia/test@sha256:569e7db1a867069835e8e97d50c96eccafde65f08ea3e0d5debaf16e2545d9d1" ] }
Dockerfile Build failed
The following example is a response from a Dockerfile Build that has failed.
{ "build_id": "5346a21d-3434-4764-85be-5be1296f293c", "trigger_kind": "github", //Optional "name": "test", "repository": "dgangaia/test", "docker_url": "quay.io/dgangaia/test", "error_message": "Could not find or parse Dockerfile: unknown instruction: GIT", "namespace": "dgangaia", "trigger_id": "38b6e180-9521-4ff7-9844-acf371340b9e", //Optional "docker_tags": [ "master", "latest" ], "build_name": "6ae9a86", "trigger_metadata": { //Optional "commit": "6ae9a86930fc73dd07b02e4c5bf63ee60be180ad", "ref": "refs/heads/master", "default_branch": "master", "git_url": "git@github.com:dgangaia/test.git", "commit_info": { //Optional "url": "https://github.com/dgangaia/test/commit/6ae9a86930fc73dd07b02e4c5bf63ee60be180ad", "date": "2019-03-06T14:18:16+11:00", "message": "failed build test", "committer": { //Optional "username": "web-flow", "url": "https://github.com/web-flow", //Optional "avatar_url": "https://avatars3.githubusercontent.com/u/19864447?v=4" //Optional }, "author": { //Optional "username": "dgangaia", "url": "https://github.com/dgangaia", //Optional "avatar_url": "https://avatars1.githubusercontent.com/u/43594254?v=4" //Optional } } }, "homepage": "https://quay.io/repository/dgangaia/test/build/5346a21d-3434-4764-85be-5be1296f293c" }
Dockerfile Build cancelled
The following example is a response from a Dockerfile Build that has been cancelled.
{ "build_id": "cbd534c5-f1c0-4816-b4e3-55446b851e70", "trigger_kind": "github", "name": "test", "repository": "dgangaia/test", "namespace": "dgangaia", "docker_url": "quay.io/dgangaia/test", "trigger_id": "38b6e180-9521-4ff7-9844-acf371340b9e", "docker_tags": [ "master", "latest" ], "build_name": "cbce83c", "trigger_metadata": { "commit": "cbce83c04bfb59734fc42a83aab738704ba7ec41", "ref": "refs/heads/master", "default_branch": "master", "git_url": "git@github.com:dgangaia/test.git", "commit_info": { "url": "https://github.com/dgangaia/test/commit/cbce83c04bfb59734fc42a83aab738704ba7ec41", "date": "2019-03-06T14:27:53+11:00", "message": "testing cancel build", "committer": { "username": "web-flow", "url": "https://github.com/web-flow", "avatar_url": "https://avatars3.githubusercontent.com/u/19864447?v=4" }, "author": { "username": "dgangaia", "url": "https://github.com/dgangaia", "avatar_url": "https://avatars1.githubusercontent.com/u/43594254?v=4" } } }, "homepage": "https://quay.io/repository/dgangaia/test/build/cbd534c5-f1c0-4816-b4e3-55446b851e70" }
Vulnerability detected
The following example is a response from a Dockerfile Build has detected a vulnerability in the repository.
{ "repository": "dgangaia/repository", "namespace": "dgangaia", "name": "repository", "docker_url": "quay.io/dgangaia/repository", "homepage": "https://quay.io/repository/dgangaia/repository", "tags": ["latest", "othertag"], "vulnerability": { "id": "CVE-1234-5678", "description": "This is a bad vulnerability", "link": "http://url/to/vuln/info", "priority": "Critical", "has_fix": true } }
Chapter 11. Bare metal builds with Red Hat Quay on OpenShift Container Platform
Documentation for the builds feature has been moved to Builders and image automation. This chapter will be removed in a future version of Red Hat Quay.
Chapter 12. Red Hat Quay quota management and enforcement overview
With Red Hat Quay, users have the ability to report storage consumption and to contain registry growth by establishing configured storage quota limits. On-premise Red Hat Quay users are now equipped with the following capabilities to manage the capacity limits of their environment:
- Quota reporting: With this feature, a superuser can track the storage consumption of all their organizations. Additionally, users can track the storage consumption of their assigned organization.
- Quota management: With this feature, a superuser can define soft and hard checks for Red Hat Quay users. Soft checks tell users if the storage consumption of an organization reaches their configured threshold. Hard checks prevent users from pushing to the registry when storage consumption reaches the configured limit.
Together, these features allow service owners of a Red Hat Quay registry to define service level agreements and support a healthy resource budget.
12.1. Quota management architecture
With the quota management feature enabled, individual blob sizes are summed at the repository and namespace level. For example, if two tags in the same repository reference the same blob, the size of that blob is only counted once towards the repository total. Additionally, manifest list totals are counted toward the repository total.
Because manifest list totals are counted toward the repository total, the total quota consumed when upgrading from a previous version of Red Hat Quay might be reportedly differently in Red Hat Quay 3.9. In some cases, the new total might go over a repository’s previously-set limit. Red Hat Quay administrators might have to adjust the allotted quota of a repository to account for these changes.
The quota management feature works by calculating the size of existing repositories and namespace with a backfill worker, and then adding or subtracting from the total for every image that is pushed or garbage collected afterwords. Additionally, the subtraction from the total happens when the manifest is garbage collected.
Because subtraction occurs from the total when the manifest is garbage collected, there is a delay in the size calculation until it is able to be garbage collected. For more information about garbage collection, see Red Hat Quay garbage collection.
The following database tables hold the quota repository size, quota namespace size, and quota registry size, in bytes, of a Red Hat Quay repository within an organization:
-
QuotaRepositorySize
-
QuotaNameSpaceSize
-
QuotaRegistrySize
The organization size is calculated by the backfill worker to ensure that it is not duplicated. When an image push is initialized, the user’s organization storage is validated to check if it is beyond the configured quota limits. If an image push exceeds defined quota limitations, a soft or hard check occurs:
- For a soft check, users are notified.
- For a hard check, the push is stopped.
If storage consumption is within configured quota limits, the push is allowed to proceed.
Image manifest deletion follows a similar flow, whereby the links between associated image tags and the manifest are deleted. Additionally, after the image manifest is deleted, the repository size is recalculated and updated in the QuotaRepositorySize
, QuotaNameSpaceSize
, and QuotaRegistrySize
tables.
12.2. Quota management limitations
Quota management helps organizations to maintain resource consumption. One limitation of quota management is that calculating resource consumption on push results in the calculation becoming part of the push’s critical path. Without this, usage data might drift.
The maximum storage quota size is dependent on the selected database:
Variable | Description |
---|---|
Postgres | 8388608 TB |
MySQL | 8388608 TB |
SQL Server | 16777216 TB |
12.3. Quota management configuration fields
Field | Type | Description |
---|---|---|
FEATURE_QUOTA_MANAGEMENT | Boolean | Enables configuration, caching, and validation for quota management feature. **Default:** `False` |
DEFAULT_SYSTEM_REJECT_QUOTA_BYTES | String | Enables system default quota reject byte allowance for all organizations. By default, no limit is set. |
QUOTA_BACKFILL | Boolean | Enables the quota backfill worker to calculate the size of pre-existing blobs.
Default: |
QUOTA_TOTAL_DELAY_SECONDS | String | The time delay for starting the quota backfill. Rolling deployments can cause incorrect totals. This field must be set to a time longer than it takes for the rolling deployment to complete.
Default: |
PERMANENTLY_DELETE_TAGS | Boolean | Enables functionality related to the removal of tags from the time machine window.
Default: |
RESET_CHILD_MANIFEST_EXPIRATION | Boolean |
Resets the expirations of temporary tags targeting the child manifests. With this feature set to
Default: |
12.3.1. Example quota management configuration
The following YAML is the suggested configuration when enabling quota management.
Quota management YAML configuration
FEATURE_QUOTA_MANAGEMENT: true FEATURE_GARBAGE_COLLECTION: true PERMANENTLY_DELETE_TAGS: true QUOTA_TOTAL_DELAY_SECONDS: 1800 RESET_CHILD_MANIFEST_EXPIRATION: true
12.4. Establishing quota with the Red Hat Quay API
When an organization is first created, it does not have a quota applied. Use the /api/v1/organization/{organization}/quota endpoint:
Sample command
$ curl -k -X GET -H "Authorization: Bearer <token>" -H 'Content-Type: application/json' https://example-registry-quay-quay-enterprise.apps.docs.gcp.quaydev.org/api/v1/organization/testorg/quota | jq
Sample output
[]
12.4.1. Setting the quota
To set a quota for an organization, POST data to the /api/v1/organization/{orgname}/quota endpoint: .Sample command
$ curl -k -X POST -H "Authorization: Bearer <token>" -H 'Content-Type: application/json' -d '{"limit_bytes": 10485760}' https://example-registry-quay-quay-enterprise.apps.docs.quayteam.org/api/v1/organization/testorg/quota | jq
Sample output
"Created"
12.4.2. Viewing the quota
To see the applied quota, GET
data from the /api/v1/organization/{orgname}/quota endpoint:
Sample command
$ curl -k -X GET -H "Authorization: Bearer <token>" -H 'Content-Type: application/json' https://example-registry-quay-quay-enterprise.apps.docs.gcp.quaydev.org/api/v1/organization/testorg/quota | jq
Sample output
[ { "id": 1, "limit_bytes": 10485760, "default_config": false, "limits": [], "default_config_exists": false } ]
12.4.3. Modifying the quota
To change the existing quota, in this instance from 10 MB to 100 MB, PUT data to the /api/v1/organization/{orgname}/quota/{quota_id} endpoint:
Sample command
$ curl -k -X PUT -H "Authorization: Bearer <token>" -H 'Content-Type: application/json' -d '{"limit_bytes": 104857600}' https://example-registry-quay-quay-enterprise.apps.docs.gcp.quaydev.org/api/v1/organization/testorg/quota/1 | jq
Sample output
{ "id": 1, "limit_bytes": 104857600, "default_config": false, "limits": [], "default_config_exists": false }
12.4.4. Pushing images
To see the storage consumed, push various images to the organization.
12.4.4.1. Pushing ubuntu:18.04
Push ubuntu:18.04 to the organization from the command line:
Sample commands
$ podman pull ubuntu:18.04 $ podman tag docker.io/library/ubuntu:18.04 example-registry-quay-quay-enterprise.apps.docs.gcp.quaydev.org/testorg/ubuntu:18.04 $ podman push --tls-verify=false example-registry-quay-quay-enterprise.apps.docs.gcp.quaydev.org/testorg/ubuntu:18.04
12.4.4.2. Using the API to view quota usage
To view the storage consumed, GET
data from the /api/v1/repository endpoint:
Sample command
$ curl -k -X GET -H "Authorization: Bearer <token>" -H 'Content-Type: application/json' 'https://example-registry-quay-quay-enterprise.apps.docs.gcp.quaydev.org/api/v1/repository?last_modified=true&namespace=testorg&popularity=true&public=true' | jq
Sample output
{ "repositories": [ { "namespace": "testorg", "name": "ubuntu", "description": null, "is_public": false, "kind": "image", "state": "NORMAL", "quota_report": { "quota_bytes": 27959066, "configured_quota": 104857600 }, "last_modified": 1651225630, "popularity": 0, "is_starred": false } ] }
12.4.4.3. Pushing another image
Pull, tag, and push a second image, for example,
nginx
:Sample commands
$ podman pull nginx $ podman tag docker.io/library/nginx example-registry-quay-quay-enterprise.apps.docs.gcp.quaydev.org/testorg/nginx $ podman push --tls-verify=false example-registry-quay-quay-enterprise.apps.docs.gcp.quaydev.org/testorg/nginx
To view the quota report for the repositories in the organization, use the /api/v1/repository endpoint:
Sample command
$ curl -k -X GET -H "Authorization: Bearer <token>" -H 'Content-Type: application/json' 'https://example-registry-quay-quay-enterprise.apps.docs.gcp.quaydev.org/api/v1/repository?last_modified=true&namespace=testorg&popularity=true&public=true'
Sample output
{ "repositories": [ { "namespace": "testorg", "name": "ubuntu", "description": null, "is_public": false, "kind": "image", "state": "NORMAL", "quota_report": { "quota_bytes": 27959066, "configured_quota": 104857600 }, "last_modified": 1651225630, "popularity": 0, "is_starred": false }, { "namespace": "testorg", "name": "nginx", "description": null, "is_public": false, "kind": "image", "state": "NORMAL", "quota_report": { "quota_bytes": 59231659, "configured_quota": 104857600 }, "last_modified": 1651229507, "popularity": 0, "is_starred": false } ] }
To view the quota information in the organization details, use the /api/v1/organization/{orgname} endpoint:
Sample command
$ curl -k -X GET -H "Authorization: Bearer <token>" -H 'Content-Type: application/json' 'https://example-registry-quay-quay-enterprise.apps.docs.gcp.quaydev.org/api/v1/organization/testorg' | jq
Sample output
{ "name": "testorg", ... "quotas": [ { "id": 1, "limit_bytes": 104857600, "limits": [] } ], "quota_report": { "quota_bytes": 87190725, "configured_quota": 104857600 } }
12.4.5. Rejecting pushes using quota limits
If an image push exceeds defined quota limitations, a soft or hard check occurs:
- For a soft check, or warning, users are notified.
- For a hard check, or reject, the push is terminated.
12.4.5.1. Setting reject and warning limits
To set reject and warning limits, POST data to the /api/v1/organization/{orgname}/quota/{quota_id}/limit endpoint:
Sample reject limit command
$ curl -k -X POST -H "Authorization: Bearer <token>" -H 'Content-Type: application/json' -d '{"type":"Reject","threshold_percent":80}' https://example-registry-quay-quay-enterprise.apps.docs.gcp.quaydev.org/api/v1/organization/testorg/quota/1/limit
Sample warning limit command
$ curl -k -X POST -H "Authorization: Bearer <token>" -H 'Content-Type: application/json' -d '{"type":"Warning","threshold_percent":50}' https://example-registry-quay-quay-enterprise.apps.docs.gcp.quaydev.org/api/v1/organization/testorg/quota/1/limit
12.4.5.2. Viewing reject and warning limits
To view the reject and warning limits, use the /api/v1/organization/{orgname}/quota endpoint:
View quota limits
$ curl -k -X GET -H "Authorization: Bearer <token>" -H 'Content-Type: application/json' https://example-registry-quay-quay-enterprise.apps.docs.gcp.quaydev.org/api/v1/organization/testorg/quota | jq
Sample output for quota limits
[ { "id": 1, "limit_bytes": 104857600, "default_config": false, "limits": [ { "id": 2, "type": "Warning", "limit_percent": 50 }, { "id": 1, "type": "Reject", "limit_percent": 80 } ], "default_config_exists": false } ]
12.4.5.3. Pushing an image when the reject limit is exceeded
In this example, the reject limit (80%) has been set to below the current repository size (~83%), so the next push should automatically be rejected.
Push a sample image to the organization from the command line:
Sample image push
$ podman pull ubuntu:20.04 $ podman tag docker.io/library/ubuntu:20.04 example-registry-quay-quay-enterprise.apps.docs.gcp.quaydev.org/testorg/ubuntu:20.04 $ podman push --tls-verify=false example-registry-quay-quay-enterprise.apps.docs.gcp.quaydev.org/testorg/ubuntu:20.04
Sample output when quota exceeded
Getting image source signatures Copying blob d4dfaa212623 [--------------------------------------] 8.0b / 3.5KiB Copying blob cba97cc5811c [--------------------------------------] 8.0b / 15.0KiB Copying blob 0c78fac124da [--------------------------------------] 8.0b / 71.8MiB WARN[0002] failed, retrying in 1s ... (1/3). Error: Error writing blob: Error initiating layer upload to /v2/testorg/ubuntu/blobs/uploads/ in example-registry-quay-quay-enterprise.apps.docs.gcp.quaydev.org: denied: Quota has been exceeded on namespace Getting image source signatures Copying blob d4dfaa212623 [--------------------------------------] 8.0b / 3.5KiB Copying blob cba97cc5811c [--------------------------------------] 8.0b / 15.0KiB Copying blob 0c78fac124da [--------------------------------------] 8.0b / 71.8MiB WARN[0005] failed, retrying in 1s ... (2/3). Error: Error writing blob: Error initiating layer upload to /v2/testorg/ubuntu/blobs/uploads/ in example-registry-quay-quay-enterprise.apps.docs.gcp.quaydev.org: denied: Quota has been exceeded on namespace Getting image source signatures Copying blob d4dfaa212623 [--------------------------------------] 8.0b / 3.5KiB Copying blob cba97cc5811c [--------------------------------------] 8.0b / 15.0KiB Copying blob 0c78fac124da [--------------------------------------] 8.0b / 71.8MiB WARN[0009] failed, retrying in 1s ... (3/3). Error: Error writing blob: Error initiating layer upload to /v2/testorg/ubuntu/blobs/uploads/ in example-registry-quay-quay-enterprise.apps.docs.gcp.quaydev.org: denied: Quota has been exceeded on namespace Getting image source signatures Copying blob d4dfaa212623 [--------------------------------------] 8.0b / 3.5KiB Copying blob cba97cc5811c [--------------------------------------] 8.0b / 15.0KiB Copying blob 0c78fac124da [--------------------------------------] 8.0b / 71.8MiB Error: Error writing blob: Error initiating layer upload to /v2/testorg/ubuntu/blobs/uploads/ in example-registry-quay-quay-enterprise.apps.docs.gcp.quaydev.org: denied: Quota has been exceeded on namespace
12.4.5.4. Notifications for limits exceeded
When limits are exceeded, a notification appears:
Quota notifications
Chapter 13. Red Hat Quay as a proxy cache for upstream registries
With the growing popularity of container development, customers increasingly rely on container images from upstream registries like Docker or Google Cloud Platform to get services up and running. Today, registries have rate limitations and throttling on the number of times users can pull from these registries.
With this feature, Red Hat Quay will act as a proxy cache to circumvent pull-rate limitations from upstream registries. Adding a cache feature also accelerates pull performance, because images are pulled from the cache rather than upstream dependencies. Cached images are only updated when the upstream image digest differs from the cached image, reducing rate limitations and potential throttling.
With Red Hat Quay cache proxy, the following features are available:
- Specific organizations can be defined as a cache for upstream registries.
Configuration of a Quay organization that acts as a cache for a specific upstream registry. This repository can be defined by using the Quay UI, and offers the following configurations:
- Upstream registry credentials for private repositories or increased rate limiting.
- Expiration timer to avoid surpassing cache organization size.
- Global on/off configurable via the configuration application.
-
Caching of entire upstream registries or just a single namespace, for example, all of
docker.io
or justdocker.io/library
. - Logging of all cache pulls.
- Cached images scannability by Clair.
13.1. Proxy cache architecture
The following image shows the expected design flow and architecture of the proxy cache feature.
When a user pulls an image, for example, postgres:14
, from an upstream repository on Red Hat Quay, the repository checks to see if an image is present. If the image does not exist, a fresh pull is initiated. After being pulled, the image layers are saved to cache and server to the user in parallel. The following image depicts an architectural overview of this scenario:
If the image in the cache exists, users can rely on Quay’s cache to stay up-to-date with the upstream source so that newer images from the cache are automatically pulled. This happens when tags of the original image have been overwritten in the upstream registry. The following image depicts an architectural overview of what happens when the upstream image and cached version of the image are different:
If the upstream image and cached version are the same, no layers are pulled and the cached image is delivered to the user.
In some cases, users initiate pulls when the upstream registry is down. If this happens with the configured staleness period, the image stored in cache is delivered. If the pull happens after the configured staleness period, the error is propagated to the user. The following image depicts an architectural overview when a pull happens after the configured staleness period:
Quay administrators can leverage the configurable size limit of an organization to limit cache size so that backend storage consumption remains predictable. This is achieved by discarding images from the cache according to the frequency in which an image is used. The following image depicts an architectural overview of this scenario:
13.2. Proxy cache limitations
Proxy caching with Red Hat Quay has the following limitations:
- Your proxy cache must have a size limit of greater than, or equal to, the image you want to cache. For example, if your proxy cache organization has a maximum size of 500 MB, and the image a user wants to pull is 700 MB, the image will be cached and will overflow beyond the configured limit.
- Cached images must have the same properties that images on a Quay repository must have.
- Currently, only layers requested by the client are cached.
13.3. Using Red Hat Quay to proxy a remote registry
The following procedure describes how you can use Red Hat Quay to proxy a remote registry. This procedure is set up to proxy quay.io, which allows users to use podman
to pull any public image from any namespace on quay.io.
Prerequisites
-
FEATURE_PROXY_CACHE
in your config.yaml is set totrue
. - Assigned the Member team role. For more information about team roles, see Users and organizations in Red Hat Quay.
Procedure
- On the Red Hat Quay v2 UI, click the name of an organization, for example, cache-org.
- In the navigation pane, click Settings.
In the Remote Registry box, enter the name of the remote registry to be cached, for example,
quay.io
, and click Save.NoteBy adding a namespace to the Remote Registry, for example,
quay.io/<namespace>
, users in your organization will only be able to proxy from that namespace.- Optional. In the Remote Registry username box, enter the username for authenticating into the remote registry specified in the previous step. For anonymous pulls from the upstream, you can leave this empty. If you do note set a username at the time of creation, you cannot add one without removing the proxy cache and creating a new registry.
- Optional. In the Remote registry password box, enter the password for authenticating into the remote registry. For anonymous pulls from the upstream, you can leave this empty. If you do note set a username at the time of creation, you cannot add one without removing the proxy cache and creating a new registry.
Optional. Set a time in the Expiration field.
Note- The default tag Expiration field for cached images in a proxy organization is set to 86400 seconds. In the proxy organization, the tag expiration is refreshed to the value set in the UI’s Expiration field every time the tag is pulled. This feature is different than Quay’s default individual tag expiration feature. In a proxy organization, it is possible to override the individual tag feature. When this happens, the individual tag’s expiration is reset according to the Expiration field of the proxy organization.
- Expired images will disappear after the allotted time, but are still stored in Red Hat Quay. The time in which an image is completely deleted, or collected, depends on the Time Machine setting of your organization. The default time for garbage collection is 14 days unless otherwise specified.
- Optional. Check the http box if you want an unsecure protocol used. If not checked, https is used to request the remote registry.
- Click Save.
Verification
On the CLI, pull a public image from the remote registry that was specified, for example,
quay.io
, acting as a proxy cache:$ podman pull <registry_url>/<organization_name>/<quayio_namespace>/<image_name>
ImportantIf your organization is set up to pull from a single namespace in the remote registry, the remote registry namespace must be omitted from the URL. For example,
podman pull <registry_url>/<organization_name>/<image_name>
.
13.3.1. Leveraging storage quota limits in proxy organizations
With Red Hat Quay 3.8, the proxy cache feature has been enhanced with an auto-pruning feature for tagged images. The auto-pruning of image tags is only available when a proxied namespace has quota limitations configured. Currently, if an image size is greater than quota for an organization, the image is skipped from being uploaded until an administrator creates the necessary space. Now, when an image is pushed that exceeds the allotted space, the auto-pruning enhancement marks the least recently used tags for deletion. As a result, the new image tag is stored, while the least used image tag is marked for deletion.
- As part of the auto-pruning feature, the tags that are marked for deletion are eventually garbage collected by the garbage collector (gc) worker process. As a result, the quota size restriction is not fully enforced during this period.
- Currently, the namespace quota size computation does not take into account the size for manifest child. This is a known issue and will be fixed in a future version of Red Hat Quay.
13.3.1.1. Testing the storage quota limits feature in proxy organizations
Use the following procedure to test the auto-pruning feature of an organization with proxy cache and storage quota limitations enabled.
Prerequisites
- Your organization is configured to serve as a proxy organization. The following example proxies from quay.io.
-
FEATURE_PROXY_CACHE
is set totrue
in yourconfig.yaml
file. -
FEATURE_QUOTA_MANAGEMENT
is set totrue
in yourconfig.yaml
file. -
Your organization is configured with a quota limit, for example,
150 MB
.
Procedure
Pull an image to your repository from your proxy organization, for example:
$ podman pull quay-server.example.com/proxytest/projectquay/quay:3.7.9
Depending on the space left in your repository, you might need to pull additional images from your proxy organization, for example:
$ podman pull quay-server.example.com/proxytest/projectquay/quay:3.6.2
In the Red Hat Quay registry UI, click the name of your repository.
-
Click Tags in the navigation pane and ensure that
quay:3.7.9
andquay:3.6.2
are tagged.
-
Click Tags in the navigation pane and ensure that
Pull the last image that will result in your repository exceeding the allotted quota, for example:
$ podman pull quay-server.example.com/proxytest/projectquay/quay:3.5.1
-
Refresh the Tags page of your Red Hat Quay registry. The first image that you pushed, for example,
quay:3.7.9
should have been auto-pruned. The Tags page should now showquay:3.6.2
andquay:3.5.1
.
Chapter 14. Virtual builds with Red Hat Quay on OpenShift Container Platform
Documentation for the builds feature has been moved to Builders and image automation. This chapter will be removed in a future version of Red Hat Quay.
Chapter 15. Using the Red Hat Quay API
Red Hat Quay provides a full OAuth 2, RESTful API. [OAuth 2] RESTful API provides the following benefits:
-
It is available from endpoint
/api/v1
endpoint of your Red Hat Quay host. For example,https://<quay-server.example.com>/api/v1
. -
It allows users to connect to endpoints through their browser to
GET
,POST
,DELETE
, andPUT
Red Hat Quay settings by enabling the Swagger UI. - It can be accessed by applications that make API calls and use OAuth tokens.
- It sends and receives data as JSON.
The following section describes how to access the Red Hat Quay API so that it can be used with your deployment.
15.1. Accessing the Quay API from Quay.io
If you don’t have your own Red Hat Quay cluster running yet, you can explore the Red Hat Quay API available from Quay.io from your web browser:
https://docs.quay.io/api/swagger/
The API Explorer that appears shows Quay.io API endpoints. You will not see superuser API endpoints or endpoints for Red Hat Quay features that are not enabled on Quay.io (such as Repository Mirroring).
From API Explorer, you can get, and sometimes change, information on:
- Billing, subscriptions, and plans
- Repository builds and build triggers
- Error messages and global messages
- Repository images, manifests, permissions, notifications, vulnerabilities, and image signing
- Usage logs
- Organizations, members and OAuth applications
- User and robot accounts
- and more…
Select to open an endpoint to view the Model Schema for each part of the endpoint. Open an endpoint, enter any required parameters (such as a repository name or image), then select the Try it out!
button to query or change settings associated with a Quay.io endpoint.
15.2. Creating a v1 OAuth access token
OAuth access tokens are credentials that allow you to access protected resources in a secure manner. With Red Hat Quay, you must create an OAuth access token before you can access the API endpoints of your organization.
Use the following procedure to create an OAuth access token.
Prerequisites
- You have logged in to Red Hat Quay as an administrator.
Procedure
- On the main page, select an Organization.
- In the navigation pane, select Applications.
- Click Create New Application and provide a new application name, then press Enter.
- On the OAuth Applications page, select the name of your application.
Optional. Enter the following information:
- Application Name
- Homepage URL
- Description
- Avatar E-mail
- Redirect/Callback URL prefix
- In the navigation pane, select Generate Token.
Check the boxes for the following options:
- Administer Organization
- Administer Repositories
- Create Repositories
- View all visible repositories
- Read/Write to any accessible repositories
- Super User Access
- Administer User
- Read User Information
- Click Generate Access Token. You are redirected to a new page.
- Review the permissions that you are allowing, then click Authorize Application. Confirm your decision by clicking Authorize Application.
You are redirected to the Access Token page. Copy and save the access token.
ImportantThis is the only opportunity to copy and save the access token. It cannot be reobtained after leaving this page.
15.3. Creating an OCI referrers OAuth access token
In some cases, you might want to create an OCI referrers OAuth access token. This token is used to list OCI referrers of a manifest under a repository.
Procedure
Update your
config.yaml
file to include theFEATURE_REFERRERS_API: true
field. For example:# ... FEATURE_REFERRERS_API: true # ...
Enter the following command to Base64 encode your credentials:
$ echo -n '<username>:<password>' | base64
Example output
abcdeWFkbWluOjE5ODlraWROZXQxIQ==
Enter the following command to use the base64 encoded string and modify the URL endpoint to your Red Hat Quay server:
$ curl --location '<quay-server.example.com>/v2/auth?service=<quay-server.example.com>&scope=repository:quay/listocireferrs:pull,push' --header 'Authorization: Basic <base64_username:password_encode_token>' -k | jq
Example output
{ "token": "<example_secret> }
15.4. Reassigning an OAuth access token
Organization administrators can assign OAuth API tokens to be created by other user’s with specific permissions. This allows the audit logs to be reflected accurately when the token is used by a user that has no organization administrative permissions to create an OAuth API token.
The following procedure only works on the current Red Hat Quay UI. It is not currently implemented in the Red Hat Quay v2 UI.
Prerequisites
You are logged in as a user with organization administrative privileges, which allows you to assign an OAuth API token.
NoteOAuth API tokens are used for authentication and not authorization. For example, the user that you are assigning the OAuth token to must have the
Admin
team role to use administrative API endpoints. For more information, see Managing access to repositories.
Procedure
Optional. If not already, update your Red Hat Quay
config.yaml
file to include theFEATURE_ASSIGN_OAUTH_TOKEN: true
field:# ... FEATURE_ASSIGN_OAUTH_TOKEN: true # ...
- Optional. Restart your Red Hat Quay registry.
- Log in to your Red Hat Quay registry as an organization administrator.
- Click the name of the organization in which you created the OAuth token for.
- In the navigation pane, click Applications.
- Click the proper application name.
- In the navigation pane, click Generate Token.
- Click Assign another user and enter the name of the user that will take over the OAuth token.
Check the boxes for the desired permissions that you want the new user to have. For example, if you only want the new user to be able to create repositories, click Create Repositories.
ImportantPermission control is defined by the team role within an organization and must be configured regardless of the options selected here. For example, the user that you are assigning the OAuth token to must have the
Admin
team role to use administrative API endpoints.Solely checking the Super User Access box does not actually grant the user this permission. Superusers must be configured via the
config.yaml
file and the box must be checked here.Click Assign token. A popup box appears that confirms authorization with the following message and shows you the approved permissions:
This will prompt user <username> to generate a token with the following permissions: repo:create
Click Assign token in the popup box. You are redirected to a new page that displays the following message:
Token assigned successfully
Verification
- After reassigning an OAuth token, the assigned user must accept the token to receive the bearer token, which is required to use API endpoints. Request that the assigned user logs into the Red Hat Quay registry.
- After they have logged in, they must click their username under Users and Organizations.
- In the navigation pane, they must click External Logins And Applications.
- Under Authorized Applications, they must confirm the application by clicking Authorize Application. They are directed to a new page where they must reconfirm by clicking Authorize Application.
- They are redirected to a new page that reveals their bearer token. They must save this bearer token, as it cannot be viewed again.
15.5. Accessing your Quay API from a web browser
By enabling Swagger, you can access the API for your own Red Hat Quay instance through a web browser. This URL exposes the Red Hat Quay API explorer via the Swagger UI and this URL:
https://<yourquayhost>/api/v1/discovery.
That way of accessing the API does not include superuser endpoints that are available on Red Hat Quay installations. Here is an example of accessing a Red Hat Quay API interface running on the local system by running the swagger-ui container image:
# export SERVER_HOSTNAME=<yourhostname> # sudo podman run -p 8888:8080 -e API_URL=https://$SERVER_HOSTNAME:8443/api/v1/discovery docker.io/swaggerapi/swagger-ui
With the swagger-ui container running, open your web browser to localhost port 8888 to view API endpoints via the swagger-ui container.
To avoid errors in the log such as "API calls must be invoked with an X-Requested-With header if called from a browser," add the following line to the config.yaml
on all nodes in the cluster and restart Red Hat Quay:
BROWSER_API_CALLS_XHR_ONLY: false
15.6. Accessing the Red Hat Quay API from the command line
You can use the curl
command to GET, PUT, POST, or DELETE settings via the API for your Red Hat Quay cluster. Replace <token>
with the OAuth access token you created earlier to get or change settings in the following examples.
Chapter 16. Open Container Initiative support
Container registries were originally designed to support container images in the Docker image format. To promote the use of additional runtimes apart from Docker, the Open Container Initiative (OCI) was created to provide a standardization surrounding container runtimes and image formats. Most container registries support the OCI standardization as it is based on the Docker image manifest V2, Schema 2 format.
In addition to container images, a variety of artifacts have emerged that support not just individual applications, but also the Kubernetes platform as a whole. These range from Open Policy Agent (OPA) policies for security and governance to Helm charts and Operators that aid in application deployment.
Red Hat Quay is a private container registry that not only stores container images, but also supports an entire ecosystem of tooling to aid in the management of containers. Red Hat Quay strives to be as compatible as possible with the OCI 1.1 Image and Distribution specifications, and supports common media types like Helm charts (as long as they pushed with a version of Helm that supports OCI) and a variety of arbitrary media types within the manifest or layer components of container images. Support for OCI media types differs from previous iterations of Red Hat Quay, when the registry was more strict about accepted media types. Because Red Hat Quay now works with a wider array of media types, including those that were previously outside the scope of its support, it is now more versatile accommodating not only standard container image formats but also emerging or unconventional types.
In addition to its expanded support for novel media types, Red Hat Quay ensures compatibility with Docker images, including V2_2 and V2_1 formats. This compatibility with Docker V2_2 and V2_1 images demonstrates Red Hat Quay’s' commitment to providing a seamless experience for Docker users. Moreover, Red Hat Quay continues to extend its support for Docker V1 pulls, catering to users who might still rely on this earlier version of Docker images.
Support for OCI artifacts are enabled by default. The following examples show you how to use some some media types, which can be used as examples for using other OCI media types.
16.1. Helm and OCI prerequisites
Helm simplifies how applications are packaged and deployed. Helm uses a packaging format called Charts which contain the Kubernetes resources representing an application. Red Hat Quay supports Helm charts so long as they are a version supported by OCI.
Use the following procedures to pre-configure your system to use Helm and other OCI media types.
The most recent version of Helm can be downloaded from the Helm releases page. After you have downloaded Helm, you must enable your system to trust SSL/TLS certificates used by Red Hat Quay.
16.1.1. Enabling your system to trust SSL/TLS certificates used by Red Hat Quay
Communication between the Helm client and Red Hat Quay is facilitated over HTTPS. As of Helm 3.5, support is only available for registries communicating over HTTPS with trusted certificates. In addition, the operating system must trust the certificates exposed by the registry. You must ensure that your operating system has been configured to trust the certificates used by Red Hat Quay. Use the following procedure to enable your system to trust the custom certificates.
Procedure
Enter the following command to copy the
rootCA.pem
file to the/etc/pki/ca-trust/source/anchors/
folder:$ sudo cp rootCA.pem /etc/pki/ca-trust/source/anchors/
Enter the following command to update the CA trust store:
$ sudo update-ca-trust extract
16.2. Using Helm charts
Use the following example to download and push an etherpad chart from the Red Hat Community of Practice (CoP) repository.
Prerequisites
- You have logged into Red Hat Quay.
Procedure
Add a chart repository by entering the following command:
$ helm repo add redhat-cop https://redhat-cop.github.io/helm-charts
Enter the following command to update the information of available charts locally from the chart repository:
$ helm repo update
Enter the following command to pull a chart from a repository:
$ helm pull redhat-cop/etherpad --version=0.0.4 --untar
Enter the following command to package the chart into a chart archive:
$ helm package ./etherpad
Example output
Successfully packaged chart and saved it to: /home/user/linux-amd64/etherpad-0.0.4.tgz
Log in to Red Hat Quay using
helm registry login
:$ helm registry login quay370.apps.quayperf370.perfscale.devcluster.openshift.com
Push the chart to your repository using the
helm push
command:$ helm push etherpad-0.0.4.tgz oci://quay370.apps.quayperf370.perfscale.devcluster.openshift.com
Example output:
Pushed: quay370.apps.quayperf370.perfscale.devcluster.openshift.com/etherpad:0.0.4 Digest: sha256:a6667ff2a0e2bd7aa4813db9ac854b5124ff1c458d170b70c2d2375325f2451b
Ensure that the push worked by deleting the local copy, and then pulling the chart from the repository:
$ rm -rf etherpad-0.0.4.tgz
$ helm pull oci://quay370.apps.quayperf370.perfscale.devcluster.openshift.com/etherpad --version 0.0.4
Example output:
Pulled: quay370.apps.quayperf370.perfscale.devcluster.openshift.com/etherpad:0.0.4 Digest: sha256:4f627399685880daf30cf77b6026dc129034d68c7676c7e07020b70cf7130902
16.3. Annotation parsing
Some OCI media types do not utilize labels and, as such, critical information such as expiration timestamps are not included. Red Hat Quay supports metadata passed through annotations to accommodate OCI media types that do not include these labels for metadata transmission. Tools such as ORAS (OCI Registry as Storage) can now be used to embed information with artifact types to help ensure that images operate properly, for example, to expire.
The following procedure uses ORAS to add an expiration date to an OCI media artifact.
If you pushed an image with podman push
, and then add an annotation with oras
, the MIME type is changed. Consequently, you will not be able to pull the same image with podman pull
because Podman does not recognize that MIME type.
Prerequisites
-
You have downloaded the
oras
CLI. For more information, see Installation. - You have pushed an OCI media artifact to your Red Hat Quay repository.
Procedure
By default, some OCI media types, like
application/vnd.oci.image.manifest.v1+json
, do not use certain labels, like expiration timestamps. You can use a CLI tool like ORAS (oras
) to add annotations to OCI media types. For example:$ oras push --annotation "quay.expires-after=2d" \ 1 --annotation "expiration = 2d" \ 2 quay.io/<organization_name>/<repository>/<image_name>:<tag>
Example output
✓ Exists application/vnd.oci.empty.v1+json 2/2 B 100.00% 0s └─ sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a ✓ Uploaded application/vnd.oci.image.manifest.v1+json 561/561 B 100.00% 511ms └─ sha256:9b4f2d43b62534423894d077f0ff0e9e496540ec8b52b568ea8b757fc9e7996b Pushed [registry] quay.io/stevsmit/testorg3/oci-image:v1 ArtifactType: application/vnd.unknown.artifact.v1 Digest: sha256:9b4f2d43b62534423894d077f0ff0e9e496540ec8b52b568ea8b757fc9e7996b
Verification
Pull the image with
oras
. For example:$ oras pull quay.io/<organization_name>/<repository>/<image_name>:<tag>
Inspect the changes using
oras
. For example:$ oras manifest fetch quay.io/<organization_name>/<repository>/<image_name>:<tag>
Example output
{"schemaVersion":2,"mediaType":"application/vnd.oci.image.manifest.v1+json","artifactType":"application/vnd.unknown.artifact.v1","config":{"mediaType":"application/vnd.oci.empty.v1+json","digest":"sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a","size":2,"data":"e30="},"layers":[{"mediaType":"application/vnd.oci.empty.v1+json","digest":"sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a","size":2,"data":"e30="}],"annotations":{"org.opencontainers.image.created":"2024-07-11T15:22:42Z","version ":" 8.11"}}
16.4. Attaching referrers to an image tag
The following procedure shows you how to attach referrers to an image tag using different schemas supported by the OCI distribution spec 1.1 using the oras
CLI. This is useful for attaching and managing additional metadata like referrers to container images.
Prerequisites
-
You have downloaded the
oras
CLI. For more information, see Installation. - You have access to an OCI media artifact.
Procedure
Tag an OCI media artifact by entering the following command:
$ podman tag <myartifact_image> <quay-server.example.com>/<organization_name>/<repository>/<image_name>:<tag>
Push the artifact to your Red Hat Quay registry. For example:
$ podman push <myartifact_image> <quay-server.example.com>/<organization_name>/<repository>/<image_name>:<tag>
Enter the following command to attach a manifest using the OCI 1.1 referrers
API
schema withoras
:$ oras attach --artifact-type <MIME_type> --distribution-spec v1.1-referrers-api <myartifact_image> \ <quay-server.example.com>/<organization_name>/<repository>/<image_name>:<tag> \ <example_file>.txt
Example output
-spec v1.1-referrers-api quay.io/testorg3/myartifact-image:v1.0 hi.txt ✓ Exists hi.txt 3/3 B 100.00% 0s └─ sha256:98ea6e4f216f2fb4b69fff9b3a44842c38686ca685f3f55dc48c5d3fb1107be4 ✓ Exists application/vnd.oci.empty.v1+json 2/2 B 100.00% 0s └─ sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a ✓ Uploaded application/vnd.oci.image.manifest.v1+json 723/723 B 100.00% 677ms └─ sha256:31c38e6adcc59a3cfbd2ef971792aaf124cbde8118e25133e9f9c9c4cd1d00c6 Attached to [registry] quay.io/testorg3/myartifact-image@sha256:db440c57edfad40c682f9186ab1c1075707ce7a6fdda24a89cb8c10eaad424da Digest: sha256:31c38e6adcc59a3cfbd2ef971792aaf124cbde8118e25133e9f9c9c4cd1d00c6
Enter the following command to attach a manifest using the OCI 1.1 referrers
tag
schema:$ oras attach --artifact-type <MIME_type> --distribution-spec v1.1-referrers-tag \ <myartifact_image> <quay-server.example.com>/<organization_name>/<repository>/<image_name>:<tag> \ <example_file>.txt
Example output
✓ Exists hi.txt 3/3 B 100.00% 0s └─ sha256:98ea6e4f216f2fb4b69fff9b3a44842c38686ca685f3f55dc48c5d3fb1107be4 ✓ Exists application/vnd.oci.empty.v1+json 2/2 B 100.00% 0s └─ sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a ✓ Uploaded application/vnd.oci.image.manifest.v1+json 723/723 B 100.00% 465ms └─ sha256:2d4b54201c8b134711ab051389f5ba24c75c2e6b0f0ff157fce8ffdfe104f383 Attached to [registry] quay.io/testorg3/myartifact-image@sha256:db440c57edfad40c682f9186ab1c1075707ce7a6fdda24a89cb8c10eaad424da Digest: sha256:2d4b54201c8b134711ab051389f5ba24c75c2e6b0f0ff157fce8ffdfe104f383
Enter the following command to discoverer referrers of the artifact using the
tag
schema:$ oras discover --insecure --distribution-spec v1.1-referrers-tag \ <quay-server.example.com>/<organization_name>/<repository>/<image_name>:<tag>
Example output
quay.io/testorg3/myartifact-image@sha256:db440c57edfad40c682f9186ab1c1075707ce7a6fdda24a89cb8c10eaad424da └── doc/example └── sha256:2d4b54201c8b134711ab051389f5ba24c75c2e6b0f0ff157fce8ffdfe104f383
Enter the following command to discoverer referrers of the artifact using the
API
schema:$ oras discover --distribution-spec v1.1-referrers-api \ <quay-server.example.com>/<organization_name>/<repository>/<image_name>:<tag>
Example output
Discovered 3 artifacts referencing v1.0 Digest: sha256:db440c57edfad40c682f9186ab1c1075707ce7a6fdda24a89cb8c10eaad424da Artifact Type Digest sha256:2d4b54201c8b134711ab051389f5ba24c75c2e6b0f0ff157fce8ffdfe104f383 sha256:22b7e167793808f83db66f7d35fbe0088b34560f34f8ead36019a4cc48fd346b sha256:bb2b7e7c3a58fd9ba60349473b3a746f9fe78995a88cb329fc2fd1fd892ea4e4
Optional. You can also discover referrers by using the
/v2/<organization_name>/<repository_name>/referrers/<sha256_digest>
endpoint. For this to work, you must generate a v2 API token and setFEATURE_REFERRERS_API: true
in yourconfig.yaml
file.Update your
config.yaml
file to include theFEATURE_REFERRERS_API
field. For example:# ... FEATURE_REFERRERS_API: true # ...
Enter the following command to Base64 encode your credentials:
$ echo -n '<username>:<password>' | base64
Example output
abcdeWFkbWluOjE5ODlraWROZXQxIQ==
Enter the following command to use the base64 encoded token and modify the URL endpoint to your Red Hat Quay server:
$ curl --location '<quay-server.example.com>/v2/auth?service=<quay-server.example.com>&scope=repository:quay/listocireferrs:pull,push' --header 'Authorization: Basic <base64_username:password_encode_token>' -k | jq
Example output
{ "token": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ijl5RWNtWmdiZ0l6czBBZW16emhTMHM1R0g2RDJnV2JGUTdUNGZYand4MlUiLCJ0eXAiOiJKV1QifQ..." }
Enter the following command, using the v2 API token, to list OCI referrers of a manifest under a repository:
$ GET https://<quay-server.example.com>/v2/<organization_name>/<repository_name>/referrers/sha256:0de63ba2d98ab328218a1b6373def69ec0d0e7535866f50589111285f2bf3fb8 --header 'Authorization: Bearer <v2_bearer_token> -k | jq
Example output
{ "schemaVersion": 2, "mediaType": "application/vnd.oci.image.index.v1+json", "manifests": [ { "mediaType": "application/vnd.oci.image.manifest.v1+json", "digest": "sha256:2d4b54201c8b134711ab051389f5ba24c75c2e6b0f0ff157fce8ffdfe104f383", "size": 793 }, ] }