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