Get started with the Red Hat Quay API
Learn how OAuth 2.0 tokens work, enable the Red Hat Quay API, and use API endpoints, Swagger, and automation workflows. Before you call authenticated endpoints, create an OAuth 2 access token; see "Manage OAuth access tokens for the Red Hat Quay API".
Introduction to Project Quay OAuth 2.0 tokens
OAuth 2.0 tokens provide secure, standards-based access to the Project Quay API. You can use OAuth 2 access tokens, robot account tokens, and OCI referrers access tokens to authenticate API operations.
Compared to more traditional API tokens, Project Quay OAuth 2 tokens offer the following enhancements:
-
Standards-based security that adheres to the OAuth 2.0 protocol.
-
Revocable access by deleting the application in which the OAuth 2 token exists.
-
Fine-grained access control so that Project Quay administrators can assign specific permissions to tokens.
-
Delegated access so that third-party applications and services can act on behalf of a user.
-
Compatibility with other services, platforms, and integrations.
Project Quay primarily supports two types of tokens: OAuth 2 access tokens and robot account tokens. A third token type, an OCI referrers access token, that is required to list OCI referrers of a manifest under a repository, is also available when warranted.
You can manage organization OAuth 2 access tokens from the API Access Tokens page of an OAuth application. You can create named tokens with optional expiration, review metadata such as scopes and last-used time, and revoke individual tokens without deleting the parent application.
Using the Project Quay API
To invoke Project Quay API endpoints from the CLI, you can pass an OAuth 2 access token in a curl request. You can use GET, PUT, POST, or DELETE methods against the documented endpoints.
After you have created an application and generated an OAuth 2 access token with the desired settings, you can pass in the access token to GET, PUT, POST, or DELETE settings by using the API from the CLI. Generally, a Project Quay API command looks similar to the following example:
$ curl -X GET -H "Authorization: Bearer <your_access_token>" \
https://<quay-server.example.com>/api/v1/<example>/<endpoint>/
where:
<your_access_token>-
Specifies the OAuth 2 access token that was generated through the Project Quay UI.
https://<quay-server.example.com>/api/v1/<example>/<endpoint>/-
Specifies your Project Quay deployment and the desired API endpoint.
All Project Quay APIs are documented in the Application Programming Interface (API) chapter. Understanding how they are documented is crucial to successful invocation. Take, for example, the following entry for the createAppToken API endpoint:
*createAppToken*
Create a new app specific token for user.
*POST /api/v1/user/apptoken*
**Authorizations: **oauth2_implicit (**user:admin**)
Request body schema (application/json)
*Path parameters*
Name: **title**
Description: Friendly name to help identify the token.
Schema: string
*Responses*
|HTTP Code|Description |Schema
|201 |Successful creation |
|400 |Bad Request |<<_apierror,ApiError>>
|401 |Session required |<<_apierror,ApiError>>
|403 |Unauthorized access |<<_apierror,ApiError>>
|404 |Not found |<<_apierror,ApiError>>
|===
where:
createAppToken-
Specifies the name of the API endpoint.
Create a new app specific token for user.-
Specifies a brief description of the API endpoint.
POST /api/v1/user/apptoken-
Specifies the API endpoint used for invocation.
Authorizations-
Specifies the authorizations required to use the API endpoint.
Path parameters-
Specifies the available paths to be used with the API endpoint. In this example,
titleis the only path to be used with thePOST /api/v1/user/apptokenendpoint. Responses-
Specifies the API responses for this endpoint.
Enabling browser-based API calls in Project Quay
To use Project Quay API access from a browser extension or Swagger UI, you can disable BROWSER_API_CALLS_XHR_ONLY in your config.yaml file.
By default, Project Quay accepts curl requests from the command line. However, if you want to enable API access from a browser extension such as Postman, or a browser interface such as Swagger, you must disable BROWSER_API_CALLS_XHR_ONLY in your config.yaml file.
-
In your Project Quay
config.yamlfile, setBROWSER_API_CALLS_XHR_ONLYtofalse. For example:# ... BROWSER_API_CALLS_XHR_ONLY: false # ... -
Restart your Project Quay deployment.
Accessing Project Quay Swagger UI
To explore and test Project Quay API endpoints interactively, you can run the Swagger UI container against your registry API discovery endpoint.
Project Quay administrators and users can interact with the API by using the Swagger UI, an interactive web interface that compiles executable commands. The Swagger UI can be launched as a container that points to your Project Quay instance’s API discovery endpoint (/api/v1/discovery). After deploying the container, you can access the Swagger UI, which loads the OpenAPI specification for Project Quay from the specified URL. Project Quay administrators and users can explore the available endpoints and their structure.
-
You have set
BROWSER_API_CALLS_XHR_ONLY: falsein yourconfig.yamlfile.
-
Enter the following command to deploy the Swagger UI container, pointing the URL to your Project Quay API discovery endpoint. For example:
$ podman run -p 8080:8080 -e SWAGGER_JSON_URL=<quay-server.example.com> docker.swagger.io/swaggerapi/swagger-uiExample output--- /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh 20-envsubst-on-templates.sh: Running envsubst on /etc/nginx/templates/default.conf.template to /etc/nginx/conf.d/default.conf /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh /docker-entrypoint.sh: Launching /docker-entrypoint.d/40-swagger-ui.sh /docker-entrypoint.sh: Configuration complete; ready for start up --- -
Navigate to the
localhostURL. In this example, the URL is http://localhost:8080/. -
Use the Swagger UI to test various API endpoints. For example, to create a new token for a user, you can click the POST /api/v1/user/apptoken endpoint → Try it out → Execute to generate an example
curlcommand.NoteCurrently, server responses cannot be generated. This is because the Swagger UI is not configured to accept bearer tokens. As a result, the following error is returned for each command:
{"error": "CSRF token was invalid or missing."}. As a workaround, you can copy this command into your terminal and manually add your bearer token, for example,-H 'Authorization: Bearer <bearer_token>'.
Automating Project Quay processes by using the API
To automate repetitive Project Quay tasks such as repository management or image pruning, you can call the API from scripts and schedule them with cron.
With the API, Project Quay administrators and users with access to the API can automate repetitive tasks such as repository management or image pruning.
The following example shows you how you might use a Python script and a cron job to automate the deletion of OAuth 2 applications except the administrator’s token. This might be useful if you want to ensure an application associated with an OAuth 2 access token is cycled after a certain period of time.
-
You have access to the Project Quay API, which entails having already created an OAuth 2 access token.
-
You have installed the Python
requestslibrary. -
You have enabled cron jobs on your machine.
-
You have created several organization applications, including one that you do not want to delete.
-
Create a Python script that executes an API command. The following example deletes organization applications by using the
DELETE /api/v1/organization/{orgname}/applications/{client_id}API endpoint.Create the following
example.pyfile:import requests # Hard-coded values API_BASE_URL = "http://<quay-server.example.com>/api/v1" ACCESS_TOKEN = "<access_token>" ORG_NAME = "<organization_name>" def get_all_organization_applications(): url = f"{API_BASE_URL}/organization/{ORG_NAME}/applications" headers = { "Authorization": f"Bearer {ACCESS_TOKEN}" } response = requests.get(url, headers=headers) if response.status_code == 200: try: applications = response.json() # Print the raw response for debugging print("Raw response:", applications) # Adjust parsing logic based on the response structure if isinstance(applications, dict) and 'applications' in applications: applications = applications['applications'] if isinstance(applications, list): print("Organization applications retrieved successfully:") for app in applications: # Updated key from 'title' to 'name' print(f"Name: {app['name']}, Client ID: {app['client_id']}") return applications else: print("Unexpected response format.") return [] except requests.exceptions.JSONDecodeError: print("Error decoding JSON response:", response.text) return [] else: print(f"Failed to retrieve applications. Status code: {response.status_code}, Response: {response.text}") return [] def delete_organization_application(client_id): url = f"{API_BASE_URL}/organization/{ORG_NAME}/applications/{client_id}" headers = { "Authorization": f"Bearer {ACCESS_TOKEN}" } response = requests.delete(url, headers=headers) if response.status_code == 204: print(f"Application {client_id} deleted successfully.") else: print(f"Failed to delete application {client_id}. Status code: {response.status_code}, Response: {response.text}") def main(): applications = get_all_organization_applications() for app in applications: if app['name'] != "<admin_token_app>": # Skip the "admin-token-app" delete_organization_application(app['client_id']) else: print(f"Skipping deletion of application: {app['name']}") # Execute the main function main()where:
import requests-
Specifies that the
requestslibrary is included in your Python code. API_BASE_URL-
Specifies the URL of your registry appended with
/api/v1. ACCESS_TOKEN-
Specifies your OAuth 2 access token.
ORG_NAME-
Specifies the organization that holds the application.
"<admin_token_app>"-
Specifies the name of the application token to remain.
-
Save the script as
prune_applications.py. -
Create a cron job that automatically runs the script:
-
Open the crontab editor by running the following command:
$ crontab -e -
In the editor, add the cron job for running the script. The following example runs the script once per month:
0 0 1 * * sudo python /path/to/prune_images.py >> /var/log/prune_images.log 2>&1
-
Discovering Project Quay API endpoints
To list available Project Quay API endpoints in Swagger format, you can call the discovery endpoint with an OAuth 2 access token.
-
You have created an OAuth 2 access token.
-
Enter the following
GET /api/v1/discoverycommand to list all of the API endpoints available in the Swagger API format:$ curl -X GET "https://<quay-server.example.com>/api/v1/discovery?query=true" \ -H "Authorization: Bearer <access_token>"Example output--- : "Manage the tags of a repository."}, {"name": "team", "description": "Create, list and manage an organization's teams."}, {"name": "trigger", "description": "Create, list and manage build triggers."}, {"name": "user", "description": "Manage the current user."}, {"name": "userfiles", "description": ""}]} ---
Obtaining Project Quay API error details
To retrieve details for a Project Quay API error type, you can call the error endpoint with an OAuth 2 access token and an error code.
-
You have created an OAuth 2 access token.
-
Obtain error details of the API by entering the
GET /api/v1/error/{error_type}endpoint. Note that you must include one of the following error codes:HTTP Code Description 200
Successful invocation
400
Bad Request
401
Session required
403
Unauthorized access
404
Not found
$ curl -X GET "https://<quay-server.example.com>/api/v1/error/<error_type>" \ -H "Authorization: Bearer <access_token>"Example outputcurl: (7) Failed to connect to quay-server.example.com port 443 after 0 ms: Couldn't connect to server
Manage OAuth access tokens for the Red Hat Quay API
Review OAuth 2 access token scopes and security, then create, reassign, revoke, and rotate organization OAuth 2 access tokens. After you have an OAuth 2 access token, you can create user application tokens for Docker, Podman, and other clients.
About OAuth 2 access tokens
OAuth 2 access tokens authenticate users to the Project Quay API for applications that require user identity verification. You create a token for an organization OAuth application and select scopes that authorize API actions.
|
Note
|
Although OAuth 2 tokens authorize actions on API endpoints based on the scopes that you define for the token, Project Quay role-based access control (RBAC) still governs access to the resources. You can create actions on a resource, for example a repository, when you have the proper role (Admin or Creator) for that namespace. This is true even if the API token was granted the |
You can create OAuth 2 access tokens by using the Project Quay UI or by using the organization application token API.
When you create an OAuth 2 token, you can select the following options:
-
Name. A user-defined identifier for the token.
-
Expiration. A lifetime for the token. Use short expirations for scripts and CI systems when practical. Use no expiration only for controlled bootstrap cases.
-
Scopes, which can include the following permissions:
-
Administer Organization. Administration of organizations, including creating robots, creating teams, adjusting team membership, and changing billing settings.
-
Administer Repositories. Administrator access to all repositories to which the granting user has access.
-
Create Repositories. Creation of repositories in namespaces where the granting user can create repositories.
-
View all visible repositories. Viewing and pulling all repositories visible to the granting user.
-
Read/Write to any accessible repositories. Viewing, pushing, and pulling to repositories where the granting user has write access.
-
Super User Access. Administration of the installation, including managing users and organizations from the superuser panel.
-
Administer User. Administration of your account, including creating robots and granting them repository permissions.
-
Read User Information. Reading user information such as username and email address.
-
The API Access Tokens page can show additional columns such as Created By, Expires, and Last Used so that you can audit tokens without deleting the parent application.
|
Important
|
The token secret is shown only when the token is created. Store it securely. Do not share token secrets through insecure channels. |
OAuth 2 access tokens are passed as a Bearer token in the Authorization header of an API call. The API is available from the /api/v1 endpoint of your Project Quay host. For example, https://<quay-server.example.com>/api/v1. You can connect to endpoints through your browser to GET, POST, DELETE, and PUT Project Quay settings by enabling the Swagger UI. Applications that make API calls and use OAuth tokens can access the API, which sends and receives data as JSON.
Organization application OAuth API tokens created through the UI support various expiration values, from 7 days to 10 years. Tokens created by using the organization application token API support custom expiration values in seconds. You can revoke tokens individually by using the API or by deleting the application in which they were created. Deleting an application revokes all tokens created within that application.
Token distributors should be mindful of the permissions that they grant when generating a token on behalf of a user, and should have absolute trust in a user before granting such permissions as Administer organization, Super User Access, and Administer User. Additionally, the access token is only revealed at the time of creation; they cannot be listed from the CLI, nor can they be found on the Project Quay UI. If an access token is lost or forgotten, a new token must be created; a token cannot be recovered.
In practice, Project Quay administrators can create a new OAuth application on the OAuth Applications page of their organization each time they want to create a new OAuth token for a user. This ensures that a single application is not responsible for all OAuth tokens. As a result, if a user’s token is compromised, the administrator can delete the application of the compromised token without disrupting other users whose tokens might be part of the same application.
Older tokens that you created with the previous Generate Token workflow continue to work. In the API Access Tokens list, legacy tokens might appear with a name such as Legacy Token. You can leave them in place, or replace them with named tokens that have explicit expiration policies and then revoke the legacy token.
|
Note
|
Deleting an OAuth application still deletes all tokens that belong to that application. Prefer revoking an individual token from the API Access Tokens page when you only need to invalidate one credential. |
Creating an OAuth 2 access token
To create an OAuth 2 access token for Project Quay API calls, you can generate a named token from an organization OAuth application in the UI.
-
You have logged in to Project Quay as an administrator.
-
You have created an organization.
-
On the Project Quay UI, select your organization.
-
In the navigation pane, click OAuth Applications.
-
Create an application if you do not already have one:
-
Click Create OAuth Application.
-
Enter an application name and any required application details, such as homepage URL, description, avatar e-mail, and redirect/callback URL.
-
Click Create application.
-
-
Click the name of your OAuth application.
-
Click API Access Tokens.
-
Click Generate New Token.
-
Configure the token:
-
Enter a Token name.
-
Set an expiration period, such as 10 years.
-
Optional: Click Assign another user to assign this OAuth token to another user. When prompted, select the desired user.
-
Select the permissions, or scopes, for the token. For example:
-
Administer Organization. This application can administer your organizations, including creating robots, creating teams, adjusting team membership, and changing billing settings. Grant this permission only when you have absolute trust in the requesting application.
-
Administer Repositories. This application has administrator access to all repositories to which the granting user has access.
-
Create Repositories. This application can create repositories in all namespaces where the granting user can create repositories.
-
View all visible repositories. This application can view and pull all repositories visible to the granting user.
-
Read/Write to any accessible repositories. This application can view, push, and pull to all repositories to which the granting user has write access.
-
Super User Access. This application can administer your installation, including managing users, managing organizations, and other features found in the superuser panel. Grant this permission only when you have absolute trust in the requesting application.
-
Administer User. This application can administer your account, including creating robots and granting them permissions to your repositories. Grant this permission only when you have absolute trust in the requesting application.
-
Read User Information. This application can read user information such as username and email address.
-
-
-
Click Generate token.
-
Review the requested permissions, then click Authorize Application. Confirm the authorization when prompted.
ImportantAssign only the scopes that the token holder needs. Treat Administer Organization, Super User Access, and Administer User as high-trust permissions.
-
Copy and store the access token secret.
ImportantThis is the only opportunity to copy the token secret. Project Quay does not show the full secret again after you leave the page.
-
Confirm that the new token appears on the API Access Tokens page for the application. The list can include the token name, creator, scopes, expiration, and last-used information when those columns are available.
-
Optional. Call an API endpoint with the token to confirm that it works. For example:
$ curl -X GET "https://<quay-server.example.com>/api/v1/user/" \ -H "Authorization: Bearer <access_token>"
Managing a user application by using the API
To create, list, or delete a user application token without sharing your password, you can use the Project Quay API. User application tokens work like encrypted username and password credentials for Docker, Podman, or other clients.
Project Quay users can create, list information about, and delete a user application that can be used as an alternative to using your password for Docker, Podman, or other service providers. User application tokens work like your username and password, but are encrypted and do not provide any information to third parties regarding who is accessing Project Quay.
|
Note
|
After creation by using the CLI, the user application token is listed under User Settings of the Project Quay UI. Note that this differs from an application token that is created under user settings, and should be considered a different application entirely. |
-
You have created an OAuth 2 access token.
-
Create a user application by entering the
POST /api/v1/user/apptokenAPI call:$ curl -X POST \ -H "Authorization: Bearer <access_token>" \ -H "Content-Type: application/json" \ -d '{ "title": "MyAppToken" }' \ "http://quay-server.example.com/api/v1/user/apptoken"Example output{"token": {"uuid": "6b5aa827-cee5-4fbe-a434-4b7b8a245ca7", "title": "MyAppToken", "last_accessed": null, "created": "Wed, 08 Jan 2025 19:32:48 -0000", "expiration": null, "token_code": "string"}} -
You can obtain information about your application, including when the application expires, by using the
GET /api/v1/user/apptokencommand. For example:$ curl -X GET \ -H "Authorization: Bearer <access_token>" \ "http://quay-server.example.com/api/v1/user/apptoken"Example output{"tokens": [{"uuid": "6b5aa827-cee5-4fbe-a434-4b7b8a245ca7", "title": "MyAppToken", "last_accessed": null, "created": "Wed, 08 Jan 2025 19:32:48 -0000", "expiration": null}], "only_expiring": null} -
You can obtain information about a specific user application by entering the
GET /api/v1/user/apptoken/{token_uuid}command:$ curl -X GET \ -H "Authorization: Bearer <access_token>" \ "http://quay-server.example.com/api/v1/user/apptoken/<token_uuid>"Example output{"token": {"uuid": "6b5aa827-cee5-4fbe-a434-4b7b8a245ca7", "title": "MyAppToken", "last_accessed": null, "created": "Wed, 08 Jan 2025 19:32:48 -0000", "expiration": null, "token_code": "string"}} -
You can delete or revoke a user application token by using the
DELETE /api/v1/user/apptoken/{token_uuid}endpoint:$ curl -X DELETE \ -H "Authorization: Bearer <access_token>" \ "http://quay-server.example.com/api/v1/user/apptoken/<token_uuid>"This command does not return output in the CLI. You can return a list of tokens by entering one of the aforementioned commands.
Reassigning an OAuth access token
To keep audit logs accurate when another user needs an OAuth API token, you can reassign token creation to that user from an organization OAuth application.
Organization administrators can assign OAuth API tokens to be created by other users with specific permissions. Audit logs then reflect the user who uses the token, even when that user does not have organization administrative permissions to create an OAuth API token.
|
Note
|
This procedure works only on the current Project Quay UI. The Project Quay v2 UI does not currently support this procedure. |
-
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
Adminteam role to use administrative API endpoints.
-
Optional. If not already, update your Project Quay
config.yamlfile to include theFEATURE_ASSIGN_OAUTH_TOKEN: truefield:# ... FEATURE_ASSIGN_OAUTH_TOKEN: true # ... -
Optional. Restart your Project Quay registry.
-
Log in to your Project Quay registry as an organization administrator.
-
Click the name of the organization in which you created the OAuth token.
-
In the navigation pane, click OAuth Applications.
-
Click the proper application name.
-
In the navigation pane, click API Access Tokens.
-
Click Generate New Token.
-
Click Assign another user and enter the name of the user who takes 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.
ImportantThe team role within an organization defines permission control 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
Adminteam 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 by using the
config.yamlfile 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
-
After reassigning an OAuth token, the assigned user must accept the token to receive the bearer token, which is required to use API endpoints. Ask the assigned user to log in to the Project Quay registry.
-
After the assigned user has logged in, ask them to click their username under Users and Organizations.
-
In the navigation pane, ask them to click External Logins And Applications.
-
Under Authorized Applications, ask them to 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. Ask them to save this bearer token, because it cannot be viewed again.
Revoking an OAuth 2 access token
To invalidate a compromised or unused OAuth 2 access token, you can revoke the token from the organization OAuth application in the Project Quay UI.
Because OAuth 2 access tokens are created through the OAuth application, they cannot be rotated or renewed. If a token is compromised, revoke it through the Project Quay UI.
-
You have created an OAuth 2 access token.
-
You have permission to manage the OAuth application that owns the token.
-
On the Project Quay UI, click the name of the organization that hosts the application.
-
In the navigation pane, click OAuth Applications.
-
Click the application name that holds the OAuth 2 token that you want to revoke.
-
Click API Access Tokens.
-
Click the menu kebab of the appropriate token and then click Revoke. Confirm that you want to revoke the token by clicking Revoke token.
-
Confirm that the token no longer appears as an active token on the API Access Tokens page.
Rotating a legacy OAuth 2 access token
To replace a legacy long-lived OAuth 2 access token, you can create a named token with an explicit expiration policy and then revoke the legacy token.
Existing legacy tokens continue to work for at least 10 years until you revoke them.
-
You have an organization OAuth application that already has a legacy token.
-
You can update any CI system, script, or client that currently uses the legacy token.
-
On the Project Quay UI, click Organization → OAuth Applications.
-
Click the application name.
-
Click API Access Tokens.
-
Identify the legacy token to replace. Legacy tokens do not have a user-defined name, do not show a creation date, and have an expiration date of 10 years from the date of creation.
-
Click Generate New Token.
-
Configure a replacement token:
-
Enter a Token name.
-
Set an expiration appropriate for the workload, for example 7 days or 10 years.
-
Select the scopes required by the client.
-
-
Click Generate Token, then click Authorize Application and confirm the authorization.
-
Copy the new token secret and store it securely.
-
Update the CI system, script, or client configuration to use the new token.
-
Verify that the client works with the new token.
-
Return to the OAuth Applications page and revoke the legacy token:
-
Click the application name that owns the legacy token.
-
Click the menu kebab icon for the legacy token.
-
Click Revoke. Confirm that you want to revoke the token by clicking Revoke token.
-
Manage robot account tokens for the Red Hat Quay API
Create and regenerate robot account tokens for CI/CD pull and push access without interactive user authentication.
Robot account tokens
Robot account tokens are persistent password-type credentials for Docker v2 registry access in Project Quay. You can use them for automation and continuous integration without interactive user authentication.
Robot account tokens are password-type credentials used to access a Project Quay registry by using normal Docker v2 endpoints. The UI labels these credentials as tokens because the password itself is encrypted.
By default, Project Quay robot account tokens do not expire and do not require user interaction, which makes robot accounts ideal for non-interactive use cases.
Robot account tokens are automatically generated at the time of a robot’s creation and are not user-specific; they are connected to the user and organization namespace where they are created. For example, a robot named project_tools+<robot_name> belongs to the project_tools namespace.
Robot account tokens provide access without needing a user’s personal credentials. How the robot account is configured, for example, with one of READ, WRITE, or ADMIN permissions, ultimately defines the actions that the robot account can take.
Because robot account tokens are persistent and do not expire by default, they are ideal for automated workflows that require consistent access to Project Quay without manual renewal. Despite this, you can regenerate robot account tokens by using the UI or by using the proper API endpoint from the CLI. To enhance the security of your Project Quay deployment, administrators should regularly refresh robot account tokens. With the keyless authentication with robot accounts feature, you can exchange robot account tokens for external OIDC tokens so that they last only one hour, which enhances the security of your registry.
When a namespace is deleted, or when the robot account itself is deleted, the tokens are garbage collected when the collector is scheduled to run.
Regenerating a robot account token by using the Project Quay UI
To replace a robot account credential from the Project Quay UI, you can regenerate the robot account token for an organization robot account.
-
You have logged into Project Quay.
-
Click the name of an organization.
-
In the navigation pane, click Robot accounts.
-
Click the name of your robot account, for example, testorg3+test.
-
Click Regenerate token in the popup box.
Regenerating a robot account token by using the Project Quay API
To replace a compromised or outdated robot account credential, you can regenerate a robot account token by using the Project Quay API for organization or user robots.
-
You have created an OAuth access token.
-
Enter the following command to regenerate a robot account token for an organization by using the
POST /api/v1/organization/{orgname}/robots/{robot_shortname}/regenerateendpoint:$ 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 by using the
POST /api/v1/user/robots/{robot_shortname}/regenerateendpoint:$ 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>"}
Manage OCI referrers OAuth access tokens for the Red Hat Quay API
Create OCI referrers OAuth access tokens to list OCI referrers of a manifest under a repository by using the Project Quay v2/auth endpoint.
OCI referrers OAuth access token
An OCI referrers OAuth access token lists OCI referrers of a manifest under a repository in Project Quay. You obtain the token through basic HTTP authentication against the v2/auth endpoint.
In some cases, depending on the features that your Project Quay deployment is configured to use, you might need an OCI referrers OAuth access token. OCI referrers OAuth access tokens list OCI referrers of a manifest under a repository, and use a curl command to make a GET request to the Project Quay v2/auth endpoint.
You obtain these tokens by using basic HTTP authentication, wherein the user provides a username and password encoded in Base64 to authenticate directly with the v2/auth API endpoint. As such, they are based directly on the user’s credentials and do not follow the same detailed authorization flow as OAuth 2, but still allow a user to authorize API requests.
OCI referrers OAuth access tokens do not offer scope-based permissions and do not expire. They are solely used to list OCI referrers of a manifest under a repository.
Creating an OCI referrers OAuth access token
To list OCI referrers of a manifest under a repository, you can create an OCI referrers OAuth access token by using basic authentication against the Project Quay v2/auth endpoint.
-
Update your
config.yamlfile to include theFEATURE_REFERRERS_API: truefield. For example:# ... FEATURE_REFERRERS_API: true # ... -
Enter the following command to Base64 encode your credentials:
$ echo -n '<username>:<password>' | base64Example outputabcdeWFkbWluOjE5ODlraWROZXQxIQ== -
Enter the following command to use the Base64-encoded string and modify the URL endpoint to your Project 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 | jqExample output{ "token": "<example_secret>" }
Automate organization and quota operations through the Red Hat Quay API
Automate organization management, quota limits, mirroring, and global messages by using the Red Hat Quay API. Organization procedures cover contact email, members, applications, and proxy cache configuration.
Managing current user options by using the Project Quay API
To retrieve account information or star and unstar repositories in Project Quay, you can use the user API endpoints with an OAuth access token.
-
You have created an OAuth access token.
-
Use the
GET /api/v1/user/endpoint to get user information for the authenticated user.$ curl -X GET "https://quay-server.example.com/api/v1/user/" \ -H "Authorization: Bearer <your_access_token>"Example output{"anonymous": false, "username": "quayadmin", "avatar": {"name": "quayadmin", "hash": "6d640d802fe23b93779b987c187a4b7a4d8fbcbd4febe7009bdff58d84498fba", "color": "#f7b6d2", "kind": "user"}, "can_create_repo": true, "is_me": true, "verified": true, "email": "test@gmil.com", "logins": [], "invoice_email": false, "invoice_email_address": null, "preferred_namespace": false, "tag_expiration_s": 1209600, "prompts": [], "company": null, "family_name": null, "given_name": null, "location": null, "is_free_account": true, "has_password_set": true, "quotas": [{"id": 4, "limit_bytes": 2199023255552, "limits": [{"id": 3, "type": "Reject", "limit_percent": 100}]}], "quota_report": {"quota_bytes": 2280675, "configured_quota": 2199023255552, "running_backfill": "complete", "backfill_status": "complete"}, "organizations": [{"name": "test", "avatar": {"name": "test", "hash": "a15d479002b20f211568fd4419e76686d2b88a4980a5b4c4bc10420776c5f6fe", "color": "#aec7e8", "kind": "org"}, "can_create_repo": true, "public": false, "is_org_admin": true, "preferred_namespace": false}, {"name": "sample", "avatar": {"name": "sample", "hash": "ba560c68f1d26e8c6b911ac9b5d10d513e7e43e576cc2baece1b8a46f36a29a5", "color": "#b5cf6b", "kind": "org"}, "can_create_repo": true, "public": false, "is_org_admin": true, "preferred_namespace": false}], "super_user": true} -
Use the
GET /api/v1/users/{username}endpoint to get user information for the specified user.$ curl -X GET "https://quay-server.example.com/api/v1/users/example_user" \ -H "Authorization: Bearer <your_access_token>"Example output{"anonymous": false, "username": "testuser", "avatar": {"name": "testuser", "hash": "f660ab912ec121d1b1e928a0bb4bc61b15f5ad44d5efdc4e1c92a25e99b8e44a", "color": "#6b6ecf", "kind": "user"}, "super_user": false} -
Use the
POST /api/v1/user/starredendpoint to star a repository:$ curl -X POST "https://quay-server.example.com/api/v1/user/starred" \ -H "Authorization: Bearer <your_access_token>" \ -H "Content-Type: application/json" \ -d '{ "namespace": "<namespace>", "repository": "<repository_name>" }'Example output{"namespace": "test", "repository": "testrepo"} -
Use the
GET /api/v1/user/starredendpoint to list all starred repositories:$ curl -X GET "https://quay-server.example.com/api/v1/user/starred?next_page=<next_page_token>" \ -H "Authorization: Bearer <your_access_token>"Example output{"repositories": [{"namespace": "test", "name": "testrepo", "description": "This repository is now under maintenance.", "is_public": true}]} -
Use the
DELETE /api/v1/user/starred/{repository}endpoint to delete a star from a repository:$ curl -X DELETE "https://quay-server.example.com/api/v1/user/starred/namespace/repository-name" \ -H "Authorization: Bearer <your_access_token>"This command does not return output in the CLI.
Managing global messages by using the API
To create, list, or delete global messages in Project Quay, you can use the messages API endpoints with an OAuth 2 access token.
-
You have created an OAuth 2 access token.
-
Create a message by using the
POST /api/v1/messageendpoint:$ curl -X POST "https://<quay-server.example.com>/api/v1/messages" \ -H "Authorization: Bearer <access_token>" \ -H "Content-Type: application/json" \ -d '{ "message": { "content": "Hi", "media_type": "text/plain", "severity": "info" } }'This command does not return output.
-
Use the
GET /api/v1/messagescommand to return the list of global messages:$ curl -X GET "https://<quay-server.example.com>/api/v1/messages" \ -H "Authorization: Bearer <access_token>"Example output{"messages": [{"uuid": "ecababd4-3451-4458-b5db-801684137444", "content": "Hi", "severity": "info", "media_type": "text/plain"}]} -
Delete the global message by using the
DELETE /api/v1/message/{uuid}endpoint:$ curl -X DELETE "https://<quay-server.example.com>/api/v1/message/<uuid>" \ -H "Authorization: Bearer <access_token>"This command does not return output.
Using the API to mirror a repository
To mirror an external repository into Project Quay, you can create and manage a repository mirror configuration through the API. You can also sync, cancel, or update the configuration.
-
You have set
FEATURE_REPO_MIRROR: truein yourconfig.yamlfile.
-
Create a new repository mirror configuration by using the
POST /api/v1/repository/{repository}/mirrorendpoint:$ curl -X POST "https://<quay-server.example.com>/api/v1/repository/<namespace>/<repo>/mirror" \ -H "Authorization: Bearer <access_token>" \ -H "Content-Type: application/json" \ -d '{ "is_enabled": <is_enabled>, "external_reference": "<external_reference>", "external_registry_username": "<external_registry_username>", "external_registry_password": "<external_registry_password>", "sync_start_date": "<sync_start_date>", "sync_interval": <sync_interval>, "robot_username": "<robot_username>", "skopeo_timeout_interval": 600, "root_rule": { "rule": "<rule>", "rule_type": "<rule_type>" } }' -
Return information about the mirror configuration by using the
GET /api/v1/repository/{repository}/mirrorendpoint:$ curl -X GET "https://<quay-server.example.com>/api/v1/repository/<namespace>/<repo>/mirror" \ -H "Authorization: Bearer <access_token>"Example output{"is_enabled": true, "mirror_type": "PULL", "external_reference": "https://quay.io/repository/argoproj/argocd", "external_registry_username": null, "external_registry_config": {}, "sync_interval": 86400, "sync_start_date": "2025-01-15T12:00:00Z", "sync_expiration_date": null, "sync_retries_remaining": 3, "sync_status": "NEVER_RUN", "root_rule": {"rule_kind": "tag_glob_csv", "rule_value": ["*.latest*"]}, "robot_username": "quayadmin+mirror_robot"} -
Sync the repositories by using the
POST /api/v1/repository/{repository}/mirror/sync-nowendpoint. For example:$ curl -X POST "https://<quay-server.example.com>/api/v1/repository/<namespace>/<repo>/mirror/sync-now" \ -H "Authorization: Bearer <access_token>"This command does not return output in the CLI.
-
Cancel the sync with the
POST /api/v1/repository/{repository}/mirror/sync-cancelendpoint. For example:$ curl -X POST "https://<quay-server.example.com>/api/v1/repository/<namespace>/<repo>/mirror/sync-cancel" \ -H "Authorization: Bearer <access_token>"This command does not return output in the CLI.
-
After creating a mirror configuration, make changes with the
PUT /api/v1/repository/{repository}/mirrorcommand. For example, you might choose to disable automatic synchronizations:$ curl -X PUT "https://<quay-server.example.com>/api/v1/repository/<namespace>/<repo>/mirror" \ -H "Authorization: Bearer <access_token>" \ -H "Content-Type: application/json" \ -d '{ "is_enabled": <false>, "external_reference": "<external_reference>", "external_registry_username": "<external_registry_username>", "external_registry_password": "<external_registry_password>", "sync_start_date": "<sync_start_date>", "sync_interval": <sync_interval>, "robot_username": "<robot_username>", "skopeo_timeout_interval": 600, "root_rule": { "rule": "<rule>", "rule_type": "<rule_type>" } }'Where:
"is_enabled": <false>-
Disables automatic synchronization.
Establishing quota with the Project Quay API
Quota policies in Project Quay set storage limits for organizations and users so that you can control registry capacity. You can create, view, update, and delete quota settings through the API.
Managing organization quota with the Project Quay API
To manage storage quota for an organization in Project Quay, you can use the organization quota API endpoints. You can check, create, change, or delete quota limitations.
When an organization is first created, it does not have an established quota.
-
You have generated an OAuth access token.
-
To set a quota for an organization, use the
POST /api/v1/organization/{orgname}/quotaendpoint:$ curl -X POST "https://<quay-server.example.com>/api/v1/organization/<orgname>/quota" \ -H "Authorization: Bearer <access_token>" \ -H "Content-Type: application/json" \ -d '{ "limit_bytes": 10737418240, "limits": "10 Gi" }'Example output"Created" -
Use the
GET /api/v1/organization/{orgname}/quotacommand to return information about the policy, including the ID number, which is required for other organization quota endpoints. For example:$ 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 | jqExample output[{"id": 1, "limit_bytes": 10737418240, "limit": "10.0 GiB", "default_config": false, "limits": [], "default_config_exists": false}]After you obtain the ID number, you can use the
GET /api/v1/organization/{orgname}/quota/{quota_id}command to list the quota policy. For example:$ curl -X GET "https://<quay-server.example.com>/api/v1/organization/<orgname>/quota/<quota_id>" \ -H "Authorization: Bearer <access_token>"Example output{"id": 1, "limit_bytes": 10737418240, "limit": "10.0 GiB", "default_config": false, "limits": [], "default_config_exists": false} -
Use the
PUT /api/v1/organization/{orgname}/quota/{quota_id}command to modify the existing quota limitation. Note that this requires the policy ID. For example:$ curl -X PUT "https://<quay-server.example.com>/api/v1/organization/<orgname>/quota/<quota_id>" \ -H "Authorization: Bearer <access_token>" \ -H "Content-Type: application/json" \ -d '{ "limit_bytes": <limit_in_bytes> }'Example output{"id": 1, "limit_bytes": 21474836480, "limit": "20.0 GiB", "default_config": false, "limits": [], "default_config_exists": false} -
Delete an organization’s quota with the
DELETE /api/v1/organization/{orgname}/quota/{quota_id}command. For example:$ curl -X DELETE "https://<quay-server.example.com>/api/v1/organization/<orgname>/quota/<quota_id>" \ -H "Authorization: Bearer <access_token>"This command does not return output.
Setting quota limits for an organization by using the Project Quay API
To return a warning or deny image pushes when an organization exceeds its quota in Project Quay, you can create, list, update, and delete organization quota limits through the API.
-
Use the
POST /api/v1/organization/{orgname}/quota/{quota_id}/limitcommand to create a quota policy that rejects images if they exceed the allotted quota. For example:$ curl -X POST "https://<quay-server.example.com>/api/v1/organization/<orgname>/quota/<quota_id>/limit" \ -H "Authorization: Bearer <access_token>" \ -H "Content-Type: application/json" \ -d '{ "limit_bytes": 21474836480, "type": "Reject", "threshold_percent": 90 }'where:
type-
Specifies one of
RejectorWarning. threshold_percent-
Specifies the quota threshold, in percent of quota.
Example output"Created"
-
Use the
GET /api/v1/organization/{orgname}/quota/{quota_id}/limitcommand to obtain the ID of the quota limit. For example:$ curl -X GET "https://<quay-server.example.com>/api/v1/organization/<orgname>/quota/<quota_id>/limit" \ -H "Authorization: Bearer <access_token>"Example output[{"id": 2, "type": "Reject", "limit_percent": 90}] -
Update the policy with the
PUT /api/v1/organization/{orgname}/quota/{quota_id}/limit/{limit_id}endpoint. For example:$ curl -X PUT "https://<quay-server.example.com>/api/v1/organization/<orgname>/quota/<quota_id>/limit/<limit_id>" \ -H "Authorization: Bearer <access_token>" \ -H "Content-Type: application/json" \ -d '{ "type": "<type>", "threshold_percent": <threshold_percent> }'Example output{"id": 3, "limit_bytes": 10737418240, "limit": "10.0 GiB", "default_config": false, "limits": [{"id": 2, "type": "Warning", "limit_percent": 80}], "default_config_exists": false} -
Delete the quota limit with the
DELETE /api/v1/organization/{orgname}/quota/{quota_id}/limit/{limit_id}endpoint:$ curl -X DELETE "https://<quay-server.example.com>/api/v1/organization/<orgname>/quota/<quota_id>/limit/<limit_id>" \ -H "Authorization: Bearer <access_token>"This command does not return output.
Obtaining quota limits for the user with the Project Quay API
To view storage quota and limit policies for the logged-in user in Project Quay, you can call the user quota API endpoints.
Quota limits for users must be set on the Project Quay UI. The following APIs return the quota limits for the user that is logged in.
-
Use the
GET /api/v1/user/quotacommand to return information about the quota limitations:$ curl -X GET "https://<quay-server.example.com>/api/v1/user/quota" \ -H "Authorization: Bearer <access_token>"Example output[{"id": 4, "limit_bytes": 2199023255552, "limit": "2.0 TiB", "default_config": false, "limits": [], "default_config_exists": false}] -
After you have received the quota ID, pass it in with the
GET /api/v1/user/quota/{quota_id}endpoint to return information about the limitation:$ curl -X GET "https://<quay-server.example.com>/api/v1/user/quota/{quota_id}" \ -H "Authorization: Bearer <access_token>"Example output{"id": 4, "limit_bytes": 2199023255552, "limit": "2.0 TiB", "default_config": false, "limits": [], "default_config_exists": false} -
View the limitations by using the
GET /api/v1/user/quota/{quota_id}/limitendpoint. For example:$ curl -X GET "https://<quay-server.example.com>/api/v1/user/quota/{quota_id}/limit" \ -H "Authorization: Bearer <access_token>"Example output[{"id": 3, "type": "Reject", "limit_percent": 100}] -
Return additional information about the entire policy by using the
GET /api/v1/user/quota/{quota_id}/limit/{limit_id}endpoint:$ curl -X GET "https://<quay-server.example.com>/api/v1/user/quota/{quota_id}/limit/{limit_id}" \ -H "Authorization: Bearer <access_token>"Example output{"id": 4, "limit_bytes": 2199023255552, "limit": "2.0 TiB", "default_config": false, "limits": [{"id": 3, "type": "Reject", "limit_percent": 100}], "default_config_exists": false}
Managing organizations by using the API
To create and manage organizations in Project Quay, you can use organization API endpoints. You can view organization details, manage members, configure proxy caches, and delete organizations.
Managing organization contact email with the API
Use the organization contact email setting to configure where automated system alerts are sent for an organization. The contact_email field allows multiple organizations to share the same notification address without requiring separate user accounts for each team.
|
Note
|
In the Project Quay web UI, the |
The organization contact_email field has the following properties:
-
Receives namespace-level notifications (such as quota warnings and quota errors), billing and payment alerts (invoices, payment failures), and organization account recovery emails.
-
Can be shared across multiple organizations (useful for team distribution lists).
-
An optional setting; if left empty, notifications default to organization owners.
|
Note
|
When When you set |
|
Note
|
For |
-
You have Created an OAuth access token.
-
You have organization administrator permissions.
-
To retrieve the current email configured for an organization, use the following
GET /api/v1/organization/{orgname}endpoint:$ curl -X GET \ -H "Authorization: Bearer <bearer_token>" \ "https://<quay-server.example.com>/api/v1/organization/engineering"Example response{ "name": "engineering", "email": "team-notifications@example.com", "is_admin": true }When an email address is not configured, the API response returns
"email": "". -
To set the contact email when creating an organization, pass the
contact_emailfield by using thePOST /api/v1/organization/endpoint:$ curl -X POST \ -H "Authorization: Bearer <bearer_token>" \ -H "Content-Type: application/json" \ -d '{"name": "engineering", "contact_email": "team-alerts@example.com"}' \ "https://<quay-server.example.com>/api/v1/organization/" -
To update the contact email for an existing organization, use the
PUT /api/v1/organization/{orgname}endpoint:$ curl -X PUT \ -H "Authorization: Bearer <bearer_token>" \ -H "Content-Type: application/json" \ -d '{"contact_email": "new-team-alerts@example.com"}' \ "https://<quay-server.example.com>/api/v1/organization/engineering" -
To remove the contact email, set
contact_emailtonullor""(empty string). System notifications default to organization owners:$ curl -X PUT \ -H "Authorization: Bearer <bearer_token>" \ -H "Content-Type: application/json" \ -d '{"contact_email": ""}' \ "https://<quay-server.example.com>/api/v1/organization/engineering" -
Multiple organizations can share the same notification address (for example, a team distribution list):
$ curl -X PUT -H "Authorization: Bearer <token>" -H "Content-Type: application/json" \ -d '{"email": "devops-team@example.com"}' \ "https://<quay-server.example.com>/api/v1/organization/engineering"$ curl -X PUT -H "Authorization: Bearer <token>" -H "Content-Type: application/json" \ -d '{"email": "devops-team@example.com"}' \ "https://<quay-server.example.com>/api/v1/organization/qa-team"NoteWith the default setting (
FEATURE_ORG_SHARED_EMAIL: false), attempting to set an organization email to an address already registered to a user account returnsEmail has already been used: <email>.To allow the same email address to be shared across multiple organizations and with at most one user account, set
FEATURE_ORG_SHARED_EMAIL: truein yourconfig.yamlfile.
Retrieving organization member information by using the API
To list organization members and collaborators or remove a member in Project Quay, you can call the organization members API endpoints with an OAuth access token.
-
You have created an OAuth access token.
-
Use the
GET /api/v1/organization/{orgname}/membersendpoint to return a list of organization members:$ curl -X GET "https://<quay-server.example.com>/api/v1/organization/<orgname>/members" \ -H "Authorization: Bearer <access_token>"Example output{"members": [{"name": "quayadmin", "kind": "user", "avatar": {"name": "quayadmin", "hash": "6d640d802fe23b93779b987c187a4b7a4d8fbcbd4febe7009bdff58d84498fba", "color": "#f7b6d2", "kind": "user"}, "teams": [{"name": "owners", "avatar": {"name": "owners", "hash": "6f0e3a8c0eb46e8834b43b03374ece43a030621d92a7437beb48f871e90f8d90", "color": "#c7c7c7", "kind": "team"}}], "repositories": ["testrepo"]}, {"name": "testuser", "kind": "user", "avatar": {"name": "testuser", "hash": "f660ab912ec121d1b1e928a0bb4bc61b15f5ad44d5efdc4e1c92a25e99b8e44a", "color": "#6b6ecf", "kind": "user"}, "teams": [{"name": "owners", "avatar": {"name": "owners", "hash": "6f0e3a8c0eb46e8834b43b03374ece43a030621d92a7437beb48f871e90f8d90", "color": "#c7c7c7", "kind": "team"}}], "repositories": []}]} -
You can use the
GET /api/v1/organization/{orgname}/collaboratorsendpoint to return a list of organization collaborators:$ curl -X GET "https://<quay-server.example.com>/api/v1/organization/{orgname}/collaborators" \ -H "Authorization: Bearer <access_token>"Example output{"collaborators": [user-test]} -
Use the
GET /api/v1/organization/{orgname}/members/{membername}endpoint to obtain more specific information about a user:$ curl -X GET "https://<quay-server.example.com>/api/v1/organization/<orgname>/members/<membername>" \ -H "Authorization: Bearer <access_token>"Example output{"name": "quayadmin", "kind": "user", "avatar": {"name": "quayadmin", "hash": "6d640d802fe23b93779b987c187a4b7a4d8fbcbd4febe7009bdff58d84498fba", "color": "#f7b6d2", "kind": "user"}, "teams": [{"name": "owners", "avatar": {"name": "owners", "hash": "6f0e3a8c0eb46e8834b43b03374ece43a030621d92a7437beb48f871e90f8d90", "color": "#c7c7c7", "kind": "team"}}], "repositories": ["testrepo"]} -
Use the
DELETE /api/v1/organization/{orgname}/members/{membername}endpoint to delete a team member.$ curl -X DELETE "https://<quay-server.example.com>/api/v1/organization/<orgname>/members/<membername>" \ -H "Authorization: Bearer <access_token>"This command does not return output.
Managing an organization application by using the Project Quay API
To create, list, update, or delete organization applications in Project Quay, you can call the organization applications API endpoints with an OAuth access token.
|
Note
|
After you create an organization application in the UI, create and manage OAuth 2 access tokens from the application’s API Access Tokens page. |
-
You have created an OAuth access token.
-
Use the
POST /api/v1/organization/{orgname}/applicationsendpoint to create a new application for your organization. For example:$ curl -X POST "https://<quay-server.example.com>/api/v1/organization/<orgname>/applications" \ -H "Authorization: Bearer <access_token>" \ -H "Content-Type: application/json" \ -d '{ "name": "<app_name>", "redirect_uri": "<redirect_uri>", "application_uri": "<application_uri>", "description": "<app_description>", "avatar_email": "<avatar_email>" }'Example output{"name": "new-application", "description": "", "application_uri": "", "client_id": "E6GJSHOZMFBVNHTHNB53", "client_secret": "SANSWCWSGLVAUQ60L4Q4CEO3C1QAYGEXZK2VKJNI", "redirect_uri": "", "avatar_email": null} -
Use the
GET /api/v1/organization/{orgname}/applicationsendpoint to return a list of all organization applications. For example:$ curl -X GET "https://<quay-server.example.com>/api/v1/organization/<orgname>/applications" \ -H "Authorization: Bearer <access_token>"Example output{"applications": [{"name": "test", "description": "", "application_uri": "", "client_id": "MCJ61D8KQBFS2DXM56S2", "client_secret": "J5G7CCX5QCA8Q5XZLWGI7USJPSM4M5MQHJED46CF", "redirect_uri": "", "avatar_email": null}, {"name": "new-token", "description": "", "application_uri": "", "client_id": "IG58PX2REEY9O08IZFZE", "client_secret": "2LWTWO89KH26P2CO4TWFM7PGCX4V4SUZES2CIZMR", "redirect_uri": "", "avatar_email": null}, {"name": "second-token", "description": "", "application_uri": "", "client_id": "6XBK7QY7ACSCN5XBM3GS", "client_secret": "AVKBOUXTFO3MXBBK5UJD5QCQRN2FWL3O0XPZZT78", "redirect_uri": "", "avatar_email": null}, {"name": "new-application", "description": "", "application_uri": "", "client_id": "E6GJSHOZMFBVNHTHNB53", "client_secret": "SANSWCWSGLVAUQ60L4Q4CEO3C1QAYGEXZK2VKJNI", "redirect_uri": "", "avatar_email": null}]}You can also return applications for a specific client by using the
GET /api/v1/organization/{orgname}/applications/{client_id}endpoint. For example:$ curl -X GET "https://<quay-server.example.com>/api/v1/organization/<orgname>/applications/<client_id>" \ -H "Authorization: Bearer <access_token>"Example output{"name": "test", "description": "", "application_uri": "", "client_id": "MCJ61D8KQBFS2DXM56S2", "client_secret": "J5G7CCX5QCA8Q5XZLWGI7USJPSM4M5MQHJED46CF", "redirect_uri": "", "avatar_email": null} -
After creation, you can update organization applications, for example to add a redirect URI or a new description, by using the
PUT /api/v1/organization/{orgname}/applications/{client_id}endpoint:$ curl -X PUT "https://quay-server.example.com/api/v1/organization/test/applications/12345" \ -H "Authorization: Bearer <access_token>" \ -H "Content-Type: application/json" \ -d '{ "name": "Updated Application Name", "redirect_uri": "https://example.com/oauth/callback", "application_uri": "https://example.com", "description": "Updated description for the application", "avatar_email": "avatar@example.com" }' -
After creation, you can return application information by using the
GET /api/v1/app/{client_id}endpoint:$ curl -X GET "https://<quay-server.example.com>/api/v1/app/<client_id>" \ -H "Authorization: Bearer <access_token>"Example output{"name": "new-application3", "description": "", "uri": "", "avatar": {"name": "new-application3", "hash": "a15d479002b20f211568fd4419e76686d2b88a4980a5b4c4bc10420776c5f6fe", "color": "#aec7e8", "kind": "app"}, "organization": {"name": "test", "email": "new-contact@test-org.com", "avatar": {"name": "test", "hash": "a15d479002b20f211568fd4419e76686d2b88a4980a5b4c4bc10420776c5f6fe", "color": "#aec7e8", "kind": "user"}, "is_admin": true, "is_member": true, "teams": {}, "ordered_teams": [], "invoice_email": true, "invoice_email_address": "billing@test-org.com", "tag_expiration_s": 1209600, "is_free_account": true, "quotas": [{"id": 2, "limit_bytes": 10737418240, "limits": [{"id": 1, "type": "Reject", "limit_percent": 90}]}], "quota_report": {"quota_bytes": 0, "configured_quota": 10737418240, "running_backfill": "complete", "backfill_status": "complete"}}} -
You can delete organization applications with the
DELETE /api/v1/organization/{orgname}/applications/{client_id}endpoint. For example:$ curl -X DELETE "https://<quay-server.example.com>/api/v1/organization/{orgname}/applications/{client_id}" \ -H "Authorization: Bearer <access_token>"This command does not return output.
Configuring a proxy cache for an organization by using the Project Quay API
To create, validate, view, or delete a proxy cache configuration for an organization in Project Quay, you can call the organization proxycache API endpoints with an OAuth access token.
-
You have created an OAuth access token.
-
Use the
POST /api/v1/organization/{orgname}/proxycacheendpoint to create a proxy cache configuration for the organization.$ curl -X POST "https://<quay-server.example.com>/api/v1/organization/<orgname>/proxycache" \ -H "Authorization: Bearer <access_token>" \ -H "Content-Type: application/json" \ -d '{ "upstream_registry": "<upstream_registry>" "upstream_registry_username": "your_robot_account_username" "upstream_registry_password": "your_robot_account_password" }' -
Use the
POST /api/v1/organization/{orgname}/validateproxycacheendpoint to validate the proxy configuration:$ curl -X POST "https://<quay-server.example.com>/api/v1/organization/{orgname}/validateproxycache" \ -H "Authorization: Bearer <access_token>" \ -H "Content-Type: application/json" \ -d '{ "upstream_registry": "<upstream_registry>" "upstream_registry_username": "your_robot_account_username" "upstream_registry_password": "your_robot_account_password" }' -
Use the
GET /api/v1/organization/{orgname}/proxycacheendpoint to obtain information about the proxy cache. For example:$ curl -X GET "https://<quay-server.example.com>/api/v1/organization/{orgname}/proxycache" \ -H "Authorization: Bearer <access_token>"Example output{"upstream_registry": "quay.io", "expiration_s": 86400, "insecure": false} -
Use the
DELETE /api/v1/organization/{orgname}/proxycacheendpoint to delete the proxy cache configuration:$ curl -X DELETE "https://<quay-server.example.com>/api/v1/organization/{orgname}/proxycache" \ -H "Authorization: Bearer <access_token>"Example output"Deleted"
Automate repository and robot operations through the Red Hat Quay API
Automate repository permissions, auto-prune policies, and robot operations by using the Red Hat Quay API.
Managing repository permissions by using the Project Quay API
To create, view, and delete user and team access on a repository in Project Quay, you can manage repository permissions through the API.
Managing user permissions by using the Project Quay API
To view, change, or remove a user role on a repository in Project Quay, you can call the repository user permissions API endpoints with an OAuth access token.
-
You have created an OAuth access token.
-
Use the
GET /api/v1/repository/{repository}/permissions/user/{username}endpoint to obtain repository permissions for a user. For example:$ curl -X GET \ -H "Authorization: Bearer <access_token>" \ "https://quay-server.example.com/api/v1/repository/<repository_path>/permissions/user/<username>"Example output{"role": "read", "name": "testuser", "is_robot": false, "avatar": {"name": "testuser", "hash": "f660ab912ec121d1b1e928a0bb4bc61b15f5ad44d5efdc4e1c92a25e99b8e44a", "color": "#6b6ecf", "kind": "user"}, "is_org_member": false} -
Return all user permissions with the
GET /api/v1/repository/{repository}/permissions/user/endpoint:$ curl -X GET \ -H "Authorization: Bearer <access_token>" \ "https://quay-server.example.com/api/v1/repository/<namespace>/<repository>/permissions/user/"Example output{"permissions": {"quayadmin": {"role": "admin", "name": "quayadmin", "is_robot": false, "avatar": {"name": "quayadmin", "hash": "6d640d802fe23b93779b987c187a4b7a4d8fbcbd4febe7009bdff58d84498fba", "color": "#f7b6d2", "kind": "user"}, "is_org_member": true}, "test+example": {"role": "admin", "name": "test+example", "is_robot": true, "avatar": {"name": "test+example", "hash": "3b03050c26e900500437beee4f7f2a5855ca7e7c5eab4623a023ee613565a60e", "color": "#a1d99b", "kind": "robot"}, "is_org_member": true}}} -
Alternatively, use the
GET /api/v1/repository/{repository}/permissions/user/{username}/transitiveendpoint to return only the repository permission for the user:$ curl -X GET \ -H "Authorization: Bearer <access_token>" \ "https://quay-server.example.com/api/v1/repository/<repository_path>/permissions/user/<username>/transitive"Example output{"permissions": [{"role": "admin"}]} -
Change the user’s permissions, such as making the user an
admin, by using thePUT /api/v1/repository/{repository}/permissions/user/{username}endpoint. For example:$ curl -X PUT \ -H "Authorization: Bearer <access_token>" \ -H "Content-Type: application/json" \ -d '{"role": "<role>"}' \ "https://quay-server.example.com/api/v1/repository/<repository_path>/permissions/user/<username>"Example output{"role": "admin", "name": "testuser", "is_robot": false, "avatar": {"name": "testuser", "hash": "f660ab912ec121d1b1e928a0bb4bc61b15f5ad44d5efdc4e1c92a25e99b8e44a", "color": "#6b6ecf", "kind": "user"}, "is_org_member": false} -
Delete user permissions by using the
DELETE /api/v1/repository/{repository}/permissions/user/{username}endpoint. For example:$ curl -X DELETE \ -H "Authorization: Bearer <access_token>" \ "https://quay-server.example.com/api/v1/repository/<namespace>/<repository>/permissions/user/<username>"This command does not return output.
Managing team permissions by using the Project Quay API
To view, change, or remove a team role on a repository in Project Quay, you can call the repository team permissions API endpoints with an OAuth access token.
-
You have created an OAuth access token.
-
Return permissions for a specified team by using the
GET /api/v1/repository/{repository}/permissions/team/{teamname}endpoint:$ curl -X GET \ -H "Authorization: Bearer <access_token>" \ "https://quay-server.example.com/api/v1/repository/<namespace>/<repository>/permissions/team/<teamname>"Example output{"role": "write"} -
Return permissions for all teams with the
GET /api/v1/repository/{repository}/permissions/team/endpoint. For example:$ curl -X GET \ -H "Authorization: Bearer <access_token>" \ "https://quay-server.example.com/api/v1/repository/<namespace>/<repository>/permissions/team/"Example output{"permissions": {"ironmanteam": {"role": "read", "name": "ironmanteam", "avatar": {"name": "ironmanteam", "hash": "8045b2361613622183e87f33a7bfc54e100a41bca41094abb64320df29ef458d", "color": "#969696", "kind": "team"}}, "sillyteam": {"role": "read", "name": "sillyteam", "avatar": {"name": "sillyteam", "hash": "f275d39bdee2766d2404e2c6dbff28fe290969242e9fcf1ffb2cde36b83448ff", "color": "#17becf", "kind": "team"}}}} -
Change permissions for a specified team by using the
PUT /api/v1/repository/{repository}/permissions/team/{teamname}command. For example:$ curl -X PUT \ -H "Authorization: Bearer <access_token>" \ -H "Content-Type: application/json" \ -d '{"role": "<role>"}' \ "https://quay-server.example.com/api/v1/repository/<namespace>/<repository>/permissions/team/<teamname>"Example output{"role": "admin", "name": "superteam", "avatar": {"name": "superteam", "hash": "48cb6d114200039fed5c601480653ae7371d5a8849521d4c3bf2418ea013fc0f", "color": "#9467bd", "kind": "team"}} -
Delete team permissions with the
DELETE /api/v1/repository/{repository}/permissions/team/{teamname}command. For example:$ curl -X DELETE \ -H "Authorization: Bearer <access_token>" \ "https://quay-server.example.com/api/v1/repository/<namespace>/<repository>/permissions/team/<teamname>"This command does not return output in the CLI.
Managing auto-prune policies by using the Project Quay API
To create, retrieve, update, and delete auto-prune policies for organizations, repositories, and users in Project Quay, you can use the auto-prune policy API endpoints.
Creating and configuring repositories
To create a repository and manage its visibility, details, and description in Project Quay, you can call the repository API endpoints with an OAuth access token.
-
You have created an OAuth access token.
-
Enter the following command to create a repository by using the
POST /api/v1/repositoryendpoint:$ 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"} -
You can list repositories with the
GET /api/v1/repositoryendpoint. For example:$ curl -X GET \ -H "Authorization: Bearer <ACCESS_TOKEN>" \ "https://quay-server.example.com/api/v1/repository?public=true&starred=false&namespace=<NAMESPACE>"Example output{"repositories": [{"namespace": "quayadmin", "name": "busybox", "description": null, "is_public": false, "kind": "image", "state": "MIRROR", "is_starred": false, "quota_report": {"quota_bytes": 2280675, "configured_quota": 2199023255552}}]} -
Change visibility from public to private with the
POST /api/v1/repository/{repository}/changevisibilityendpoint:$ curl -X POST \ -H "Authorization: Bearer <ACCESS_TOKEN>" \ -H "Content-Type: application/json" \ -d '{ "visibility": "private" }' \ "https://quay-server.example.com/api/v1/repository/<NAMESPACE>/<REPO_NAME>/changevisibility"Example output{"success": true} -
You can check the Project Quay UI, or you can enter the following
GET /api/v1/repository/{repository}command to return details about a 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} -
Update repository descriptions with the
PUT /api/v1/repository/{repository}endpoint:$ curl -X PUT \ -H "Authorization: Bearer <bearer_token>" \ -H "Content-Type: application/json" \ -d '{ "description": "This is an updated description for the repository." }' \ "https://quay-server.example.com/api/v1/repository/<NAMESPACE>/<REPOSITORY>"Example output{"success": true} -
Enter the following command to delete a repository by 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>"This command does not return output in the CLI.
Creating and configuring robot accounts by using the Project Quay API
To create, retrieve, update, and delete robot accounts for organizations and users in Project Quay, you can use the robot account API endpoints.
Creating a robot account by using the Project Quay API
To automate access to your repositories, you can create a robot account by using the Project Quay API. You can create robot accounts for an organization or for your own user account.
-
You have created an OAuth access token.
-
Enter the following command to create a new robot account for an organization by 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}
Obtaining robot account information by using the Project Quay API
To review robot account details and permissions for an organization or user in Project Quay, you can call the robot account API endpoints with an OAuth access token.
-
You have created an OAuth access token.
-
Use the
GET /api/v1/organization/{orgname}/robots/{robot_shortname}API endpoint to return information for a robot for an organization:$ curl -X GET \ -H "Authorization: Bearer <bearer_token>" \ "https://quay-server.example.com/api/v1/organization/<ORGNAME>/robots/<ROBOT_SHORTNAME>"Example output{"name": "test+example", "created": "Mon, 25 Nov 2024 16:25:16 -0000", "last_accessed": null, "description": "", "token": "string", "unstructured_metadata": {}} -
Use the
GET /api/v1/organization/{orgname}/robots/{robot_shortname}/permissionsendpoint to return the list of permissions for a specific organization robot:$ curl -X GET \ -H "Authorization: Bearer <bearer_token>" \ "https://quay-server.example.com/api/v1/organization/<ORGNAME>/robots/<ROBOT_SHORTNAME>/permissions"Example output{"permissions": [{"repository": {"name": "testrepo", "is_public": true}, "role": "admin"}]} -
Use the
GET /api/v1/user/robots/{robot_shortname}API endpoint to return the user’s robot with the specified name:$ curl -X GET \ -H "Authorization: Bearer <bearer_token>" \ "https://quay-server.example.com/api/v1/user/robots/<ROBOT_SHORTNAME>"Example output{"name": "quayadmin+mirror_robot", "created": "Wed, 15 Jan 2025 17:22:09 -0000", "last_accessed": null, "description": "", "token": "<token_example>", "unstructured_metadata": {}} -
Use the
GET /api/v1/user/robots/{robot_shortname}/permissionsAPI endpoint to return a list of permissions for the user robot:$ curl -X GET \ -H "Authorization: Bearer <bearer_token>" \ "https://quay-server.example.com/api/v1/user/robots/<ROBOT_SHORTNAME>/permissions"Example output{"permissions": [{"repository": {"name": "busybox", "is_public": false}, "role": "write"}]}
Deleting a robot account by using the Project Quay API
To remove a robot account that you no longer need, you can delete it by using the Project Quay API. You can delete robot accounts that belong to an organization or to your own user account.
-
You have created an OAuth access token.
-
Enter the following command to delete a robot account for an organization by 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 Project Quay UI, or you can enter the following
GET /api/v1/organization/{orgname}/robotscommand 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 Project 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"}
Automate tags and teams through the Red Hat Quay API
Automate tag management, team operations, and registry search by using the Red Hat Quay API.
Searching against registry context
To find repositories, entities, and other registry resources in Project Quay, you can use the search API endpoints with an OAuth access token.
-
You have created an OAuth access token.
-
Use the
GET /api/v1/find/repositoriesendpoint to get a list of apps and repositories that match the specified query:$ curl -X GET "https://quay-server.example.com/api/v1/find/repositories?query=<repo_name>&page=1&includeUsage=true" \ -H "Authorization: Bearer <bearer_token>"Example output{"results": [], "has_additional": false, "page": 2, "page_size": 10, "start_index": 10} -
Use the
GET /api/v1/find/allendpoint to get a list of entities and resources that match the specified query:$ curl -X GET "https://quay-server.example.com/api/v1/find/all?query=<mysearchterm>" \ -H "Authorization: Bearer <bearer_token>"Example output{"results": [{"kind": "repository", "title": "repo", "namespace": {"title": "user", "kind": "user", "avatar": {"name": "quayadmin", "hash": "6d640d802fe23b93779b987c187a4b7a4d8fbcbd4febe7009bdff58d84498fba", "color": "#f7b6d2", "kind": "user"}, "name": "quayadmin", "score": 1, "href": "/user/quayadmin"}, "name": "busybox", "description": null, "is_public": false, "score": 4.0, "href": "/repository/quayadmin/busybox"}]} -
Use the
GET /api/v1/entities/{prefix}endpoint to get a list of entities that match the specified prefix.$ curl -X GET "https://quay-server.example.com/api/v1/entities/<prefix>?includeOrgs=<true_or_false>&includeTeams=<true_or_false>&namespace=<namespace>" \ -H "Authorization: Bearer <bearer_token>"Example output{"results": [{"name": "quayadmin", "kind": "user", "is_robot": false, "avatar": {"name": "quayadmin", "hash": "6d640d802fe23b93779b987c187a4b7a4d8fbcbd4febe7009bdff58d84498fba", "color": "#f7b6d2", "kind": "user"}}]}
Managing tags with the Project Quay API
To change, restore, list, or delete repository tags in Project Quay, you can use the tag API endpoints with an OAuth access token.
-
You have created an OAuth access token.
-
Use the
PUT /api/v1/repository/{repository}/tag/{tag}endpoint to change which image a tag points to or create a new tag:$ curl -X PUT "https://quay-server.example.com/api/v1/repository/<namespace>/<repo_name>/tag/<tag_name>" \ -H "Authorization: Bearer <ACCESS_TOKEN>" \ -H "Content-Type: application/json" \ -d '{"manifest_digest": "<MANIFEST_DIGEST>"}'Example output"Updated" -
Use the
POST /api/v1/repository/{repository}/tag/{tag}/restoreendpoint to restore a repository tag back to a previous image in the repository:$ curl -X POST "https://quay-server.example.com/api/v1/repository/<namespace>/<repo_name>/tag/<tag_name>/restore" \ -H "Authorization: Bearer <your_access_token>" \ -H "Content-Type: application/json" \ -d '{"manifest_digest": "sha256:<your_manifest_digest>"}'Example output{} -
Use the
GET /api/v1/repository/{repository}/tag/endpoint to obtain a list of repository tags:$ curl -X GET "https://quay-server.example.com/api/v1/repository/<namespace>/<repo_name>/tag/" \ -H "Authorization: Bearer <your_access_token>" \ -H "Content-Type: application/json"Example output{"tags": [{"name": "test", "reversion": true, "start_ts": 1740496373, "manifest_digest": "sha256:d08334991a3dba62307016833083d6433f489ab0f7d36d0a4771a20b4569b2f6", "is_manifest_list": false, "size": 2280303, "last_modified": "Tue, 25 Feb 2025 15:12:53 -0000"}, {"name": "test", "reversion": false, "start_ts": 1740495442, "end_ts": 1740496373, "manifest_digest": "sha256:d08334991a3dba62307016833083d6433f489ab0f7d36d0a4771a20b4569b2f6", "is_manifest_list": false, "size": 2280303, "last_modified": "Tue, 25 Feb 2025 14:57:22 -0000", "expiration": "Tue, 25 Feb 2025 15:12:53 -0000"}, {"name": "test", "reversion": false, "start_ts": 1740495408, "end_ts": 1740495442, "manifest_digest": "sha256:d08334991a3dba62307016833083d6433f489ab0f7d36d0a4771a20b4569b2f6", "is_manifest_list": false, "size": 2280303, "last_modified": "Tue, 25 Feb 2025 14:56:48 -0000", "expiration": "Tue, 25 Feb 2025 14:57:22 -0000"}], "page": 1, "has_additional": false} -
Use the
DELETE /api/v1/repository/{repository}/tag/{tag}endpoint to delete a tag from a repository:$ curl -X DELETE "https://quay-server.example.com/api/v1/repository/<namespace>/<repo_name>/tag/<tag_name>" \ -H "Authorization: Bearer <your_access_token>"This command does not return output in the CLI.
Managing teams by using the API
Organization teams in Project Quay group users for shared repository access. You can manage teams and membership by using the API.
Managing team members and repository permissions by using the API
To add, invite, or remove members of an organization team in Project Quay, you can use the team member API endpoints with an OAuth access token.
-
You have created an OAuth access token.
-
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 return output in the CLI. To ensure that a member has been deleted, you can enter the
GET /api/v1/organization/{orgname}/team/{teamname}/memberscommand 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>"
Setting the role of a team within an organization by using the API
To view repository permissions for a team or set a team’s role in an Project Quay organization, you can use the organization team API endpoints with an OAuth access token.
-
You have created an OAuth access token.
-
Enter the following
GET /api/v1/organization/{orgname}/team/{teamname}/permissionscommand 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}
Deleting a team within an organization by using the API
To delete a team from an organization in Project Quay, you can use the organization team API endpoint with an OAuth access token.
-
You have created an OAuth access token.
-
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.
Build container images from Dockerfiles in Red Hat Quay
Build container images from Dockerfiles by using the Red Hat Quay UI or API, including starting builds and creating build triggers.
Container image builds
Project Quay can build container images from Dockerfiles on worker nodes. You can start builds manually or automatically from source-control events so that registry images stay aligned with your code.
Builds are supported on Red Hat Quay on OpenShift Container Platform and Kubernetes. A build manager coordinates build jobs. You can run builders on bare metal nodes or as virtual (unprivileged container) builders, depending on isolation needs and available infrastructure.
When you plan builds, decide whether Project Quay should own image builds in your pipeline or whether an external CI system should push finished images into the registry. If you use Project Quay builds, choose a builder strategy and confirm networking constraints for your cluster.
|
Note
|
Running builds directly in a container on bare metal does not provide the same isolation as virtual machines, but it still provides meaningful process isolation. |
Building container images
The Project Quay builds feature supports building Docker and Podman container images from Dockerfiles. You can create containerized applications by defining build contexts and using base images from public repositories.
supports the ability to build Docker and Podman container images. This functionality is valuable for developers and organizations who rely on container and container orchestration.
Build contexts
When building an image with Docker or Podman, a directory is specified to become the build context. This is true for both manual Builds and Build triggers, because the Build that is created by
is not different than running docker build or podman build on your local machine.
Build contexts are always specified in the subdirectory from the Build setup, and fallback to the root of the Build source if a directory is not specified.
When a build is triggered, Build workers clone the Git repository to the worker machine, and then enter the Build context before conducting a Build.
For Builds based on .tar archives, Build workers extract the archive and enter the Build context. For example:
example
├── .git
├── Dockerfile
├── file
└── subdir
└── Dockerfile
Imagine that the Extracted Build archive is the directory structure got a Github repository called example. If no subdirectory is specified in the Build trigger setup, or when manually starting the Build, the Build operates in the example directory.
If a subdirectory is specified in the Build trigger setup, for example, subdir, only the Dockerfile within it is visible to the Build. This means that you cannot use the ADD command in the Dockerfile to add file, because it is outside of the Build context.
Unlike Docker Hub, the Dockerfile is part of the Build context on
As a result, it must not appear in the .dockerignore file.
Starting a new build
Starting a build creates a container image from a Dockerfile in Project Quay. You can start builds manually by uploading a Dockerfile or automatically by using build triggers.
-
You have navigated to the Builds page of your repository.
-
On the Builds page, click Start New Build.
-
When prompted, click Upload Dockerfile to upload a Dockerfile or an archive that contains a Dockerfile at the root directory.
-
Click Start Build.
Note-
Currently, users cannot specify the Docker build context when manually starting a build.
-
Currently, BitBucket is unsupported on the Project Quay v2 UI.
-
-
You are redirected to the build, which can be viewed in real-time. Wait for the Dockerfile build to be completed and pushed.
-
Optional. you can click Download Logs to download the logs, or Copy Logs to copy the logs.
-
Click the back button to return to the Repository Builds page, where you can view the build history.

