PoC: Separate Access Model for Deployment Approval (API)
What does this MR do and why?
This MR is on top of !82071 (closed)
This MR is a PoC that represents the backend implementation for Deployment Approval Rules. It's for giving a high-level overview of the entire implementation. This is NOT FOR MERGE.
Related #345678 (closed)
The approach
We add a capability to create Approval Rules via API. If the rules exist, the system switches to the rule-base authorization instead of using deploy access levels for approvals.
We likely follow-up frontend and UX proposal after the backend architecture has been settled.
Screenshots or screen recordings
Creating a new Protected Environment
shinya@shinya-B550-VISION-D:~/workspace/thin-gdk/services/rails/src$ curl --header "PRIVATE-TOKEN: glpat-SNHmsxECHzfGdP4BzCsF" "http://local.gitlab.test:8181/api/v4/projects/261/protected_environments/production" | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 287 100 287 0 0 56 0 0:00:05 0:00:05 --:--:-- 58
{
"name": "production",
"deploy_access_levels": [
{
"access_level": 40,
"access_level_description": "Maintainers",
"user_id": null,
"group_id": null
}
],
"required_approval_count": 0,
"approval_rules": [
{
"user_id": null,
"group_id": null,
"access_level": 40,
"access_level_description": "Maintainers",
"count": 1
}
]
}
Making sure the deployment is blocked
shinya@shinya-B550-VISION-D:~/workspace/thin-gdk/services/rails/src$ curl --header "PRIVATE-TOKEN: glpat-SNHmsxECHzfGdP4BzCsF" "http://local.gitlab.test:8181/api/v4/projects/261/deployments/1520" | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 2569 0 2569 0 0 7468 0 --:--:-- --:--:-- --:--:-- 7468
{
"id": 1520,
"iid": 1,
"ref": "main",
"sha": "ac67928811755a52fc4e01fac64be5ee1caa77f1",
"created_at": "2022-03-10T13:03:37.957Z",
"updated_at": "2022-03-10T13:03:41.777Z",
"user": {
"id": 1,
"username": "root",
"name": "Administrator",
"state": "active",
"avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
"web_url": "http://local.gitlab.test:8181/root"
},
"environment": {
"id": 708,
"name": "production",
"slug": "production",
"external_url": null,
"created_at": "2022-03-10T13:03:37.662Z",
"updated_at": "2022-03-10T13:03:37.662Z"
},
"deployable": {
"id": 3915,
"status": "manual",
"stage": "test",
"name": "deploy",
"ref": "main",
"tag": false,
"coverage": null,
"allow_failure": false,
"created_at": "2022-03-10T13:03:37.709Z",
"started_at": null,
"finished_at": null,
"duration": null,
"queued_duration": null,
"user": {
"id": 1,
"username": "root",
"name": "Administrator",
"state": "active",
"avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
"web_url": "http://local.gitlab.test:8181/root",
"created_at": "2021-06-18T09:55:00.193Z",
"bio": "",
"location": null,
"public_email": "",
"skype": "",
"linkedin": "",
"twitter": "",
"website_url": "",
"organization": null,
"job_title": "",
"pronouns": null,
"bot": false,
"work_information": null,
"followers": 0,
"following": 0,
"local_time": "1:50 PM"
},
"commit": {
"id": "ac67928811755a52fc4e01fac64be5ee1caa77f1",
"short_id": "ac679288",
"created_at": "2022-03-10T13:01:14.000+00:00",
"parent_ids": [
"8a0fd35f780f63908f4fb4e90c2f0a1881605172"
],
"title": "Add new file",
"message": "Add new file",
"author_name": "Administrator",
"author_email": "admin@example.com",
"authored_date": "2022-03-10T13:01:14.000+00:00",
"committer_name": "Administrator",
"committer_email": "admin@example.com",
"committed_date": "2022-03-10T13:01:14.000+00:00",
"trailers": {},
"web_url": "http://local.gitlab.test:8181/root/deploy-approval-rules/-/commit/ac67928811755a52fc4e01fac64be5ee1caa77f1"
},
"pipeline": {
"id": 1368,
"iid": 1,
"project_id": 261,
"sha": "ac67928811755a52fc4e01fac64be5ee1caa77f1",
"ref": "main",
"status": "manual",
"source": "web",
"created_at": "2022-03-10T13:03:37.671Z",
"updated_at": "2022-03-10T13:03:41.846Z",
"web_url": "http://local.gitlab.test:8181/root/deploy-approval-rules/-/pipelines/1368"
},
"web_url": "http://local.gitlab.test:8181/root/deploy-approval-rules/-/jobs/3915",
"artifacts": [],
"runner": null,
"artifacts_expire_at": null,
"tag_list": []
},
"status": "blocked",
"pending_approval_count": 0,
"approvals": [],
"approval_summary": [
{
"user_id": null,
"group_id": null,
"access_level": 40,
"access_level_description": "Maintainers",
"count": 1,
"deployment_approvals": []
}
]
}
Approving a job
shinya@shinya-B550-VISION-D:~/workspace/thin-gdk/services/rails/src$ curl --data "status=approved&comment=Looks good to me" \
> --header "PRIVATE-TOKEN: glpat-_jA--dPSAaQxvsMUaap5" "http://local.gitlab.test:8181/api/v4/projects/261/deployments/1520/approval" | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 358 100 318 100 40 700 88 --:--:-- --:--:-- --:--:-- 786
{
"user": {
"id": 100,
"username": "shinya",
"name": "shinya Maeda",
"state": "active",
"avatar_url": "https://www.gravatar.com/avatar/d99019d49e480c8654156065b29eeb6f?s=80&d=identicon",
"web_url": "http://local.gitlab.test:8181/shinya"
},
"status": "approved",
"created_at": "2022-03-10T13:54:21.628Z",
"comment": "Looks good to me"
}
shinya@shinya-B550-VISION-D:~/workspace/thin-gdk/services/rails/src$ curl --data "status=approved&comment=Looks good to me" \
> --header "PRIVATE-TOKEN: glpat-_jA--dPSAaQxvsMUaap5" "http://local.gitlab.test:8181/api/v4/projects/261/deployments/1520/approval" | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 117 100 77 100 40 484 251 --:--:-- --:--:-- --:--:-- 735
{
"message": "You do not have permission to approve or reject this deployment"
}
Making sure the deployment started running
shinya@shinya-B550-VISION-D:~/workspace/thin-gdk/services/rails/src$ curl --header "PRIVATE-TOKEN: glpat-SNHmsxECHzfGdP4BzCsF" "http://local.gitlab.test:8181/api/v4/projects/261/deployments/1520" | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 3215 0 3215 0 0 13680 0 --:--:-- --:--:-- --:--:-- 13680
{
"id": 1520,
"iid": 1,
"ref": "main",
"sha": "ac67928811755a52fc4e01fac64be5ee1caa77f1",
"created_at": "2022-03-10T13:03:37.957Z",
"updated_at": "2022-03-10T13:54:21.648Z",
"user": {
"id": 1,
"username": "root",
"name": "Administrator",
"state": "active",
"avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
"web_url": "http://local.gitlab.test:8181/root"
},
"environment": {
"id": 708,
"name": "production",
"slug": "production",
"external_url": null,
"created_at": "2022-03-10T13:03:37.662Z",
"updated_at": "2022-03-10T13:03:37.662Z"
},
"deployable": {
"id": 3915,
"status": "pending",
"stage": "test",
"name": "deploy",
"ref": "main",
"tag": false,
"coverage": null,
"allow_failure": false,
"created_at": "2022-03-10T13:03:37.709Z",
"started_at": null,
"finished_at": null,
"duration": null,
"queued_duration": 20.255790985,
"user": {
"id": 1,
"username": "root",
"name": "Administrator",
"state": "active",
"avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
"web_url": "http://local.gitlab.test:8181/root",
"created_at": "2021-06-18T09:55:00.193Z",
"bio": "",
"location": null,
"public_email": "",
"skype": "",
"linkedin": "",
"twitter": "",
"website_url": "",
"organization": null,
"job_title": "",
"pronouns": null,
"bot": false,
"work_information": null,
"followers": 0,
"following": 0,
"local_time": "1:54 PM"
},
"commit": {
"id": "ac67928811755a52fc4e01fac64be5ee1caa77f1",
"short_id": "ac679288",
"created_at": "2022-03-10T13:01:14.000+00:00",
"parent_ids": [
"8a0fd35f780f63908f4fb4e90c2f0a1881605172"
],
"title": "Add new file",
"message": "Add new file",
"author_name": "Administrator",
"author_email": "admin@example.com",
"authored_date": "2022-03-10T13:01:14.000+00:00",
"committer_name": "Administrator",
"committer_email": "admin@example.com",
"committed_date": "2022-03-10T13:01:14.000+00:00",
"trailers": {},
"web_url": "http://local.gitlab.test:8181/root/deploy-approval-rules/-/commit/ac67928811755a52fc4e01fac64be5ee1caa77f1"
},
"pipeline": {
"id": 1368,
"iid": 1,
"project_id": 261,
"sha": "ac67928811755a52fc4e01fac64be5ee1caa77f1",
"ref": "main",
"status": "pending",
"source": "web",
"created_at": "2022-03-10T13:03:37.671Z",
"updated_at": "2022-03-10T13:54:23.292Z",
"web_url": "http://local.gitlab.test:8181/root/deploy-approval-rules/-/pipelines/1368"
},
"web_url": "http://local.gitlab.test:8181/root/deploy-approval-rules/-/jobs/3915",
"artifacts": [],
"runner": null,
"artifacts_expire_at": null,
"tag_list": []
},
"status": "created",
"pending_approval_count": 0,
"approvals": [
{
"user": {
"id": 100,
"username": "shinya",
"name": "shinya Maeda",
"state": "active",
"avatar_url": "https://www.gravatar.com/avatar/d99019d49e480c8654156065b29eeb6f?s=80&d=identicon",
"web_url": "http://local.gitlab.test:8181/shinya"
},
"status": "approved",
"created_at": "2022-03-10T13:54:21.628Z",
"comment": "Looks good to me"
}
],
"approval_summary": [
{
"user_id": null,
"group_id": null,
"access_level": 40,
"access_level_description": "Maintainers",
"count": 1,
"deployment_approvals": [
{
"user": {
"id": 100,
"username": "shinya",
"name": "shinya Maeda",
"state": "active",
"avatar_url": "https://www.gravatar.com/avatar/d99019d49e480c8654156065b29eeb6f?s=80&d=identicon",
"web_url": "http://local.gitlab.test:8181/shinya"
},
"status": "approved",
"created_at": "2022-03-10T13:54:21.628Z",
"comment": "Looks good to me"
}
]
}
]
}
How to set up and validate locally
Numbered steps to set up and validate the change are strongly suggested.
MR acceptance checklist
This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.
-
I have evaluated the MR acceptance checklist for this MR.
Edited by Shinya Maeda