Skip to content

implementation plan for 2FA enforcement for orgsΒ #1291

@WcaleNieWolny

Description

@WcaleNieWolny

The high-level idea

As described in #1256, Capgo would like to have an enforcement of 2FA on the organization level implemented. This new system was found to be an important feature for security-conscious enterprise clients. On a high level, this system should meet all the following criteria:

  1. When a member of an organization that is enforcing 2FA for all of its members (hereafter: "2FA-enforcing org") does not have 2FA enabled, they should not be allowed to read or write from such org
    1.1. In the webapp, the user should see a dialog in which the lack of access is explained after having clicked on the organization
    1.2. In the CLI, a new check should be introduced that checks 2FA enforcement rules, and if it deems that the user is violating the 2FA-enforcement rules, it should block his access and explain why his access has been denied
    1.3. A new error in the API shall be introduced that ensures the conformity with 2FA-enforcement policies
  2. The database should be changed to ensure that when clients bypass the client-side check of 2FA-enforcement and call the database directly, they are refused access

The order of pull requests

Note

The specifics of each PR will be explained bellow

The PRs for this feature should be made in the following order:

  1. Pull request for the RLS/Database
  2. A pull request for the CLI
  3. A pull request for the API
  4. A pull request for the frontend
  5. A pull request for the docs

Step 1 - the PR for the RLS/Database

This is one of the most important steps from a technical perspective that will shape the further implementation.
After having considered the difficulites related to this PR, it has been concluded that there are fundamentally 7 main parts of this PR. These are:

  1. An introduction of a enforcing_2fa boolean in the orgs table (defaults to false)
  2. The change of check_min_rights
    2.1. check_min_rights should check if the org has enabled 2FA-enforcement and if the user has 2FA enabled. If he does not, return false
    2.2. Call PERFORM public.pg_log to log when the access is denied
    2.3. By chaning the check_min_rights we avoid the creation of a new RLS, which is beneficial for performance
  3. Verbose tests of the new feature
    3.1. The tests should be written in SQL, as at this stage, no CLI or backend changes will have been implemented
  4. get_orgs_v7 shall be introduced
    4.1 When the user fails to comply with the 2FA enforcment rules of the org, he shall not be privy to paying, trial_left, can_use_more, is_canceled, app_count, subscription_start, subscription_end, management_email or is_yearly. These values shall be redacted and return false in this case.
    4.1.1. Consider how this information could be leaked using get_orgs_v6
    4.2. A new field named enforcing_2fa shall be introduced in this function
    4.3. A new field called 2fa_has_access shall be introduced. If the user has 2FA and enforcing_2fa is true, return true, otherwise false unless enforcing_2fa is false, then always return true
    4.4. A new field called "can_leave_org" shall be introduced. It should return true when there is at least one super_admin that is not the user calling get_orgs_v7
    4.5. A new field called "can_delete_org" shall be introduced. It should return true when the user has super_admin permissions and 2fa_has_access is true, or it shall return true when 2fa_has_access is false AND the user is the only member in the organization
  5. A new function called check_org_members_2fa_enabled(org_id)
    5.1. This new function should be accessible only to super_admins or an organization
    5.2. This function should return a list of { user_id: string, 2fa_enabled: true/false }
  6. New functions called has_2fa_enabled() and has_2fa_enabled(user_id: uuid) shall be created
    6.1 has_2fa_enabled() should return whether the user has 2FA enabled for themself
    6.2 has_2fa_enabled(user_id) should only be accessible to the supabase user/postgres or our backend and not normal users of Capgo. It should check if 2fa is enabled for a given user.
  7. A new function called reject_access_due_to_2fa(org_id, user_id) shall be introduced
    7.1 If a given org does not enable 2FA enforcement, return false
    7.2 If a given org REQUIRES 2FA, and has_2fa_enabled(user_id) == false, return true
    7.3. Otherwise, return false
    7.4 Similar to has_2fa_enabled(user_id), this function shall be private (accessible only to Capgo's backend, not normal users)

Step 2 - the PR for the CLI

This step should be implemented briefly after having completed AND MERGED part 1. It is crucial that by the time we get to step 4, all the users will have already updated to a CLI version containing the changes required for 2FA-enforcement to work correctly. In the PR for the CLI, the following changes will be introduced:

  1. Before trying to access any resource that could require 2FA to be enabled, the CLI will check if the user enabled 2FA
    1.1. If the user fails to comply with 2FA enforcement policies, the CLI should inform them of the reason for the access denial.
  2. A new option should be introduced that allows the activation of 2FA-enforcement for an organization.
    2.1. When enabling this option, check_org_members_2fa_enabled and get_org_members should be called. If any member does not have 2FA enabled, the consequences of enabling 2FA enforcement shall be explained. A confirmation of intent shall be required before allowing to proceed with the change.
    2.1.1 If the user trying to enable 2FA enforcement does not themself have 2FA enabled, they shall be informed that by enabling 2FA enforcement, they will lose access to the organization until they setup 2FA on their account
  3. A suite of tests shall be developed to test all the features mentioned above

Step 3 - the backend

This step should not pose a lot of technical difficulties. In this step, in the public backend reject_access_due_to_2fa(org_id, user_id) should be called to confirm the user does not violate the 2FA-enforcment policy. If the function returns true, a new error should be thrown explaining the steps required to regain access. (Likely linking to Capgo docs)

Step 4 - the frontend

There are numerous changes required on the frontend. Providing a positive user experience is of the highest priorities when designing the frontend for 2FA enforcement. The changes required are:

  1. The introduction of a switch for 2FA enforcement in the general tab for organizations
    1.1. This switch is to be moved to a seperated tab called "security" at a later date
    1.2. After the user click on this switch, if he does not have 2FA enabled, it shall be explained that he will loose access until they activate 2FA on their account
    1.3. If there are any mebers in the organization that do not have 2FA enabled, the consequences of enabling 2FA enforcement shall be explained. The user must be aware that access for certain members will be denied until 2FA is enabled on their account.
  2. When the user load the Capgo dashboard, the orgs which the user doesn't have access to shall be listed last in the organization selector.
    2.2. The default org shouldn't default to the org that denies access to the user due to 2FA enforcement, even if said org has the most apps of all othe organizations the user is in
    2.3. The default organization can be an organization that is denying access due to 2FA enforcement policies only in the situation where the user is only in one organization.
  3. Should an organization deny access to one if its members, said member shall always be redirected to the main dashboard
  4. If access is denied, the main dashboard shall say "This organization requires 2FA. If you want to access it, please set up 2FA in your account's settings."
    4.1. In this dialog, there shall also be a button to leave the organization and to delete the organization. These buttons should only be clickable only when respectively can_leave_org and can_delete_org are true
  5. When the org has 2fa enforcement enabled, super_admins should be able to see in the list of org members who has or hasn't 2fa enabled

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions