Federation Enhancements
Problem to solve
OmniAuth standardizes multi-provider authentication for web applications. Currently this functionality is primarily used for social login. That is to say, many of the OmniAuth authentication gems ignore the optional credentials field as specified in the Auth Hash Schema.
GitLab allows access to the full auth hash, but it currently does not contextualize that access based on the provider or access level. More specifically, the credentials and delegated access mechanisms available from social login are not exploited to their maximum potential. Contextualizing that access can be leveraged to secure CI jobs with federation, adding an extra layer of validation, for example.
Ergo the problem to solve is how to fully leverage social login for scalable, secure, distributed workflows across heterogeneous systems, both cloud-based and high-performance based.
Proposal
The high-level mechanism is presented here:
Stages 1-10 are all part of the standard authorization code flow of OAuth 2.0 RFC 6749, section 4.1. From a GitLab user's perspective, they simply go to gitlab.com/profile/account and connect their social sign-in identities. The enhancements come starting at stage 9, where now, during the auth hash construction, a user's identity no longer just stores their external user id, but also contains their credentials. Then, at stage 10, the context of the user's access is sent down to the runner. These credentials can be leveraged by runner admins in stage 11 to validate the user and ensure CI jobs are run as the necessary local user (i.e., the external user id) or some specified service user. Effectively, this extends data zones to runners, and more generally, provides a robust mechanism for automated access in a zero trust network.
The key pieces required are:
-
Base updates to the identity model and user session. Per the auth hash schema, the credentials field is added as a column to the PostgreSQL identities table. This should be encrypted, so it will leverage Vault when it is integrated with GitLab. Additionally, the user's session should contain information about access levels.
-
OmniAuth callback controller enhancement. In particular, the OmniAuth identity linker base should reflect that identities which expire can be updated.
-
With the enhanced user context in place, we then expose the user account and credentials to runner jobs triggered by the user relative to the session, rather than the overall user.
-
Finally,
FederationEvent
s allow auditing of all aforementioned actions.
Constraints:
-
Feature flag
Permissions and Security
The heart of this feature proposal is adding the context of who is running a CI job, and whether they have the necessary access to do so, to the CI job itself. And that context assumes GitLab's existing permissions model. Namely, there is no need to change the existing permissions model, only the workflows when CI jobs are submitted to federated runners.
From a user's perspective, nothing changes in their workflow except connecting social logins before triggering jobs to be run at federated runners. From a server admin's perspective, nothing changes except seeing the logs filled with more social login entries.
The biggest change happens with runner admins. It is completely up to their discretion how they wish to leverage a user's external user id and access token to validate whether that user can run a CI job on their system. Further, we take heavy advantage of the custom executor to implement this currently.
Documentation
As this feature proposal advances, we wish to share working examples, as well as our full virtualized testing environment, to users, developers, and admins.
Testing
Tests will be added when a consensus for the implementation approach is reached. We currently heavily leverage a full virtualized testing environment in a private GitLab repo which we can go through with the GitLab team if so desired. Also, depending on the consensus, we might like to implement a REST API, perhaps at /identities/:user_id
, for further tests.