Service accounts
# Problem
We have multiple use cases to support authentication methods where the actor is not a `User`. We want to support tokens that belong to a group or a project. We want all admins (group admins or project admins respectively) to be able to manage them, not just the user who created it. We also want to avoid the deletion of these tokens when an actual member is removed.
# Current State
We have multiple different approaches so far, a couple of them:
* ~~`ScimToken` is accepted by a [few API endpoints](https://docs.gitlab.com/ee/api/scim.html) and uses [custom logic](https://gitlab.com/gitlab-org/gitlab/-/blob/v13.5.0-ee/ee/lib/api/scim.rb#L40) to authenticate / authorize a group level token.~~
* `DeployToken` can be used to [authenticate to the API](https://gitlab.com/gitlab-org/gitlab/-/blob/v13.5.0-ee/lib/api/api_guard.rb#L72). This caused a security incident in the past because our code [relies heavily on `current_user`](https://gitlab.com/gitlab-org/gitlab/-/issues/275941) and it's very easy to miss when something else is passed in.
* [`Project Access Tokens`](https://docs.gitlab.com/ee/user/project/settings/project_access_tokens.html) are essentially `PersonalAccessTokens`. We automatically create a new user for each of them and add them as a member. The membership level is not configurable, they are added as `maintainers`. This is unnecessarily high for many use cases. The creation and deletion of lots of `Users` might also not be ideal.
* [`Group Access Tokens`](https://docs.gitlab.com/ee/user/group/settings/group_access_tokens.html) are highly privileged (when granted `scope`). They have a maximum role of `Owner`. They do not consume a seat, and are associated with a bot user.
`
That's a bunch of the security concerns so far, plus having all these various implementations are very confusing.
This issue captures concerns with the current implementation: https://gitlab.com/gitlab-org/gitlab/-/issues/374535+
# Proposal
#### ✏️ [Figma work space](https://www.figma.com/file/citX6p2dsOKjjlQhLNlZLG/284393-Service-accounts?node-id=1%3A54)
#### 🕹 [Prototype 2021-11-10](https://www.figma.com/proto/citX6p2dsOKjjlQhLNlZLG/%23284393-Service-accounts?page-id=510%3A14677&node-id=510%3A14678&viewport=382%2C48%2C0.17&scaling=min-zoom&starting-point-node-id=510%3A14678) | [(Screens)](https://www.figma.com/file/citX6p2dsOKjjlQhLNlZLG/%23284393-Service-accounts?node-id=510%3A14677)
Create non human accounts, that don't consume a seat, that can be used for authenticating with GitLab. The user should be able to choose the scopes (project level, group level, and permissions within each of those) for each service account.
#### MVC iteration road map
@ifarkas [suggested](https://gitlab.com/groups/gitlab-org/-/epics/5793#note_844611348):
> 1. introduce service accounts with supporting `PersonalAccessToken` only
> 1. for `ProjectAccessTokens`:
> 1. migrate the bot user of `ProjectAccessTokens` to be a service account, `ProjectAccessTokens` will be available as `PersonalAccessToken` of the service account
> 1. deprecate the notion of `ProjectAccessToken`
> 1. for `GroupAccessToken`:
> 1. migrate the bot user of `GroupAccessToken` to be a service account, `GroupAccessToken` will be available as `PersonalAccessToken` of the service account
> 1. deprecate the notion of `GroupAccessToken`
> 1. for `DeployToken`:
> 1. allow to be associated with a service account
> 1. create a service account for existing `DeployTokens`
> 1. deprecate the current workflow that allows creating a `DeployToken` without having a service account associated with it
> 1. get rid of all the custom authentication code that is required for `DeployTokens`
and [here](https://gitlab.com/groups/gitlab-org/-/epics/6777#note_684741335):
> * instead of hiding the underlying user, we could list them (maybe on a new `Service Accounts` tab on the membership page).
> * access level should be configurable instead of being `maintainers`
> * service account and tokens should be somewhat independent. Eg. unlike `Project Access Tokens`, deleting the token should not delete the service account. Of course, deleting a service account should delete all associated tokens.
> * allow the creation of multiple service accounts
> * allow the creation of multiple `PersonalAccesTokens` per service account
> * add more and more token types
# Requirements
- Ability to scope to top level container, group, or project
- Ability to define role of the service account
# Considerations
API automation around managing service accounts
Introduce service accounts. Each service account would essentially be a `User` by introducing another value to the `user_type` enum or another boolean field. They would not be allowed to log in and should not count as licensed seats. They would be added as members, and admins would be able to manage them similarly to how members are managed currently (so membership level would be configurable too). Once created, admins would be able to create various tokens for these service accounts including `PersonalAccessTokens`, `DeployTokens`, ~~`ScimToken`~~, etc.
We could migrate our tokens to be backed by service accounts and eliminate all existing logic for custom authentication / authorization.
This might also help with [unifying all tokens](https://gitlab.com/gitlab-org/gitlab/-/issues/27123), as the difference between tokens boils down to using scopes in many cases.
# Other Considerations
1. Expiry of issued tokens - when do the tokens expire? is it configurable? is it different based on token type?
2. Rotation of tokens - currently this is a manual process that our customers have to set their devOps engineers reminders to do etc. Is there any way this can be automated? We should look into how competitors do this portion.
3. Continue to support Personal Access Tokens as they exist today
4. Existing Project Access Tokens - as this concept is rolled into Service Accounts, we need to have a migration plan for these - where will they end up in the UI?
5. Unified "token" creation feels cumbersome.
- Deploy tokens generate a token
- ~~SCIM tokens do not generate a token~~
- Access tokens generate a user account, AND a token.
6. PAT user requests a JWT - struggle with
epic