Creating a build trigger
To automate container image builds from your Git repositories, you can create a custom Git build trigger in Project Quay. Build triggers automatically build and push images when you push code to your Git repository.
The following steps can be replicated to create a build trigger using Github, Gitlab, or Bitbucket, however, you must configure the credentials for these services in your config.yaml file.
|
Note
|
|
-
Log in to your Project Quay registry.
-
In the navigation pane, click Repositories.
-
Click Create Repository.
-
Click the Builds tab.
-
On the Builds page, click Create Build Trigger.
-
Select the desired platform, for example, Github, Bitbucket, Gitlab, or use a custom Git repository. For this example, click Custom Git Repository Push.
-
Enter a custom Git repository name, for example,
git@github.com:<username>/<repo>.git. Then, click Next. -
When prompted, configure the tagging options by selecting one of, or both of, the following options:
-
Tag manifest with the branch or tag name. When selecting this option, the built manifest the name of the branch or tag for the git commit are tagged.
-
Add
latesttag if on default branch. When selecting this option, the built manifest with latest if the build occurred on the default branch for the repository are tagged.Optionally, you can add a custom tagging template. There are multiple tag templates that you can enter here, including using short SHA IDs, timestamps, author names, committer, and branch names from the commit as tags. For more information, see "Tag naming for build triggers".
After you have configured tagging, click Next.
-
-
When prompted, select the location of the Dockerfile to be built when the trigger is invoked. If the Dockerfile is located at the root of the git repository and named Dockerfile, enter /Dockerfile as the Dockerfile path. Then, click Next.
-
When prompted, select the context for the Docker build. If the Dockerfile is located at the root of the Git repository, enter
/as the build context directory. Then, click Next. -
Optional. Choose an optional robot account. This allows you to pull a private base image during the build process. If you know that a private base image is not used, you can skip this step.
-
Click Next. Check for any verification warnings. If necessary, fix the issues before clicking Finish.
-
You are alerted that the trigger has been successfully activated. Note that using this trigger requires the following actions:
-
You must give the following public key read access to the git repository.
-
You must set your repository to
POSTto the following URL to trigger a build.Save the SSH Public Key, then click Return to <organization_name>/<repository_name>. You are redirected to the Builds page of your repository.
-
-
On the Builds page, you now have a build trigger. For example:

