SharePoint sites shared with Everyone and Microsoft Delve issue

There is was a known problem with Microsoft Delve. It’s not a technology problem though. (Upd: Delve is scheduled for retirement in Dec 2024)

We know SharePoint site permissions are not easy to manage. E.g. you can break permissions inheritance at any level – subsite, library, list, folder, list item or specific document. Anybody with full permissions can do that. The worst thing is there is was (*1) no native ability for site owner to get full site permissions report. We must have used third-party tools or PowerShell to have all permissions in one document.

So no wonder SharePoint sites were heavily over-exposed. Especially when a site owner tired with complexity of SharePoint permissions system decided to share resource with “Everyone”. And the other person, not knowing site is shared with everyone, might save some sensitive data. That is the real issue.

Now, what is Delve? It’s a service that
– get signals from allover Office 365 – who did what etc.
– based on that, using AI and Office Graph, generates suggestions – “what others do”.
Of course, Delve is security-trimmed, i.e. it will neve suggest you a document you do not have access to. But some sites might be overshared. Delve works as it should work – it suggests you documents it believes related to you (based on Microsoft Graph insights) and you already have access to.

Now bad thing happens – people start seeing documents they never new they have access to. Where are these documents from? Of course from sites shared with Everyone. Who to blame for the security breach? Delve? Microsoft Graph? Microsoft 365 SharePoint Online?

Strictly says, it is not Delve’s problem. It’s more human problem than technological.
Delve just does it’s job, and does perfectly. Delve simply displays the information already shared widely.

How do we solve the issue?

  1. Disable Delve?
  2. Disable search (stop sites crawling and remove results)?
  3. Restrict users who can provide signals via item insights privacy?
    see Microsoft KBA on how to disable MS Graph for a specific User

Those methods are half-measure. Methods above are just hiding the problem – not solving it. Agree it helps stop the deterioration, bud does not fix the root cause.

How do we solve the real problem and what is the root cause?

  1. Of course, we need remove incorrectly provided permissions. How?
  2. Only site owner (data owner) knows which content should be shared with whom with which access rights. So we need to ask sites owners to review their permissions. How?
  3. First, we need a list of over-exposed sites. How?
  4. There are two methods (more details – check this article)
    • Brute force – use PowerShell or 3-rd party tool to get permission report on all sites in tenant, select permissions provided for Everyone…
    • Smart move – use Microsoft search. As search is security-trimmed, we can search for available content on behalf of a user with no permissions provided.
  5. Then we find owners for each wide-open site. How?
    • for group-based sites we get member of the “owners” group
    • for non-group based sites we get site collection administrators
  6. We would also sort sites by “is it supposed to be public?”. I.e. if the site was born as public – e.g. Public Team or Public Yammer community – or Communication site – maybe it’s less concern.
  7. It would be a good idea to bring DLP and/or automatic content sensitivity labelling, so we could start remediation from sites labelled as storing most sensitive data.
  8. Finally, we need to let site owner know that his site is Open to everybody and ask to fix it. How?


References

Bill Baer’s on search and “prevent sensitive files from being exposed in search”

PnP.PowerShell Release 1.3.0

Great news:

Added -Interactive login option to Connect-PnPOnline which is similar to -UseWebLogin but without the limitations of the latter. The -UseWebLogin is using cookie based authentication towards SharePoint and cannot access Graph tokens. Using -Interactive we use Azure AD Authentication and as a result we are able to acquire Graph tokens.

more changes: https://github.com/pnp/powershell/releases/tag/1.3.0

Power Apps functions/code hints

OnNew:
Set(SharePointFormMode, “NewForm”); NewForm(formNew); Navigate(screenNew, ScreenTransition.None)

OnEdit:
Set(SharePointFormMode, “EditForm”); EditForm(formEdit); Navigate(screenEdit, ScreenTransition.None)

OnView:
Set(SharePointFormMode, “ViewForm”); ViewForm(formView); Navigate(screenView, ScreenTransition.None)

OnSave – If(SharePointFormMode=”CreateForm”, SubmitForm(CreateItemForm), If(SharePointFormMode=”EditForm”, SubmitForm(EditItemForm)))

OnCancel – If(SharePointFormMode=”CreateForm”, ResetForm(CreateItemForm), If(SharePointFormMode=”EditForm”, ResetForm(EditItemForm)))

Connect-PnPOnline with a certificate stored in Azure Key Vault

Scenario

