Do not allow creating Service Accounts for a subgroup
Self-Managed
POST /groups/:id/service_accounts
API endpoint creates service account for group/organization. When service account is created, internally its attribute provisioned_by_group_id
is set to group/organization ID. This is done for purposes mark to which group/organization this service account belongs to. provisioned_by_group_id
used in the codebase to identify to which group/organization the service account is tied and for authorization checks based on that attribute. In the GitLab system internals, authorization checks, we assert and expect that provisioned_by_group_id
could only refer to a top-level group. We should guarantee that, otherwise it will lead to data integrity issues and break application behavior in lots of places.
Currently, POST /groups/:id/service_accounts
API endpoint allows creating Service Accounts for a subgroup, hence provisioned_by_group_id
can be set to a subgroup ID. It leads to lead to data integrity issues and break application behavior. Below one example is provided to confirm that in Step to reproduce
section.
Another issue will pop up when we will build Service Accounts UI (&9965). We will need to identify all service account that belongs to organization. We will need to to something fancy and complex from implementation perspective to identify those service accounts that internally tied to a subgroup. Simple code like User.service_account.with_provisioning_group(organization-group)
or organization-group.provisioned_users.service_account
won't work.
Step to reproduce
- Create top-level group. My group ID is
95
. - Create a subgroup of the top-level group. My subgroup ID is
98
- Enforce SSO for the group. For SSO-enforced groups only users with the group saml identity could be added. As per !126059 (merged) Service Accounts that belongs to group should be allowed to be added to the group despite SSO enforcement.
- Create service account for top-level group by using the API endpoint.
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/95/service_accounts"
{"id":74,"username":"service_account_group_95_23b5e245aa754827ff6063e696e9d8ef","name":"Service account user"}
- Create service account for the subgroup
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/98/service_accounts"
{"id":75,"username":"service_account_group_98_f9fcc6038fba0e9a498c90c62777fa68","name":"Service account user"}
- Add service account created for top-level group to members of the group or any of its subgroup/project
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --data "user_id=74&access_level=30" "https://gitlab.example.com/api/v4/groups/95/members"
{"id":74,"username":"service_account_group_95_23b5e245aa754827ff6063e696e9d8ef","name":"Service account user","state":"active","locked":false,"avatar_url":"https://secure.gravatar.com/avatar/cb2fcba1992b798b1895026f4b4e81897d6733f25b092f4dc7920ede8e9ad5ba?s=80\u0026d=identicon","web_url":"https://gdk.test:3443/service_account_group_95_23b5e245aa754827ff6063e696e9d8ef","access_level":30,"created_at":"2024-03-06T14:26:00.969Z","created_by":{"id":71,"username":"bdenkovych","name":"Bogdan Denkovych","state":"active","locked":false,"avatar_url":"https://gdk.test:3443/uploads/-/system/user/avatar/71/avatar.png","web_url":"https://gdk.test:3443/bdenkovych"},"expires_at":null,"group_saml_identity":null,"membership_state":"active"}
- Add service account created for the subgroup to members of the group or any of its subgroup/project
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --data "user_id=75&access_level=30" "https://gitlab.example.com/api/v4/groups/95/members"
{"message":{"user":["is not linked to a SAML account or has an inactive SCIM identity. For information on how to resolve this error, see the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"/help/user/group/saml_sso/troubleshooting_scim\">troubleshooting SCIM documentation</a>."]}
You will see the error. It is a typebug.
.com
POST /groups/:id/service_accounts
API endpoint returns 500 Internal Server Error
when creating Service Accounts for a subgroup, see
- https://new-sentry.gitlab.net/organizations/gitlab/issues/546498/?project=3
- https://new-sentry.gitlab.net/organizations/gitlab/issues/668820/?project=3
We should handle that error and return 400 Bad request
with error message instead of 500 Internal Server Error
- for better user experience
-
500
impacts the error budget
Solution
Do not allow creating Service Accounts for a subgroup.
As per !152195 (merged), update ee/app/policies/ee/group_policy.rb
. The fix will look something like:
diff --git ee/app/policies/ee/group_policy.rb ee/app/policies/ee/group_policy.rb
index 192b810aca63..06dc00db31ff 100644
--- ee/app/policies/ee/group_policy.rb
+++ ee/app/policies/ee/group_policy.rb
@@ -442,7 +442,7 @@ module GroupPolicy
prevent :admin_group_member
end
- rule { service_accounts_available & (admin | (is_gitlab_com & owner)) }.policy do
+ rule { service_accounts_available & ~has_parent & (admin | (is_gitlab_com & owner)) }.policy do
enable :create_service_account
end
-
Add tests for both Self-Managed and .com contexts -
Add tests for API endpoints directly to ensure that they do not return 500
anymore. -
Update documentation