Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create a JSON file to store permission scopes required for ScubaGear #1380

Closed
wants to merge 16 commits into from

Conversation

MichaelHicks-MSFT
Copy link
Collaborator

@MichaelHicks-MSFT MichaelHicks-MSFT commented Oct 28, 2024

🗣 Description

Permissions file containing current SCuBAGear permissions mapping.

💭 Motivation and context

Added permissions file to allow centralized management of all SCuBAGear Microsoft Graph permissions.

#1391 is a follow up to this issue, which aims to modify the Connection module to read from the new ScubaPermissions.json file instead of hard coded values.

Closes #1356

🧪 Testing

Testing was conducted across commercial and gcchigh tenants. Created PowerShell code that imported the JSON file and made connections to Microsoft Graph utilizing the permission scopes defined under Permission within the ScubaGearGraphScopes section of the file.

✅ Pre-approval checklist

  • This PR has an informative and human-readable title.
  • PR targets the correct parent branch (e.g., main or release-name) for merge.
  • Changes are limited to a single goal - eschew scope creep!
  • Changes are sized such that they do not touch excessive number of files.
  • All future TODOs are captured in issues, which are referenced in code comments.
  • These code changes follow the ScubaGear content style guide.
  • Related issues these changes resolve are linked preferably via closing keywords.
  • All relevant type-of-change labels added.
  • All relevant project fields are set.
  • All relevant repo and/or project documentation updated to reflect these changes.
  • Unit tests added/updated to cover PowerShell and Rego changes.
  • Functional tests added/updated to cover PowerShell and Rego changes.
  • All relevant functional tests passed.
  • All automated checks (e.g., linting, static analysis, unit/smoke tests) passed.

✅ Pre-merge checklist

  • PR passed smoke test check.

  • Feature branch has been rebased against changes from parent branch, as needed

    Use Rebase branch button below or use this reference to rebase from the command line.

  • Resolved all merge conflicts on branch

  • Notified merge coordinator that PR is ready for merge via comment mention

✅ Post-merge checklist

  • Feature branch deleted after merge to clean up repository.
  • Verified that all checks pass on parent branch (e.g., main or release-name) after merge.

@buidav buidav requested review from buidav and tkol2022 October 28, 2024 21:25
@buidav buidav added the enhancement This issue or pull request will add new or improve existing functionality label Oct 28, 2024
@buidav buidav added this to the Kraken milestone Oct 28, 2024
@buidav buidav linked an issue Oct 28, 2024 that may be closed by this pull request
Copy link
Collaborator

@tkol2022 tkol2022 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Can you move the file from the /Connection folder to a new /Permissions folder instead?
  • I noticed you removed the ScubaGearSPPermissions node. In the future ScubaGear will have a utility script that helps users register a service principal to run the tool. Is the thought that our new utility script can just filter the GraphCmdLetPermissions node for entries that are of runtype = application and just use that list to create the needed permissions for the service principal in Entra Id?
  • We need to add the following REST APIs as entries to the GraphCmdLetPermissions node along with their associated required permissions. Entra Id now includes direct calls to REST APIs without Cmdlets and therefore we need to ensure those permissions are represented.
    • /beta/roleManagement/directory/roleEligibilityScheduleInstances
    • /beta/roleManagement/directory/roleAssignmentScheduleInstances
    • /beta/identityGovernance/privilegedAccess/group/eligibilityScheduleInstances
    • /beta/privilegedAccess/aadGroups/resources

@schrolla schrolla removed the request for review from mitchelbaker-cisa November 4, 2024 18:16
@mitchelbaker-cisa mitchelbaker-cisa changed the title Create ScubaGear-Permissions.json Create a JSON file to store permission scopes required for ScubaGear Nov 5, 2024
Copy link
Collaborator

@schrolla schrolla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor recommendation for the format as we've had code trip over string vs list values before when it isn't consistent.

@mitchelbaker-cisa mitchelbaker-cisa marked this pull request as draft November 7, 2024 19:45
@mitchelbaker-cisa mitchelbaker-cisa force-pushed the main branch 2 times, most recently from 40c59a0 to 23a7323 Compare December 7, 2024 01:28
@mitchelbaker-cisa mitchelbaker-cisa marked this pull request as ready for review December 7, 2024 01:28
Copy link
Collaborator

@schrolla schrolla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found a few more multi-valued fields that are represented as strings when singletons. Recommend consistently representing as multi-valued structure (array or dictionary) to make the structure easier to traverse in all cases. Specific fields and examples are included in review comments below.

@mitchelbaker-cisa
Copy link
Collaborator

Updated leastPermissions and poshModule keys to array type.