After you have created a custom Git trigger, additional steps are required. Continue on to "Setting up a custom Git trigger".
If you are setting up a build trigger for Github, Gitlab, or Bitbucket, continue on to "Manually triggering a build".
Managing builds by using the Project Quay API
To list, activate, start, update, or delete build triggers in Project Quay, you can use the build trigger API endpoints with an OAuth access token.
-
You have created an OAuth access token.
-
Use the
GET /api/v1/repository/{repository}/trigger/endpoint to list the triggers for the specified repository:$ curl -X GET "https://quay-server.example.com/api/v1/repository/example_namespace/example_repo/trigger/" \ -H "Authorization: Bearer <your_access_token>"Example output{"triggers": [{"id": "32ca5eae-a29f-46c7-8f44-3221ca417c92", "service": "custom-git", "is_active": false, "build_source": null, "repository_url": null, "config": {}, "can_invoke": true, "enabled": true, "disabled_reason": null}]} -
Use the
POST /api/v1/repository/{repository}/trigger/{trigger_uuid}/activateendpoint to activate the specified build trigger.$ curl -X POST "https://quay-server.example.com/api/v1/repository/example_namespace/example_repo/trigger/example-trigger-uuid/activate" \ -H "Authorization: Bearer <your_access_token>" \ -H "Content-Type: application/json" \ -d '{ "config": { "branch": "main" }, "pull_robot": "example+robot" }' -
Use the
POST /api/v1/repository/{repository}/trigger/{trigger_uuid}/startendpoint to manually start the build from the specified trigger:$ curl -X POST "https://quay-server.example.com/api/v1/repository/example_namespace/example_repo/trigger/example-trigger-uuid/start" \ -H "Authorization: Bearer <your_access_token>" \ -H "Content-Type: application/json" \ -d '{ "branch_name": "main", "commit_sha": "abcdef1234567890", "refs": "refs/heads/main" }' -
Use the
GET /api/v1/repository/{repository}/trigger/{trigger_uuid}/buildsendpoint to list the builds started by the specified trigger:$ curl -X GET "https://quay-server.example.com/api/v1/repository/example_namespace/example_repo/trigger/example-trigger-uuid/builds?limit=10" \ -H "Authorization: Bearer <your_access_token>" -
Use the
GET /api/v1/repository/{repository}/trigger/{trigger_uuid}endpoint to get information for the specified build trigger:$ curl -X GET "https://quay-server.example.com/api/v1/repository/example_namespace/example_repo/trigger/example-trigger-uuid" \ -H "Authorization: Bearer <your_access_token>" -
Use the
PUT /api/v1/repository/{repository}/trigger/{trigger_uuid}endpoint to update the specified build trigger:$ curl -X PUT "https://quay-server.example.com/api/v1/repository/example_namespace/example_repo/trigger/example-trigger-uuid" \ -H "Authorization: Bearer <your_access_token>" \ -H "Content-Type: application/json" \ -d '{"enabled": true}' -
Use the
DELETE /api/v1/repository/{repository}/trigger/{trigger_uuid}endpoint to delete the specified build trigger:$ curl -X DELETE "https://quay-server.example.com/api/v1/repository/example_namespace/example_repo/trigger/example-trigger-uuid" \ -H "Authorization: Bearer <your_access_token>"
Configure build triggers for Red Hat Quay
Configure Git, webhook, and GitHub App build triggers, including credentials, SSH keys, and manual build starts.
Setting up a custom Git trigger
To complete the setup of your custom Git build trigger in Project Quay, you must provide read access to the SSH public key and configure a webhook endpoint. These steps enable your Git repository to automatically trigger builds when you push code.
These steps are only required if you are using a custom Git trigger.
Obtaining build trigger credentials
To configure your custom Git trigger, you can obtain the SSH public key and webhook endpoint URL from the Project Quay user interface. These credentials are available on the Builds page of your repository.
-
You have created a custom Git trigger.
-
On the Builds page of your repository, click the menu kebab for your custom Git trigger.
-
Click View Credentials.
-
Save the SSH Public Key and Webhook Endpoint URL.
The key and the URL are available by selecting View Credentials from the Settings, or gear icon.
SSH public key access
SSH public key access in Project Quay enables builder instances to clone Git repositories for custom build triggers. Install the SSH public key that Project Quay generates in your Git server configuration, either by adding it to the authorized_keys file or using Deploy Keys.
Depending on the Git server configuration, you can install the SSH public key that Project Quay generates for a custom Git trigger in several ways.
For example, the Getting Git on a Server documentation describes how to configure a Git server on a Linux-based machine with a focus on managing repositories and access control through SSH. In this procedure, a small server adds the keys to the $HOME/.ssh/authorize_keys folder, which provides access for builders to clone the repository.
For any Git repository management software that is not officially supported, the software usually provides a field to input the key, often labeled as Deploy Keys.
Webhook reference
The webhook reference provides the JSON payload format required to trigger builds in Project Quay. You must POST a JSON payload with commit, ref, and default_branch fields to the webhook URL to automatically start a build.
|
Note
|
This request requires a |
{
"commit": "1c002dd", // required
"ref": "refs/heads/master", // required
"default_branch": "master", // required
"commit_info": { // optional
"url": "gitsoftware.com/repository/commits/1234567", // required
"message": "initial commit", // required
"date": "timestamp", // required
"author": { // optional
"username": "user", // required
"avatar_url": "gravatar.com/user.png", // required
"url": "gitsoftware.com/users/user" // required
},
"committer": { // optional
"username": "user", // required
"avatar_url": "gravatar.com/user.png", // required
"url": "gitsoftware.com/users/user" // required
}
}
}
This can typically be accomplished with a post-receive Git hook, however it does depend on your server setup.
Tag naming for build triggers
Tag naming for build triggers in Project Quay lets you create custom tags using templates that include commit information such as SHA, branch name, author, and date. You can use these templates to automatically tag your built images with meaningful identifiers based on the Git commit that triggered the build.
One option is to include any string of characters assigned as a tag for each built image. Alternatively, you can use the following tag templates on the Configure Tagging section of the build trigger to tag images with information from each commit:

-
${commit}: Full SHA of the issued commit
-
${parsed_ref.branch}: Branch information (if available)
-
${parsed_ref.tag}: Tag information (if available)
-
${parsed_ref.remote}: The remote name
-
${commit_info.date}: Date when the commit was issued
-
${commit_info.author.username}: Username of the author of the commit
-
${commit_info.short_sha}: First 7 characters of the commit SHA
-
${committer.properties.username}: Username of the committer
This list is not complete, but does contain the most useful options for tagging purposes. You can find the complete tag template schema in the Project Quay source repository.
Skipping a source control-triggered build
You can skip source control-triggered builds in Project Quay by adding [skip build] or [build skip] to your commit message. This prevents the build system from automatically building images for commits that do not require new builds.
Manually triggering a build
Manual build triggering in Project Quay lets you start builds on demand without waiting for automatic triggers from source control. You can manually trigger builds from the Builds page by selecting a build trigger and specifying a commit ID.
-
On the Builds page, Start new build.
-
When prompted, select Invoke Build Trigger.
-
Click Run Trigger Now to manually start the process.
-
Enter a commit ID from which to initiate the build, for example,
1c002dd.After the build starts, you can see the build ID on the Repository Builds page.
Creating an OAuth application in GitHub
To enable GitHub integration for automated builds in Project Quay, you can create an OAuth application in GitHub. This allows Project Quay to access GitHub repositories and trigger container image builds when commits or pull requests are made.
-
Log into GitHub Enterprise.
-
In the navigation pane, select your username → Your organizations.
-
In the navigation pane, select Applications → Developer Settings.
-
In the navigation pane, click OAuth Apps → New OAuth App. You are navigated to the following page:

