Chapter 7. Access management for Red Hat Quay As a Red Hat Quay user, you can create your own repositories and make them accessible to other users that are part of your instance. Alternatively, you can create an organization and associate a set of repositories directly to that organization, referred to as an organization repository . Organization repositories differ from basic repositories in that the organization is intended to set up shared repositories through groups of users. In Red Hat Quay, groups of users can be either Teams , or sets of users with the same permissions, or individual users . You can also allow access to user repositories and organization repositories by creating credentials associated with Robot Accounts. Robot Accounts make it easy for a variety of container clients, such as Docker or Podman, to access your repositories without requiring that the client have a Red Hat Quay user account. 7.1. Red Hat Quay teams overview In Red Hat Quay a team is a group of users with shared permissions, allowing for efficient management and collaboration on projects. Teams can help streamline access control and project management within organizations and repositories. They can be assigned designated permissions and help ensure that members have the appropriate level of access to their repositories based on their roles and responsibilities. 7.1.1. Creating a team by using the UI When you create a team for your organization you can select the team name, choose which repositories to make available to the team, and decide the level of access to the team. Use the following procedure to create a team for your organization repository. Prerequisites You have created an organization. Procedure On the Red Hat Quay v2 UI, click the name of an organization. On your organization's page, click Teams and membership . Click the Create new team box. In the Create team popup window, provide a name for your new team. Optional. Provide a description for your new team. Click Proceed . A new popup window appears. Optional. Add this team to a repository, and set the permissions to one of the following: None . Team members have no permission to the repository. Read . Team members can view and pull from the repository. Write . Team members can read (pull) from and write (push) to the repository. Admin . Full access to pull from, and push to, the repository, plus the ability to do administrative tasks associated with the repository. Optional. Add a team member or robot account. To add a team member, enter the name of their Red Hat Quay account. Review and finish the information, then click Review and Finish . The new team appears under the Teams and membership page . 7.1.2. Creating a team by using the API When you create a team for your organization with the API you can select the team name, choose which repositories to make available to the team, and decide the level of access to the team. Use the following procedure to create a team for your organization repository. Prerequisites You have created an organization. You have Created an OAuth access token . You have set BROWSER_API_CALLS_XHR_ONLY: false in your config.yaml file. Procedure Enter the following PUT /api/v1/organization/{orgname}/team/{teamname} command to create a team for your organization: USD curl -k -X PUT -H 'Accept: application/json' -H 'Content-Type: application/json' -H "Authorization: Bearer <bearer_token>" --data '{"role": "creator"}' https://<quay-server.example.com>/api/v1/organization/<organization_name>/team/<team_name> Example output {"name": "example_team", "description": "", "can_view": true, "role": "creator", "avatar": {"name": "example_team", "hash": "dec209fd7312a2284b689d4db3135e2846f27e0f40fa126776a0ce17366bc989", "color": "#e7ba52", "kind": "team"}, "new_team": true} 7.1.3. Managing a team by using the UI After you have created a team, you can use the UI to manage team members, set repository permissions, delete the team, or view more general information about the team. 7.1.3.1. Adding users to a team by using the UI With administrative privileges to an Organization, you can add users and robot accounts to a team. When you add a user, Red Hat Quay sends an email to that user. The user remains pending until they accept the invitation. Use the following procedure to add users or robot accounts to a team. Procedure On the Red Hat Quay landing page, click the name of your Organization. In the navigation pane, click Teams and Membership . Select the menu kebab of the team that you want to add users or robot accounts to. Then, click Manage team members . Click Add new member . In the textbox, enter information for one of the following: A username from an account on the registry. The email address for a user account on the registry. The name of a robot account. The name must be in the form of <organization_name>+<robot_name>. Note Robot Accounts are immediately added to the team. For user accounts, an invitation to join is mailed to the user. Until the user accepts that invitation, the user remains in the INVITED TO JOIN state. After the user accepts the email invitation to join the team, they move from the INVITED TO JOIN list to the MEMBERS list for the Organization. Click Add member . 7.1.3.2. Setting a team role by using the UI After you have created a team, you can set the role of that team within the Organization. Prerequisites You have created a team. Procedure On the Red Hat Quay landing page, click the name of your Organization. In the navigation pane, click Teams and Membership . Select the TEAM ROLE drop-down menu, as shown in the following figure: For the selected team, choose one of the following roles: Admin . Full administrative access to the organization, including the ability to create teams, add members, and set permissions. Member . Inherits all permissions set for the team. Creator . All member permissions, plus the ability to create new repositories. 7.1.3.2.1. Managing team members and repository permissions Use the following procedure to manage team members and set repository permissions. On the Teams and membership page of your organization, you can also manage team members and set repository permissions. Click the kebab menu, and select one of the following options: Manage Team Members . On this page, you can view all members, team members, robot accounts, or users who have been invited. You can also add a new team member by clicking Add new member . Set repository permissions . On this page, you can set the repository permissions to one of the following: None . Team members have no permission to the repository. Read . Team members can view and pull from the repository. Write . Team members can read (pull) from and write (push) to the repository. Admin . Full access to pull from, and push to, the repository, plus the ability to do administrative tasks associated with the repository. Delete . This popup windows allows you to delete the team by clicking Delete . 7.1.3.2.2. Viewing additional information about a team Use the following procedure to view general information about the team. Procedure On the Teams and membership page of your organization, you can click the one of the following options to reveal more information about teams, members, and collaborators: Team View . This menu shows all team names, the number of members, the number of repositories, and the role for each team. Members View . This menu shows all usernames of team members, the teams that they are part of, the repository permissions of the user. Collaborators View . This menu shows repository collaborators. Collaborators are users that do not belong to any team in the organization, but who have direct permissions on one or more repositories belonging to the organization. 7.1.4. Managing a team by using the Red Hat Quay API After you have created a team, you can use the API to obtain information about team permissions or team members, add, update, or delete team members (including by email), or delete an organization team. The following procedures show you how to how to manage a team using the Red Hat Quay API. 7.1.4.1. Managing team members and repository permissions by using the API Use the following procedures to add a member to a team (by direct invite or by email), or to remove a member from a team. Prerequisites You have Created an OAuth access token . You have set BROWSER_API_CALLS_XHR_ONLY: false in your config.yaml file. Procedure Enter the PUT /api/v1/organization/{orgname}/team/{teamname}/members/{membername} command to add or invite a member to an existing team: USD 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: USD curl -X DELETE \ -H "Authorization: Bearer <your_access_token>" \ "<quay-server.example.com>/api/v1/organization/<organization_name>/team/<team_name>/members/<member_name>" This command does not an output in the CLI. To ensure that a member has been deleted, you can enter the GET /api/v1/organization/{orgname}/team/{teamname}/members command and ensure that the member is not returned in the output. USD 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: USD 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: USD curl -X DELETE \ -H "Authorization: Bearer <your_access_token>" \ "<quay-server.example.com>/api/v1/organization/<organization_name>/team/<team_name>/invite/<email>" 7.1.4.2. Setting the role of a team within an organization by using the API Use the following procedure to view and set the role a team within an organization using the API. Prerequisites You have Created an OAuth access token . You have set BROWSER_API_CALLS_XHR_ONLY: false in your config.yaml file. Procedure Enter the following GET /api/v1/organization/{orgname}/team/{teamname}/permissions command to return a list of repository permissions for the organization's team. Note that your team must have been added to a repository for this command to return information. USD 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: USD 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} 7.1.4.3. Deleting a team within an organization by using the API Use the following procedure to delete a team within an organization by using the API. Prerequisites You have Created an OAuth access token . You have set BROWSER_API_CALLS_XHR_ONLY: false in your config.yaml file. Procedure You can delete a team within an organization by entering the DELETE /api/v1/organization/{orgname}/team/{teamname} command: USD 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. 7.2. Creating and managing default permissions by using the UI Default permissions define permissions that should be granted automatically to a repository when it is created, in addition to the default of the repository's creator. Permissions are assigned based on the user who created the repository. Use the following procedure to create default permissions using the Red Hat Quay v2 UI. Procedure Click the name of an organization. Click Default permissions . Click Create default permissions . A toggle drawer appears. Select either Anyone or Specific user to create a default permission when a repository is created. If selecting Anyone , the following information must be provided: Applied to . Search, invite, or add a user/robot/team. Permission . Set the permission to one of Read , Write , or Admin . If selecting Specific user , the following information must be provided: Repository creator . Provide either a user or robot account. Applied to . Provide a username, robot account, or team name. Permission . Set the permission to one of Read , Write , or Admin . Click Create default permission . A confirmation box appears, returning the following alert: Successfully created default permission for creator . 7.3. Creating and managing default permissions by using the API Use the following procedures to manage default permissions using the Red Hat Quay API. Prerequisites You have Created an OAuth access token . You have set BROWSER_API_CALLS_XHR_ONLY: false in your config.yaml file. Procedure Enter the following command to create a default permission with the POST /api/v1/organization/{orgname}/prototypes endpoint: USD curl -X POST -H "Authorization: Bearer <bearer_token>" -H "Content-Type: application/json" --data '{ "role": "<admin_read_or_write>", "delegate": { "name": "<username>", "kind": "user" }, "activating_user": { "name": "<robot_name>" } }' https://<quay-server.example.com>/api/v1/organization/<organization_name>/prototypes Example output {"activating_user": {"name": "test-org+test", "is_robot": true, "kind": "user", "is_org_member": true, "avatar": {"name": "test-org+test", "hash": "aa85264436fe9839e7160bf349100a9b71403a5e9ec684d5b5e9571f6c821370", "color": "#8c564b", "kind": "robot"}}, "delegate": {"name": "testuser", "is_robot": false, "kind": "user", "is_org_member": false, "avatar": {"name": "testuser", "hash": "f660ab912ec121d1b1e928a0bb4bc61b15f5ad44d5efdc4e1c92a25e99b8e44a", "color": "#6b6ecf", "kind": "user"}}, "role": "admin", "id": "977dc2bc-bc75-411d-82b3-604e5b79a493"} Enter the following command to update a default permission using the PUT /api/v1/organization/{orgname}/prototypes/{prototypeid} endpoint, for example, if you want to change the permission type. You must include the ID that was returned when you created the policy. USD curl -X PUT \ -H "Authorization: Bearer <bearer_token>" \ -H "Content-Type: application/json" \ --data '{ "role": "write" }' \ https://<quay-server.example.com>/api/v1/organization/<organization_name>/prototypes/<prototypeid> Example output {"activating_user": {"name": "test-org+test", "is_robot": true, "kind": "user", "is_org_member": true, "avatar": {"name": "test-org+test", "hash": "aa85264436fe9839e7160bf349100a9b71403a5e9ec684d5b5e9571f6c821370", "color": "#8c564b", "kind": "robot"}}, "delegate": {"name": "testuser", "is_robot": false, "kind": "user", "is_org_member": false, "avatar": {"name": "testuser", "hash": "f660ab912ec121d1b1e928a0bb4bc61b15f5ad44d5efdc4e1c92a25e99b8e44a", "color": "#6b6ecf", "kind": "user"}}, "role": "write", "id": "977dc2bc-bc75-411d-82b3-604e5b79a493"} You can delete the permission by entering the DELETE /api/v1/organization/{orgname}/prototypes/{prototypeid} command: curl -X DELETE \ -H "Authorization: Bearer <bearer_token>" \ -H "Accept: application/json" \ https://<quay-server.example.com>/api/v1/organization/<organization_name>/prototypes/<prototype_id> This command does not return an output. Instead, you can obtain a list of all permissions by entering the GET /api/v1/organization/{orgname}/prototypes command: USD curl -X GET \ -H "Authorization: Bearer <bearer_token>" \ -H "Accept: application/json" \ https://<quay-server.example.com>/api/v1/organization/<organization_name>/prototypes Example output {"prototypes": []} 7.4. Adjusting access settings for a repository by using the UI Use the following procedure to adjust access settings for a user or robot account for a repository using the v2 UI. Prerequisites You have created a user account or robot account. Procedure Log into Red Hat Quay. On the v2 UI, click Repositories . Click the name of a repository, for example, quayadmin/busybox . Click the Settings tab. Optional. Click User and robot permissions . You can adjust the settings for a user or robot account by clicking the dropdown menu option under Permissions . You can change the settings to Read , Write , or Admin . Read . The User or Robot Account can view and pull from the repository. Write . The User or Robot Account can read (pull) from and write (push) to the repository. Admin . The User or Robot account has access to pull from, and push to, the repository, plus the ability to do administrative tasks associated with the repository. 7.5. Adjusting access settings for a repository by using the API Use the following procedure to adjust access settings for a user or robot account for a repository by using the API. Prerequisites You have created a user account or robot account. You have Created an OAuth access token . You have set BROWSER_API_CALLS_XHR_ONLY: false in your config.yaml file. Procedure Enter the following PUT /api/v1/repository/{repository}/permissions/user/{username} command to change the permissions of a user: USD curl -X PUT \ -H "Authorization: Bearer <bearer_token>" \ -H "Content-Type: application/json" \ -d '{"role": "admin"}' \ https://<quay-server.example.com>/api/v1/repository/<namespace>/<repository>/permissions/user/<username> Example output {"role": "admin", "name": "quayadmin+test", "is_robot": true, "avatar": {"name": "quayadmin+test", "hash": "ca9afae0a9d3ca322fc8a7a866e8476dd6c98de543decd186ae090e420a88feb", "color": "#8c564b", "kind": "robot"}} To delete the current permission, you can enter the DELETE /api/v1/repository/{repository}/permissions/user/{username} command: USD curl -X DELETE \ -H "Authorization: Bearer <bearer_token>" \ -H "Accept: application/json" \ https://<quay-server.example.com>/api/v1/repository/<namespace>/<repository>/permissions/user/<username> This command does not return any output in the CLI. Instead, you can check that the permissions were deleted by entering the GET /api/v1/repository/{repository}/permissions/user/ command: USD curl -X GET \ -H "Authorization: Bearer <bearer_token>" \ -H "Accept: application/json" \ https://<quay-server.example.com>/api/v1/repository/<namespace>/<repository>/permissions/user/<username>/ Example output {"message":"User does not have permission for repo."}

