Draft: [POC] Resolve "Group SAML - Check SSO status on API activity and direct user to SSO"
What does this MR do and why?
::Gitlab::Auth::GroupSaml::SsoEnforcer
In !10034 (merged) we implemented SSO status check for Web(aka requests with current session - Gitlab::Session.current
). This SSO status check happens in GroupPolicy
and ProjectPolicy
. Since our policies are the source of truth in terms of users' abilities, it brings confidence that this SSO enforcement always takes its action for Web requests if enabled.
POC: SSO status check for Git, Dependency proxy, and API
In !12594 (closed) @jamedjo
tried to implement SSO status check for sessionless requests(aka Git, Dependency proxy, API).
This MR extends ::Gitlab::Auth::GroupSaml::SsoEnforcer
to check SSO status for sessionless requests.
Since GitLab stores users' sessions to Redis instance, it is possible to retrieve a user's sessions by ActiveSession.list_sessions(user)
in a sessionless environment.
What is great about this change
-
::Gitlab::Auth::GroupSaml::SsoEnforcer
remains to be the one class responsible for SSO enforcement - that this SSO status check happens in the policy layer(
GroupPolicy
/ProjectPolicy
).
This MR was abandoned for some reason. At that point, we lost the way @jamedjo
wanted to implement it.
This POC is based on this work(!12594 (closed)).
With this approach, it wasn't possible to disable SSO status check for some specific activities: Git, API, etc., because we didn't know how to differentiate what type of request it is on performing SSO status check(::Gitlab::Auth::GroupSaml::SsoEnforcer.group_access_restricted?
call in the policy layer).
To solve this issue this POC suggests using the global state to register the type of activity for a specific part of the code:
::Gitlab::Auth::GroupSaml::SsoEnforcer.register_git_activity do
super # Check if git command is allowed for a project
end
In that way, Gitlab::Auth::GroupSaml::SsoEnforcer
could recognize the type of current activity and apply rules that are unique to git activity or bypass SSO status check if it is disabled for git.
The same way we can make Gitlab::Auth::GroupSaml::SsoEnforcer
recognize API activity to be able to apply specific rules for API activity or allow customers to turn off SSO check for API:
around_actions :register_api_activity
def register_api_activity
::Gitlab::Auth::GroupSaml::SsoEnforcer.register_api_activity do
yield # Check if api request is allowed a group/project
end
The big win from this is that:
-
::Gitlab::Auth::GroupSaml::SsoEnforcer
remains to be only one source responsible for SSO enforcement - all this SSO status check happens on the policy layer(
GroupPolicy/ProjectPolicy
) - We can extend it since
::Gitlab::Auth::GroupSaml::SsoEnforcer
can differentiate the type of activity
The cons of this approach:
- If a user needs a new SSO session, they would see
404 Not found
response by default(currently for API)- See how much effort it took to redirect user to group sign in if SSO status check fails: !12246 (merged)
- The same for Git activity. But I managed to retain the message that tells users
SSO is required
instead of404
. See code changes in this MR.
- Currently, we have two SSO status check implementations in place
- They are not consistent in bypassing rules: #334010
- It might be hard to roll out this POC's changes
This POC proofs that this approach works and simplifies SSO status check implementation. See this MR's code changes and specs.
master
branch: SSO enforcement for Git and Dependency proxy
Current implementation in Git activity
In !56867 (merged) we added SSO status check for git activity.
This MR introduced additional ::Gitlab::Auth::GroupSaml::SessionEnforcer
class that is able to check SSO status in sesionless request only(by using ActiveSession.list_sessions(user)
). SSO status check happens on internal/allowed
endpoint.
::Gitlab::Auth::GroupSaml::SessionEnforcer
depends on saml_provider.git_check_enforced
config, meaning it is not possible to reuse this class for other types of activities. See !73642 (comment 725224206) for details.
Dependency proxy activity
See !67373 (merged)
To reuse ::Gitlab::Auth::GroupSaml::SessionEnforcer
class for SSO status check for Dependency proxy we decided to make it to be configurable by saml_provider.git_check_enforced
, which is not the right move IMHO(#337969).
SSO status check for dependency proxy relies on ::Gitlab::Auth::GroupSaml::SessionEnforcer
and was put in the policy layer with a little hack: !67373 (diffs).
It made the SSO enforcement implementation to be even more confusing and not extendable.
I tried to implement SSO status check for API on top of the current implementation, see this MR/thread: !73642 (comment 725224206).
Related to #297389
What do you think about this?