-
Enter a name for the application in the Application name textbox.
-
In the Homepage URL textbox, enter your Project Quay URL.
NoteIf you are using public GitHub, the Homepage URL entered must be accessible by your users. It can still be an internal URL.
-
In the Authorization callback URL, enter https://<RED_HAT_QUAY_URL>/oauth2/github/callback.
-
Click Register application to save your settings.
-
When the new application’s summary is shown, record the Client ID and the Client Secret shown for the new application.
Work with OCI artifacts, Helm charts, and image signing
Push OCI artifacts and Helm charts, attach referrers to image tags, and sign content with Cosign in Red Hat Quay.
Open Container Initiative support
Project Quay supports Open Container Initiative image and distribution formats beyond Docker manifests. You can store Helm charts and other OCI media types in the registry.
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.
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. 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.
In addition to its expanded support for novel media types, ensures compatibility with Docker images, including V2_2 and V2_1 formats. This compatibility with Docker V2_2 and V2_1 images demonstrates commitment to providing a seamless experience for Docker users. Moreover, 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 media types, which can be used as examples for using other OCI media types.
Helm and OCI prerequisites
Before you use Helm charts with Project Quay, you can install a supported Helm client and trust registry certificates. OCI chart support requires a compatible Helm version.
Helm simplifies how applications are packaged and deployed. Helm uses a packaging format called Charts which contain the Kubernetes resources representing an application. supports Helm charts so long as they are a version supported by OCI.
You can download the most recent version of Helm from the Helm releases page.
Using Helm charts
To use Helm charts with Project Quay, you can push and pull OCI chart artifacts in the registry. You manage charts like other supported OCI media types.
Use the following example to download and push an etherpad chart from the Red Hat Community of Practice (CoP) repository.
-
You have logged into Quay.
-
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 ./etherpadExample output
Successfully packaged chart and saved it to: /home/user/linux-amd64/etherpad-0.0.4.tgz -
Log in to Project Quay using
helm registry login:$ helm registry login quay370.apps.quayperf370.perfscale.devcluster.openshift.com -
Push the chart to your repository using the
helm pushcommand:
Annotation parsing
Some OCI media types do not include labels for metadata such as expiration. You can use ORAS annotations with Project Quay to embed that metadata in artifacts.
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.
|
Important
|
If you pushed an image with |
-
You have downloaded the
orasCLI. -
You have pushed an OCI media artifact to your Project Quay repository.
-
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" \ --annotation "expiration = 2d" \ quay.io/<organization_name>/<repository>/<image_name>:<tag>where:
--annotation "quay.expires-after=2d"-
Specifies that the expiration time is set for 2 days, indicated by
2d. --annotation "expiration = 2d"-
Specifies that the expiration label is added.
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
-
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"}}
Attaching referrers to an image tag
To attach referrers to an image tag in Project Quay, you can use the oras CLI with OCI distribution spec 1.1 referrers schemas.
This 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.
-
You have downloaded the
orasCLI. -
You have access to an OCI media artifact.
-
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 Project 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
APIschema 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>.txtExample 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
tagschema:$ 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>.txtExample 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
tagschema:$ oras discover --insecure --distribution-spec v1.1-referrers-tag \ <quay-server.example.com>/<organization_name>/<repository>/<image_name>:<tag>Example outputquay.io/testorg3/myartifact-image@sha256:db440c57edfad40c682f9186ab1c1075707ce7a6fdda24a89cb8c10eaad424da └── doc/example └── sha256:2d4b54201c8b134711ab051389f5ba24c75c2e6b0f0ff157fce8ffdfe104f383 -
Enter the following command to discoverer referrers of the artifact using the
APIschema:$ oras discover --distribution-spec v1.1-referrers-api \ <quay-server.example.com>/<organization_name>/<repository>/<image_name>:<tag>Example outputDiscovered 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: truein yourconfig.yamlfile.-
Update your
config.yamlfile to include theFEATURE_REFERRERS_APIfield. For example:# ... FEATURE_REFERRERS_API: true # ... -
Enter the following command to Base64 encode your credentials:
$ echo -n '<username>:<password>' | base64Example outputabcdeWFkbWluOjE5ODlraWROZXQxIQ== -
Enter the following command to use the base64 encoded token and modify the URL endpoint to your Project 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 | jqExample output{ "token": "<example_token_output>..." }
-
-
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 | jqExample 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 }, ] }
Cosign OCI support
To sign and verify container images with Cosign in Project Quay, you can install Cosign and authenticate to the registry. Cosign uses ECDSA-P256 signatures and Simple Signing payloads.
Cosign is a tool that can be used to sign and verify container images. It uses the ECDSA-P256 signature algorithm and Red Hat’s Simple Signing payload format to create public keys that are stored in PKIX files. Private keys are stored as encrypted PEM files.
Cosign currently supports the following:
-
Hardware and KMS Signing
-
Bring-your-own PKI
-
OIDC PKI
-
Built-in binary transparency and timestamping service
Use the following procedure to directly install Cosign.
-
You have installed Go version 1.16 or later.
-
Enter the following
gocommand to directly install Cosign:$ go install github.com/sigstore/cosign/cmd/cosign@v1.0.0Example outputgo: downloading github.com/sigstore/cosign v1.0.0 go: downloading github.com/peterbourgon/ff/v3 v3.1.0 -
Generate a key-value pair for Cosign by entering the following command:
$ cosign generate-key-pairExample outputEnter password for private key: Enter again: Private key written to cosign.key Public key written to cosign.pub -
Sign the key-value pair by entering the following command:
$ cosign sign -key cosign.key <quay-server.example.com>/user1/busybox:testExample outputEnter password for private key: Pushing signature to: quay-server.example.com/user1/busybox:sha256-ff13b8f6f289b92ec2913fa57c5dd0a874c3a7f8f149aabee50e3d01546473e3.sigIf you experience an
UNAUTHORIZED: access to the requested resource is not authorizederror when signing, which occurs because Cosign relies on~./docker/config.jsonfor authorization, you might need to execute the following command:$ podman login --authfile ~/.docker/config.json <_quay-server.example.com_or_quay.io_>Example outputUsername: Password: Login Succeeded! -
Enter the following command to see the updated authorization configuration:
$ cat ~/.docker/config.json { "auths": { "quay-server.example.com": { "auth": "cXVheWFkbWluOnBhc3N3b3Jk" } }
Installing and using Cosign
To install Cosign and sign images in Project Quay, you can generate a key pair, sign a tag, and verify the signature. You authenticate to the registry with your existing credentials.
-
You have installed Go version 1.16 or later.
-
You have set
FEATURE_GENERAL_OCI_SUPPORTtoTruein yourconfig.yamlfile.
-
Enter the following
gocommand to directly install Cosign:$ go install github.com/sigstore/cosign/cmd/cosign@v1.0.0Example outputgo: downloading github.com/sigstore/cosign v1.0.0 go: downloading github.com/peterbourgon/ff/v3 v3.1.0 -
Generate a key-value pair for Cosign by entering the following command:
$ cosign generate-key-pairExample outputEnter password for private key: Enter again: Private key written to cosign.key Public key written to cosign.pub -
Sign the key-value pair by entering the following command:
$ cosign sign -key cosign.key <quay-server.example.com>/user1/busybox:testExample outputEnter password for private key: Pushing signature to: quay-server.example.com/user1/busybox:sha256-ff13b8f6f289b92ec2913fa57c5dd0a874c3a7f8f149aabee50e3d01546473e3.sigIf you experience an
UNAUTHORIZED: access to the requested resource is not authorizederror when signing, which occurs because Cosign relies on~./docker/config.jsonfor authorization, you might need to execute the following command:$ podman login --authfile ~/.docker/config.json <quay-server.example.com>Example outputUsername: Password: Login Succeeded! -
Enter the following command to see the updated authorization configuration:
$ cat ~/.docker/config.json { "auths": { "quay-server.example.com": { "auth": "cXVheWFkbWluOnBhc3N3b3Jk" } }