You run some PnP PowerShell code unattended e.g. daemon/service app, background job – under application permissions – with no user interaction.
Your app needs to connect to SharePoint and/or Microsoft Graph API. Your organization require authentication with a certificate (no secrets). You want certificate stored securely in Azure Key Vault.

Solution (Step-by-step process)

  1. Obtain a certificate (create a self-signed or request trusted)
  2. In Azure where you have Microsoft 365 SharePoint tenant
    1. Create a new Registered App in Azure; save App (client) id, Directory (Tenant) Id
    2. Configure App: add MS Graph and SharePoint API application (not delegated) permissions
    3. Upload the certificate to the app under “Certificates & secrets”
  3. In Azure where you have paid subscription (could be same or different)
    1. Create an Azure Key Vault
    2. Upload certificate to the Key Vault manually (with GUI)
  4. While you develop/debug your custom daemon application at your local machine
    1. Provide permissions to the Key Vault via Access Control and Access Policies to your personal account
    2. Connect to Azure (the one where your Key Vault is) running Connect-AzAccount
      – so your app can get a Certificate to authenticate to SharePoint Online
  5. For your application deployed to Azure (e.g. Azure Function App )
    1. Turn On managed identity (Your Function App -> Identity -> Status:On) and Save; notice an Object (Principal) Id just created
    2. Provide for your managed identity principal Id permissions to the Key Vault via Key Vault Access Policies, so when your daemon app is running in the cloud – it could go to the key Vault and retrieve Certificate

Here is the sample PowerShell code to get certificate from Azure Key Vault and Connect to SharePoint with PnP (Connect-PnPOnline):

# ensure you use PowerShell 7
$PSVersionTable

# connect to your Azure subscription
Connect-AzAccount -Subscription "<subscription id>" -Tenant "<tenant id>"
Get-AzSubscription | fl
Get-AzContext

# Specify Key Vault Name and Certificate Name
$VaultName = "<azure key vault name>"
$certName = "certificate name as it stored in key vault"

# Get certificate stored in KeyVault (Yes, get it as SECRET)
$secret = Get-AzKeyVaultSecret -VaultName $vaultName -Name $certName
$secretValueText = ($secret.SecretValue | ConvertFrom-SecureString -AsPlainText )

# connect to PnP
$tenant = "contoso.onmicrosoft.com" # or tenant Id
$siteUrl = "https://contoso.sharepoint.com"
$clientID = "<App (client) Id>" # Azure Registered App with the same certificate and API permissions configured
Connect-PnPOnline -Url $siteUrl -ClientId $clientID -Tenant $tenant -CertificateBase64Encoded $secretValueText

Get-PnPSite

The same PowerShell code in GitHub: Connect-PnPOnline-with-certificate.ps1

References:

Yammer API with PowerShell: Private groups and messages

As an Office 365 administrator, I would like to get some reports on Yammer with PowerShell. How it’s done?

Patrick Lamber wrote a good article here: “Access the Yammer REST API through PowerShell“. The only I would add (important!) is:

By default, even with a Verified Admin token, you do not have access to private messages and private groups content.
To get private stuff, you need select “Private Content Mode” under Yammer Admin Center -> Content and Security -> Content Mode:

Check Microsoft: “Monitor private content in Yammer” and
Yammer: “Verified Admin Private Content Mode

If you do not have “Private Content Mode” set up, you might see some weird “Invoke-WebRequest” errors like:

VSCode, PowerShell, .Net and GitHub hints

Dotnet (.net core, .net 5) useful commands:

dotnet --info
dotnet new sln
dotnet new webapi -o API
dotnet sln add APi
dotnet watch run
dotnet dev-certs https --trust
dotnet new gitignore

Visual Studio Code setup:

Some useful plug-ins:

  • PowerShell from Microsoft
  • GitHub pull requests and issues from GitHub
  • C# from Microsoft
    (+ ^P assets)
  • C# Extensions from JosKreativ
  • Material Icon Theme from Philipp Kief
  • Bracket Pair Colorizer 2

VS Code basic configuration:
– AutoSave
– Font Size
– Hide folders: Settings->Exclude “**/obj” “**/bin”
– Compact folders: Settings->”Compact folders”
– appsettings.Development.json: “Microsoft”: “Warning” -> “Microsoft”: “Information”
– launchSettings.json:
“launchBrowser”: true/false,
“launchUrl”

Git basic commands:

git init
create gitignore (dotnet new gitignore)
add appsettings.json to gitignore
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/orgName/AppName.git
git push -u origin main
git config --global credential.helper wincred
git config --global user.name "<John Doe>"
git config --global user.email <johndoe@example.com>