Commands:
curl -k -X PUT -H 'Accept: application/json' -H 'Content-Type: application/json' -H "Authorization: Bearer <bearer_token>" --data '{"role": "creator"}' https://<quay-server.example.com>/api/v1/organization/<organization_name>/team/<team_name>
{"name": "example_team", "description": "", "can_view": true, "role": "creator", "avatar": {"name": "example_team", "hash": "dec209fd7312a2284b689d4db3135e2846f27e0f40fa126776a0ce17366bc989", "color": "#e7ba52", "kind": "team"}, "new_team": true}
curl -X PUT -H "Authorization: Bearer <your_access_token>" "<quay-server.example.com>/api/v1/organization/<organization_name>/team/<team_name>/members/<member_name>"
{"name": "testuser", "kind": "user", "is_robot": false, "avatar": {"name": "testuser", "hash": "d51d17303dc3271ac3266fb332d7df919bab882bbfc7199d2017a4daac8979f0", "color": "#5254a3", "kind": "user"}, "invited": false}
curl -X DELETE -H "Authorization: Bearer <your_access_token>" "<quay-server.example.com>/api/v1/organization/<organization_name>/team/<team_name>/members/<member_name>"
curl -X GET -H "Authorization: Bearer <your_access_token>" "<quay-server.example.com>/api/v1/organization/<organization_name>/team/<team_name>/members"
{"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}
curl -X PUT -H "Authorization: Bearer <your_access_token>" "<quay-server.example.com>/api/v1/organization/<organization_name>/team/<team_name>/invite/<email>"
curl -X DELETE -H "Authorization: Bearer <your_access_token>" "<quay-server.example.com>/api/v1/organization/<organization_name>/team/<team_name>/invite/<email>"
curl -X GET -H "Authorization: Bearer <your_access_token>" "<quay-server.example.com>/api/v1/organization/<organization_name>/team/<team_name>/permissions"
{"permissions": [{"repository": {"name": "api-repo", "is_public": true}, "role": "admin"}]}
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>"
{"name": "testteam", "description": "", "can_view": true, "role": "creator", "avatar": {"name": "testteam", "hash": "827f8c5762148d7e85402495b126e0a18b9b168170416ed04b49aae551099dc8", "color": "#ff7f0e", "kind": "team"}, "new_team": false}
curl -X DELETE -H "Authorization: Bearer <your_access_token>" "<quay-server.example.com>/api/v1/organization/<organization_name>/team/<team_name>"
curl -X POST -H "Authorization: Bearer <bearer_token>" -H "Content-Type: application/json" --data '{ "role": "<admin_read_or_write>", "delegate": { "name": "<username>", "kind": "user" }, "activating_user": { "name": "<robot_name>" } }' https://<quay-server.example.com>/api/v1/organization/<organization_name>/prototypes
{"activating_user": {"name": "test-org+test", "is_robot": true, "kind": "user", "is_org_member": true, "avatar": {"name": "test-org+test", "hash": "aa85264436fe9839e7160bf349100a9b71403a5e9ec684d5b5e9571f6c821370", "color": "#8c564b", "kind": "robot"}}, "delegate": {"name": "testuser", "is_robot": false, "kind": "user", "is_org_member": false, "avatar": {"name": "testuser", "hash": "f660ab912ec121d1b1e928a0bb4bc61b15f5ad44d5efdc4e1c92a25e99b8e44a", "color": "#6b6ecf", "kind": "user"}}, "role": "admin", "id": "977dc2bc-bc75-411d-82b3-604e5b79a493"}
curl -X PUT -H "Authorization: Bearer <bearer_token>" -H "Content-Type: application/json" --data '{ "role": "write" }' https://<quay-server.example.com>/api/v1/organization/<organization_name>/prototypes/<prototypeid>
{"activating_user": {"name": "test-org+test", "is_robot": true, "kind": "user", "is_org_member": true, "avatar": {"name": "test-org+test", "hash": "aa85264436fe9839e7160bf349100a9b71403a5e9ec684d5b5e9571f6c821370", "color": "#8c564b", "kind": "robot"}}, "delegate": {"name": "testuser", "is_robot": false, "kind": "user", "is_org_member": false, "avatar": {"name": "testuser", "hash": "f660ab912ec121d1b1e928a0bb4bc61b15f5ad44d5efdc4e1c92a25e99b8e44a", "color": "#6b6ecf", "kind": "user"}}, "role": "write", "id": "977dc2bc-bc75-411d-82b3-604e5b79a493"}
curl -X DELETE -H "Authorization: Bearer <bearer_token>" -H "Accept: application/json" https://<quay-server.example.com>/api/v1/organization/<organization_name>/prototypes/<prototype_id>
curl -X GET -H "Authorization: Bearer <bearer_token>" -H "Accept: application/json" https://<quay-server.example.com>/api/v1/organization/<organization_name>/prototypes
{"prototypes": []}
curl -X PUT -H "Authorization: Bearer <bearer_token>" -H "Content-Type: application/json" -d '{"role": "admin"}' https://<quay-server.example.com>/api/v1/repository/<namespace>/<repository>/permissions/user/<username>
{"role": "admin", "name": "quayadmin+test", "is_robot": true, "avatar": {"name": "quayadmin+test", "hash": "ca9afae0a9d3ca322fc8a7a866e8476dd6c98de543decd186ae090e420a88feb", "color": "#8c564b", "kind": "robot"}}
curl -X DELETE -H "Authorization: Bearer <bearer_token>" -H "Accept: application/json" https://<quay-server.example.com>/api/v1/repository/<namespace>/<repository>/permissions/user/<username>
curl -X GET -H "Authorization: Bearer <bearer_token>" -H "Accept: application/json" https://<quay-server.example.com>/api/v1/repository/<namespace>/<repository>/permissions/user/<username>/
message: User does not have permission for repo.