"dod": "https://{domain}-admin.sharepoint.mil.us"
},
"poshModule": ["Microsoft.Online.SharePoint.PowerShell"],
"leastPermissions": ["Sites.FullControl.All"],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Connect-SPOService doesn't support Service Principal auth. This should be empty array.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A new property was added to indicate noninteractive permissions, "spRolePermissions": []. @buidav does that resolve your comment? Or are additional changes needed.

@schrolla schrolla removed this from the Kraken milestone Dec 18, 2024
@tkol2022
Copy link
Collaborator

tkol2022 commented Feb 6, 2025

Testing Instructions for Interactive authentication

The purpose of this set of tests is to exercise the new pieces of code with an interactive login. There will be separate instructions for testing with service principal.

Preparation

Download the main branch and run ScubaGear to create a local scuba results json file which will be used later in a comparison. Run with aad, defender and sharepoint. Include the same products when you run the new code in the steps below.

Download https://github.com/MichaelHicks-MSFT/ScubaGear/tree/main to a local folder /PermissionsJSON

Test 1 - Ensure Get-ScubaGearPermissions sets up up the correct permissions for ScubaGear to run interactively and ScubaGear produces the expected output json and policy results

Go to Microsoft Graph Powershell in the Entra Id > Enterprise Applications and click on Permissions
Delete the application from the tenant (this way the permissions will be cleaned out and then recreated the next time that ScubaGear is run)
Go to the PermissionsJSON folder and run ScubaGear interactively. Consent to the permissions for the organization (this is important because it allows others on the team to be able to run ScubaGear interactively).
This should create a Scuba results file

Compare this file against the Scuba results file created from the main branch and ensure that there are no differences that would indicate that the new Powershell code changes had any material effect on the items below. Ignore timestamp and ReportUUID differences.

  • The provider JSON that gets created
  • The results of the Rego tests

If there are differences between the two files, this indicates that the introduction of the Get-ScubaGearPermissions cmdlet may have introduced a bug.

Test 2 - Ensure Get-ScubaGearPermissions does not generate any permissions errors (e.g. 401)

Examine the Powershell window where the PermissionsJSON branch was executed and note any permissions errors (e.g. "unauthorized")

Test 3 -Determine if there are any differences in the permissions created in the tenant that require a review

Go to the Entra Id > Enterprise Applications and open the permissions for the Microsoft Graph Powershell app. These are the permissions created by running the PermissionsJSON with the new Get-ScubaGearPermissions cmdlet in the Connect-Tenant code.
Compare the permissions to another tenant for the same app Microsoft Graph Powershell and note any differences

…ncipal PR. Updated interactive and noninteractive markdowns to account for new permissions.
@tkol2022
Copy link
Collaborator

Test Results for Interactive authentication - E5 tenant

Test 1 - Ensure Get-ScubaGearPermissions sets up up the correct permissions for ScubaGear to run interactively

Compared the configuration settings export and policy check results. No difference between the main branch versus this one. Pass.

Test 2 - Ensure Get-ScubaGearPermissions does not generate any permissions errors (e.g. 401)

No permissions errors observed in the console. Pass.

Test 3 -Determine if there are any differences in the permissions created in the tenant that require a review

Some new permissions that were not there before were requested for the MS Graph Powershell (Microsoft Graph Command Line Tools) service principal. After discussion with the MS team, this is because each of the cmdlets documented in the JSON permissions include the least privileged permission required to execute the respective cmdlet. Pass.

@tkol2022
Copy link
Collaborator

Test Results for Interactive authentication - G3 tenant

Test 1 - Ensure Get-ScubaGearPermissions sets up up the correct permissions for ScubaGear to run interactively

Pass.

Test 2 - Ensure Get-ScubaGearPermissions does not generate any permissions errors (e.g. 401)

Pass.

Test 3 -Determine if there are any differences in the permissions created in the tenant that require a review

Pass.

@tkol2022
Copy link
Collaborator

Test Results for Interactive authentication - GCC High tenant

Test 1 - Ensure Get-ScubaGearPermissions sets up up the correct permissions for ScubaGear to run interactively

Pass.

Test 2 - Ensure Get-ScubaGearPermissions does not generate any permissions errors (e.g. 401)

Pass.

Test 3 -Determine if there are any differences in the permissions created in the tenant that require a review

Pass.

…xchange online protection for gcchigh/dod. Fixed the id for api output.

Created a new unit test to validate the permissions helper module.
Updated ScubaGear redundant permissions function (Get-ScubaGearEntraRedundantPermissions).
Added all environments to the Invoke-GraphDirectly unit tests.
@tkol2022
Copy link
Collaborator

Should the cmdlet Get-ScubaGearEntraRedundantPermissions be renamed to Get-ScubaGearEntraMinimumPermissions? hopefully I understood the intent of the function.

image

@tkol2022
Copy link
Collaborator

