Server to Server Authentication/Authorization on behalf of a user event
I have a quite long change request. Hopefully the detail is appreciated. I appreciate any feedback.
I was asked by @r.leite to wait for help to properly create a change request out of Request #178913 . But I do not wish to wait too long, because your bots will auto close things.
I do not see how I could properly put all of the information below properly into the correct template. I will happily assist in filling in a template and I am willing to participate in a live call if that helps.
Note that I abbreviate MR (Merge Request) and TP (TargetProcess).
Server to Server Authentication/Authorization on behalf of a user event.
We use three tools in our daily workflow for which I desire a proper secure way of working.
- TargetProcess (TP), our ticketing system.
- Gitlab
- Artifactory, our binary repository and package server.
These are all servers in the cloud that have web GUI's.
I will describe two typical actions that properly describe the issue that I desire to solve:
- Create a merge request (MR) from TP in Giltab.
- Upload an artifact from a Gitlab controlled build node to Artifactory.
Good to know:
- We keep the project names and paths the same in our tools. This allows the tools to correctly 'guess' the project path used in the other tool.
- All tools use the same authentication/authorization methode and server (ADFS) for users.
Create a merge request.
A user (developer) picks up a ticket to solve. From the ticket in the GUI of TP, the user presses
the button create merge request. TP uses the Gitlab API to create a branch and a MR for the ticket
for the correct project. (And now TP will show the draft/review/build/merged status in the TP GUI on
the ticket. Essential information during the stand-up.)
Current situation.
The current situation is that TP uses my API key to create the MR (and to view the MR status). As a consequence, all TP generated MR's are under my name, and I have to disable e-mail to prevent being spammed.
- We could use per project API keys. But we do have over 1200 projects that we need to manage.
- We also could create a service account for this (which costs a license). This solution requires the least amount of maintenance. (We will probably do this in the near future.)
These solutions have Privilege escalations. A user that triggers the MR creation (from TP) may not have the rights to do so (in Gitlab).
Desired situation.
The user that triggered creating an MR in Gitlab from TP should actually have the rights to do so in Gitlab. And the MR should be created as if that user created the MR in Gitlab himself.
Upload a build artifact.
A user pushes commits from his PC to the Gitlab server. Or alternatively, triggers a build from the
Gitlab GUI.
This triggers a build that generates artifacts.
These artifacts are uploaded to the Artifactory server.
I can also imagine that creating an MR in Gitlab from TP triggers a build that eventually uploads an artifact from the Giltab controlled build node to Artifactory. All on behalf of the user that triggered the MR creation in TP.
Current situation.
These artifacts are uploaded to Artifactory using an API key that is stored in the root group of a project as a secret variable.
Unfortunately, anyone with access to the group or to a project in the group can directly access the content of the variable, or a build job could be created that exposes the key.
This solution has Privilege escalation. A user that triggers the build may not have the rights to upload an artifact.
We are investigating other ways to secure artifact upload.
The issues are roughly the same when the triggered build wants to use (download) artifacts from the Artifactory
server.
Desired situation.
The build artifact is uploaded to Artifactory from the Gitlab controlled build node if the user that triggered the build has the right to do so in Artifactory. The artifact is uploaded as is the user manually uploaded the artifact himself.
First thoughts.
To me it seems that there are two levels of authentication/authorization. Both the server and the user on which behalf the server sends the API request.
Server to server.
This can probably just be done by exchanging API keys between the servers.
But an API key merely authorizes the request. Anyone could make the request. Adding authentication
would be more secure.
I can imagine that I as admin have both tools open in a web browser and copy paste an URL from one page
to the other and thereby connect the two servers to each other. They are now allowed to use the API's
form each other that I select. (And no one else.)
Authorize an action by a server on behalf of a user.
To prevent a Privilege escalation, the target server should authorize the action.
This means that the target server shall receive the identity of the user on who triggered the action.
If you trust the sending server, then you could skip authenticating the user. But it is more secure,
and thus advisable, if the user has to authenticate.
If you have ADFS on the target server, and the user was logged in into the sending server by ADFS, authentication
by the user on the target server should be automatic (without user action).
But if a build was triggered by a push from the command line, then there is a challenge. I can
imagine that the server communicates an URL back to the user o the command line containing the link
for authentication.