Explore options for authentication for Self Managed instance in the scope of Iteration 1
An end-user needs to authenticate with the GitLab instance they are a user of. This is often transparent, in cases where the feature is embedded into the web experience, but could also require manual interaction as in the case of plugging a code suggestions API into their IDE of choice. We can break this down further into two types of authentication problems:
1. Is the user allowed to access this feature on this instance?
* This is auth between `SM user <=> SM instance`
* This can continue to happen e.g. via a PAT for API based integrations or the current web session (cookie)
1. Is the SM instance allowed to access this feature on SaaS as part of Plus?
* This is auth between `SM instance <=> SaaS`; It needs to be tied to license validity and permissions, see next point.
## Update
In order to deliver Code Suggestions to SM quicker we [decided](https://gitlab.com/groups/gitlab-org/-/epics/10604#note_1394392835) to use SM *admin* SaaS PAT for our [PoC](url)
## Important links
Internal notes from the meeting:
- https://docs.google.com/document/d/1PAFj4YrvAJ8AXIIk06zf_Xt_eFMWClbVgiByaRj2xMs/edit?usp=sharing
## SM instance <=> SaaS - instance level authentication
We discussed 2 options:
### Option 1: [Service accounts](https://gitlab.com/groups/gitlab-org/-/epics/9573):
The service account is a "headless user" used to make Plus requests to SaaS on behalf of the SM end-user.
* Pre-requisite steps:
* SM admin needs to create an account on GitLab.com
* SM admin needs to create a service account, which will be configured with all needed permissions (read_code_suggestions)
* Service account token needs to be stored on Self managed instance
<details><summary>Discussed flow for WebIDE -> Click to expand</summary>
```plantuml
skinparam shadowing false
skinparam ParticipantPadding 60
skinparam BoxPadding 60
autonumber "<b>[0]"
participant "Web IDE" as A
box "GitLab SM Instance"
participant "GitLab API" as B1
end box
box "GitLab"
participant "GitLab API" as B
end box
box "Code Suggestions"
participant "Model Gateway" as C
end box
[o-> A: on init
activate A
A -> B1: POST /api/v4/code_completions/tokens
activate A
note left
{ cookie }
end note
activate B1
B1 -> B1: authenticate/authorize user
B1 -> B: authenticate/authorize service account on SaaS
activate B
B -> B: fetch secret
B -> B: sign JWT token
B --> B1: { cdf456 }
deactivate B
B1 --> A: { cdf456 }
deactivate B1
deactivate A
A -> A: store JWT token in cookie
[<-- A: done
deactivate A
...
[o-> A: on completion
activate A
A -> C: POST /v2/completions
activate A
note left
Header
{ authorization: Bearer cdf456 }
end note
activate C
C -> C: fetch secret
C -> C: verify JWT token
C ->]: fetch completions
C --> A: completions
deactivate C
deactivate B
deactivate A
[<-- A: completions
deactivate A
```
</details>
Once SM user is authenticated/authorized that he can access code suggestions, SM instance will initiate authentication with Gitlab.com, which will authenticate/authorize provided service account token, it will fetch the secret that is shared between Gitlab.com and CodeSuggestions/Model Gateway and sign the JWT token, which will be used by WebIde to access CodeSuggestions functionality.
Pros:
- It uses a solution that already exists (Service accounts are available on backend level). It would be relatively easy to create PoC.
Cons:
- It requires SM admin to create an account/configure a service account. Someone needs to add SM admin to a proper group and configure permissions for that service account.
- It will send a request to Gitlab.com in order to authenticate SM instance and sign the JWT token
### Option 2: [Cloud licensing](https://about.gitlab.com/pricing/licensing-faq/cloud-licensing/)
We use customer.gitlab.com to verify SM instance license and limits (rate limiting, number of seats) and we use it to sign JWT token for SM instance.
Relevant internal discussion
<details><summary>Discussed flow for WebIDE -> Click to expand</summary>
```plantuml
skinparam shadowing false
skinparam ParticipantPadding 60
skinparam BoxPadding 60
autonumber "<b>[0]"
participant "Web IDE" as A
box "GitLab SM Instance"
participant "GitLab API" as B1
end box
box "Customers GitLab.Com"
participant "Cloud licencing" as B
end box
box "Code Suggestions"
participant "Model Gateway" as C
end box
[o-> A: on init
activate A
A -> B1: POST /api/v4/code_completions/tokens
activate A
note left
{ cookie }
end note
activate B1
B1 -> B1: authenticate/authorize user
B1 -> B: verify license on customers.gitlab.com
activate B
B -> B: fetch secret
B -> B: sign JWT token
B --> B1: { cdf456 }
deactivate B
B1 --> A: { cdf456 }
deactivate B1
deactivate A
A -> A: store JWT token in cookie
[<-- A: done
deactivate A
...
[o-> A: on completion
activate A
A -> C: POST /v2/completions
activate A
note left
Header
{ authorization: Bearer cdf456 }
end note
activate C
C -> C: fetch secret
C -> C: verify JWT token
C ->]: fetch completions
C --> A: completions
deactivate C
deactivate B
deactivate A
[<-- A: completions
deactivate A
```
</details>
Once the SM user is authenticated/authorized he can access code suggestions, SM instance will send proof of its Premium/Ultimate license to `customers.gitlab.com`. CustomersDot will fetch the secret that is shared between CustomersDot and CodeSuggestions/Model Gateway and sign the JWT token, which will be used by WebIde to access CodeSuggestions functionality.
Pros:
- Does not call Gitlab.com
- SM admin does not need to create an account/register service account - no need for prerequisite steps
Cons:
- We don't have an API call at the moment that will check the license and sign JWT token. We need to verify a solution with gitlab~24307996
epic