tkol2022 commented Feb 11, 2025

Testing Instructions for Non-Interactive authentication

The purpose of this set of tests is to exercise the new pieces of code with an non-interactive login using a service principal.

Preparation

Download the main branch and run ScubaGear to create a local scuba results json file which will be used later in a comparison. Run with aad, defender and sharepoint. Include the same products when you run the new code in the steps below.

Download https://github.com/MichaelHicks-MSFT/ScubaGear/tree/main to a local folder /PermissionsJSON

Create a new registered app in the test tenant named: ScubaGearPermissionsJSON
Upload your certificate to the new app
Run the new cmdlet which generates a list of the minimum Graph permissions needed for a service principal as per below:
Get-ScubaGearEntraRedundantPermissions

image

Go into the permissions page for the new registered app and add the Graph permissions listed by the previous cmdlet
Add the application permissions needed for Exchange Online and Sharepoint Online to the new registered app
Assign the role of Global Reader to the new app

From here on out, you will use the newly registered application ScubaGearPermissionsJSON to authenticate to ScubaGear for the tests and your certificate.

Test 1 - Ensure that Connect-Tenant in ScubaGear works correctly with non interactive auth and ScubaGear produces the expected output json and policy results

Invoke ScubaGear with the new service principal and your certificate to generate a scuba results JSON file

Compare this file against the Scuba results file created from the main branch and ensure that there are no differences that would indicate that the new Powershell code changes had any material effect on the items below. Ignore timestamp and ReportUUID differences.

  • The provider JSON that gets created
  • The results of the Rego tests

If there are differences between the two files, this indicates that the introduction of the Get-ScubaGearPermissions cmdlet may have introduced a bug.

Test 2 - Ensure Get-ScubaGearPermissions does not generate any permissions errors (e.g. 401)

Examine the Powershell window where the PermissionsJSON branch was executed and note any permissions errors (e.g. "unauthorized")

@tkol2022
Copy link
Collaborator

Test Results for Non-Interactive authentication - GCC High, E5 and G3 tenants

The tests were performed on all tenant types listed above. I created a brand new application to test with in each tenant and gave it the permissions listed by the Get-ScubaGearEntraRedundantPermissions cmdlet.

Test 1 - Ensure that Connect-Tenant in ScubaGear works correctly with non interactive auth and ScubaGear produces the expected output json and policy results

Pass.

Test 2 - Ensure Get-ScubaGearPermissions does not generate any permissions errors (e.g. 401)

Pass.

@tkol2022
Copy link
Collaborator

Testing changes to Invoke-GraphDirectly

The AAD export provider function Invoke-GraphDirectly was tested indirectly by executing ScubaGear against Entra Id in three tenant types. No issues observed.

@tkol2022
Copy link
Collaborator

Consider initializing the variable $objects before it is used.
$objects = @()

image

@tkol2022
Copy link
Collaborator

Tested parameter validation of Get-ScubaGearPermissions and behaves as expected.

image

@tkol2022
Copy link
Collaborator

tkol2022 commented Feb 11, 2025

I have completed my review. Outstanding enhancement!

@buidav and @mitchelbaker-cisa Here are the remaining items for review (you can split up the work if you like):

  • Unit tests PermissionsHelper.Tests.ps1
  • Unit tests Invoke-GraphDirectly.Tests.ps1
  • Run against G5 using a fresh service principal and the instructions I included in the pull request comments
  • @buidav review changes to interactive.md and noninteractive.md since you recently made changes to these files and know the permissions requirements extremely well.

@DickTracyII @MichaelHicks-MSFT Left some minor final comments but the major items were tested.

Thank you.

@buidav buidav self-requested a review February 11, 2025 21:47
@schrolla schrolla modified the milestones: Lionfish, Marlin Feb 12, 2025
@buidav
Copy link
Collaborator

buidav commented Feb 12, 2025

@DickTracyII @MichaelHicks-MSFT this PR will have to solve some major merge conflicts with
docs/prerequisites/noninteractive.md
My fault there as I didn't realize this PR was making changes to the same file at the time.

@tkol2022
Copy link
Collaborator

I was using ScubaGearPermissions.json as a reference for another issue that I'm working on and I noticed we are missing Get-MgBetaDirectoryObject from the file.

@MichaelHicks-MSFT
Copy link
Collaborator Author

I was using ScubaGearPermissions.json as a reference for another issue that I'm working on and I noticed we are missing Get-MgBetaDirectoryObject from the file.

I will add that to the file.

@tkol2022
Copy link
Collaborator

@tkol2022 tkol2022 closed this Feb 26, 2025
@schrolla schrolla removed this from the Marlin milestone Feb 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement This issue or pull request will add new or improve existing functionality
Projects
None yet
6 participants