{
  "id": "ZcY7FluJUhdfeQAH",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Audit SharePoint for externally shared Items and anonymous permissions",
  "tags": [
    {
      "id": "0FRymMOqi6UCCYTI",
      "name": "free",
      "createdAt": "2025-12-25T11:06:36.527Z",
      "updatedAt": "2025-12-25T11:06:36.527Z"
    },
    {
      "id": "9ByOAYkeSAaYnPEB",
      "name": "demo",
      "createdAt": "2025-12-31T15:16:02.575Z",
      "updatedAt": "2025-12-31T15:16:02.575Z"
    },
    {
      "id": "ks1tninGT7ZLrbrc",
      "name": "template",
      "createdAt": "2025-12-31T15:16:19.399Z",
      "updatedAt": "2025-12-31T15:16:19.399Z"
    }
  ],
  "nodes": [
    {
      "id": "391d1525-c97e-448d-b9dc-dc65ffbeb812",
      "name": "When clicking \u2018Execute workflow\u2019",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -240,
        48
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "b7e5ccf2-efd4-4f9c-ae10-99bcdf478a36",
      "name": "Sharepoint - Get Sites",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        208,
        48
      ],
      "parameters": {
        "url": "https://graph.microsoft.com/v1.0/sites?search=*",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "oAuth2Api"
      },
      "credentials": {
        "oAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "6bb7b44f-2310-4281-a2c3-b71307b5dcc0",
      "name": "Split Out - Sites",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        464,
        48
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "value"
      },
      "typeVersion": 1
    },
    {
      "id": "7b6c6ae8-8ecb-4014-b9ea-22ee0fd83ceb",
      "name": "SharePoint - Get Drives",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        912,
        48
      ],
      "parameters": {
        "url": "=https://graph.microsoft.com/v1.0/sites/{{ $json.id }}/drives?$select=id,name,webUrl",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "oAuth2Api"
      },
      "credentials": {
        "oAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "4cc6b4aa-930e-4d30-821e-c13460646a45",
      "name": "Split Out - Drives",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        1136,
        48
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "value"
      },
      "typeVersion": 1
    },
    {
      "id": "75787384-eb3f-4522-b1e6-4fe823e0937d",
      "name": "SharePoint - Get Item Permissions",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1584,
        -48
      ],
      "parameters": {
        "url": "=https://graph.microsoft.com/v1.0/drives/{{ $('Split Out - Drives').item.json.id }}/items/{{ $json.id }}/permissions",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "oAuth2Api"
      },
      "credentials": {
        "oAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "bd4f2f37-6ee6-4889-8990-af9f8211da68",
      "name": "Filter Items based on permissions",
      "type": "n8n-nodes-base.code",
      "position": [
        2256,
        48
      ],
      "parameters": {
        "jsCode": "const TENANT_DOMAINS = $('Set Variables').first().json.tenantDomains\n\nfunction normStr(x) {\n  return (x ?? \"\").toString().trim();\n}\n\nfunction isExternalLoginName(loginName) {\n  const ln = normStr(loginName).toLowerCase();\n  // Strong SPO guest signals\n  return ln.includes(\"#ext#\") || ln.includes(\"urn:spo:guest\");\n}\n\nfunction domainFromEmail(email) {\n  const e = normStr(email).toLowerCase();\n  const at = e.lastIndexOf(\"@\");\n  return at >= 0 ? e.slice(at + 1) : \"\";\n}\n\nfunction isInternalDomain(domain) {\n  const d = normStr(domain).toLowerCase();\n  if (!d) return false;\n  return TENANT_DOMAINS.some(td => td.toLowerCase() === d);\n}\n\nfunction isExternalEmail(email) {\n  if (!TENANT_DOMAINS.length) return false; // domains disabled\n  const d = domainFromEmail(email);\n  if (!d) return false;\n  return !isInternalDomain(d);\n}\n\nfunction itemType(item) {\n  if (item?.folder) return \"folder\";\n  if (item?.file) return \"file\";\n  return \"unknown\";\n}\n\nconst results = [];\n\nfor (const inItem of $input.all()) {\n  const json = inItem.json;\n\n  const spItem = json.item || {};\n  const perms = json.permissions?.value || [];\n\n  let hasAnonymousLink = false;\n  let hasExternalPrincipal = false;\n\n  const anonymousLinks = [];     // link permissions\n  const externalPrincipals = []; // external users detected\n\n  for (const p of perms) {\n    // ---- 1) Anonymous links ----\n    const link = p?.link;\n    if (link && normStr(link.scope).toLowerCase() === \"anonymous\") {\n      hasAnonymousLink = true;\n      anonymousLinks.push({\n        permissionId: p.id ?? null,\n        roles: p.roles ?? [],\n        linkType: link.type ?? null,        // view/edit\n        webUrl: link.webUrl ?? null,\n        hasPassword: p.hasPassword ?? null,\n        preventsDownload: link.preventsDownload ?? null,\n      });\n    }\n\n    // ---- 2) External/guest principals ----\n    // Graph commonly includes external users under grantedToIdentitiesV2[].siteUser.loginName with #ext#\n    const granted = Array.isArray(p?.grantedToIdentitiesV2) ? p.grantedToIdentitiesV2 : [];\n\n    for (const ident of granted) {\n      const loginName = ident?.siteUser?.loginName;\n      const email = ident?.user?.email || ident?.siteUser?.email;\n\n      const externalByLogin = loginName ? isExternalLoginName(loginName) : false;\n      const externalByEmail = email ? isExternalEmail(email) : false;\n\n      if (externalByLogin || externalByEmail) {\n        hasExternalPrincipal = true;\n        externalPrincipals.push({\n          permissionId: p.id ?? null,\n          roles: p.roles ?? [],\n          displayName: ident?.user?.displayName || ident?.siteUser?.displayName || null,\n          email: email ?? null,\n          loginName: loginName ?? null,\n          linkScope: link?.scope ?? null,\n          linkType: link?.type ?? null,\n          linkWebUrl: link?.webUrl ?? null,\n        });\n      }\n    }\n  }\n\n  // Drop items that have neither anonymous nor external principals\n  if (!hasAnonymousLink && !hasExternalPrincipal) continue;\n\n  const out = {\n    // Item identity / navigation\n    name: spItem.name ?? null,\n    type: itemType(spItem),\n    webUrl: spItem.webUrl ?? null,\n    lastModifiedDateTime: spItem.lastModifiedDateTime ?? null,\n\n    // IDs that help you trace back\n    itemId: spItem.id ?? null,\n    driveId: spItem.parentReference?.driveId ?? null,\n    siteId: spItem.parentReference?.siteId ?? null,\n    parentId: spItem.parentReference?.id ?? null,\n    libraryName: spItem.parentReference?.name ?? null,\n\n    // Flags + details\n    externalSharing: {\n      hasAnonymousLink,\n      hasExternalPrincipal,\n    },\n    details: {\n      anonymousLinks,\n      anonymousLinkCount: anonymousLinks.length,\n      externalPrincipals,\n      externalPrincipalCount: externalPrincipals.length,\n    },\n  };\n\n  results.push({ json: out });\n}\n\nreturn results;\n"
      },
      "notesInFlow": true,
      "typeVersion": 2
    },
    {
      "id": "2f255329-4952-4b66-b6a4-88a6e1854e8b",
      "name": "SharePoint - Get Items",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        256,
        -272
      ],
      "parameters": {
        "url": "=https://graph.microsoft.com/v1.0/drives/{{ $json.driveId }}/root/children?$select=id,name,webUrl,folder,file,parentReference,lastModifiedDateTime",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "oAuth2Api"
      },
      "credentials": {
        "oAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "1c02f2f3-2b74-408a-8b22-414e4e2993ed",
      "name": "Split Out - Items",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        480,
        -368
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "value"
      },
      "typeVersion": 1
    },
    {
      "id": "79229b75-eb39-4739-9466-d2e621bb890c",
      "name": "If Item is not a folder",
      "type": "n8n-nodes-base.if",
      "position": [
        704,
        -368
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "5ac50e73-4807-4c85-8f27-a18faa2ca38b",
              "operator": {
                "type": "object",
                "operation": "notExists",
                "singleValue": true
              },
              "leftValue": "={{ $json.folder }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "0a640d58-a1b0-4ee3-8f4f-2491d1c2fd1c",
      "name": "If Input is a Folder",
      "type": "n8n-nodes-base.if",
      "position": [
        32,
        -368
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "5ac50e73-4807-4c85-8f27-a18faa2ca38b",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json.folderId }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "2c4cdf8c-c6ae-44c6-9c96-6fb129a49a0f",
      "name": "SharePoint - Get Child Items",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        256,
        -464
      ],
      "parameters": {
        "url": "=https://graph.microsoft.com/v1.0/drives/{{ $('Subworkflow - Get Items').item.json.driveId }}/items/{{ $('Subworkflow - Get Items').item.json.folderId }}/children?$select=id,name,webUrl,folder,file,parentReference,lastModifiedDateTime",
        "method": "=GET",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "oAuth2Api"
      },
      "credentials": {
        "oAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "23b1b844-83e6-4736-9856-44619eaa201a",
      "name": "Call 'Audit SharePoint for externally shared Items and anonymous permissions'",
      "type": "n8n-nodes-base.executeWorkflow",
      "position": [
        1360,
        48
      ],
      "parameters": {
        "mode": "each",
        "options": {},
        "workflowId": {
          "__rl": true,
          "mode": "list",
          "value": "ZcY7FluJUhdfeQAH",
          "cachedResultUrl": "/workflow/ZcY7FluJUhdfeQAH",
          "cachedResultName": "S&S \u2014 Audit SharePoint for externally shared Items and anonymous permissions"
        },
        "workflowInputs": {
          "value": {
            "driveId": "={{ $json.id }}"
          },
          "schema": [
            {
              "id": "driveId",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "driveId",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "folderId",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "folderId",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "57f5e7da-4606-48f3-b0be-e4e4892baa34",
      "name": "Subworkflow - Get Items",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "position": [
        -192,
        -368
      ],
      "parameters": {
        "workflowInputs": {
          "values": [
            {
              "name": "driveId"
            },
            {
              "name": "folderId"
            }
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "febdef38-e5f5-4876-92c3-6a24de3ca7bb",
      "name": "Recursive call Get Items",
      "type": "n8n-nodes-base.executeWorkflow",
      "position": [
        928,
        -304
      ],
      "parameters": {
        "options": {},
        "workflowId": {
          "__rl": true,
          "mode": "list",
          "value": "4sofE1bF0zs6pvOm",
          "cachedResultUrl": "/workflow/4sofE1bF0zs6pvOm",
          "cachedResultName": "S&S \u2014 Get Items"
        },
        "workflowInputs": {
          "value": {
            "driveId": "={{ $('Subworkflow - Get Items').item.json.driveId }}",
            "folderId": "={{ $json.id }}"
          },
          "schema": [
            {
              "id": "driveId",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "driveId",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "folderId",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "folderId",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "driveId"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "e2e85ed5-1175-46ad-a4f3-1c43f1a8fb24",
      "name": "Return All Data",
      "type": "n8n-nodes-base.set",
      "position": [
        1376,
        -368
      ],
      "parameters": {
        "options": {},
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "12e4b940-3092-4cf8-b667-4ba1694cd5ce",
      "name": "Keept Items and Folders",
      "type": "n8n-nodes-base.merge",
      "position": [
        1152,
        -384
      ],
      "parameters": {
        "numberInputs": 3
      },
      "typeVersion": 3.2
    },
    {
      "id": "8a947652-d218-45e9-ae42-bcaa86f38f7c",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        2032,
        48
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "b58ee602-1edd-4abe-9c34-3212a747883c",
      "name": "Rename Output for Permissions",
      "type": "n8n-nodes-base.set",
      "position": [
        1808,
        -48
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "622b739e-ef74-423a-bf03-8425dc5acb2e",
              "name": "permissions",
              "type": "object",
              "value": "={{ $json }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "bb15647d-31f2-4731-9ad9-7ad5d8ab0563",
      "name": "Rename Output for Item",
      "type": "n8n-nodes-base.set",
      "position": [
        1808,
        144
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "622b739e-ef74-423a-bf03-8425dc5acb2e",
              "name": "item",
              "type": "object",
              "value": "={{ $json }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "e4906c3c-8167-4ce1-938f-5bca326cb859",
      "name": "Set Variables",
      "type": "n8n-nodes-base.set",
      "position": [
        -16,
        48
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "ff8c328c-1c79-4613-a44b-232c8a8ea08c",
              "name": "tenantDomains",
              "type": "array",
              "value": "[ \"yourDomain1.onmicrosoft.com\", \"yourDomain1.com\" ]"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "138d381b-9ff1-4b9b-b994-cf78c65f11a6",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -896,
        -544
      ],
      "parameters": {
        "width": 592,
        "height": 448,
        "content": "## How it works\n- Fetches all SharePoint sites via Microsoft Graph\n- Retrieves document libraries for each site\n- Recursively traverses folder and file structures\n- Fetches permissions for every item\n- Analyzes permissions for anonymous links or external users\n- Outputs only externally shared items\n\n## Setup Requirements\n1. **Microsoft Entra ID app registration**\n   - Grant **Microsoft Graph \u2013 Application permissions**\n     - `Sites.Read.All`\n   - Add the credential to all HTTP request nodes\n\n2. **Configure tenant domains**\n   - Add your tenant domains in the `Set Variables` node\n   - These domains are used to identify internal and flag external users"
      },
      "typeVersion": 1
    },
    {
      "id": "3074474e-494f-4374-9a36-5c8d24433b3c",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -896,
        240
      ],
      "parameters": {
        "color": 6,
        "width": 592,
        "content": "### Notes\n- Requires EntraID Application\n- Use Client Credentials when adding the OAuth2 credentials in n8n\n- Use a schedule trigger to automatically run this\n- Refactor the subworkflow in its own workflow for better execution tracking\n- Need help? \u2709\ufe0f **office@sus-tech.at**"
      },
      "typeVersion": 1
    },
    {
      "id": "5853d909-6d09-4793-ac72-a11903c3e557",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1072,
        -112
      ],
      "parameters": {
        "color": 7,
        "width": 448,
        "height": 352,
        "content": "## Recursively traverse through items\nFor each drive start recursive process at root level"
      },
      "typeVersion": 1
    },
    {
      "id": "7db855ff-2d97-424f-a9e0-6faf5f3e6c78",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        640,
        -496
      ],
      "parameters": {
        "color": 7,
        "width": 448,
        "height": 352,
        "content": "## If Item is a folder, go into folder"
      },
      "typeVersion": 1
    },
    {
      "id": "18a03db6-92e4-439d-a036-fd17b085187c",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1104,
        -496
      ],
      "parameters": {
        "color": 7,
        "width": 448,
        "height": 352,
        "content": "## Merge Output\nKeep all traversed items: folders and files as each can have its own permissions"
      },
      "typeVersion": 1
    },
    {
      "id": "64da6e50-8566-4818-b2ed-780f5b535f47",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        128,
        -112
      ],
      "parameters": {
        "color": 7,
        "width": 928,
        "height": 352,
        "content": "## Get top level Sharepoint structure\nGets sites and drives as top level entry points for the traversal of their contents; Also filters out contentstorage sites as they are system area created by microsoft apps"
      },
      "typeVersion": 1
    },
    {
      "id": "2c266637-42e9-43bc-b161-224c5ef6b8d1",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1536,
        -112
      ],
      "parameters": {
        "color": 7,
        "width": 656,
        "height": 416,
        "content": "## Combine and filter the outputs"
      },
      "typeVersion": 1
    },
    {
      "id": "f8a2ba04-c2fb-4515-99be-0b8c97fb3a51",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -896,
        -80
      ],
      "parameters": {
        "color": 4,
        "width": 592,
        "height": 304,
        "content": "## How data is filtered\nWhat `Filter Items based on permissions` does for each input item:\n* Reads your **internal tenant domains** from the \u201cSet Variables\u201d node\n* Scans the item\u2019s `permissions.value` and flags:\n  * **Anonymous sharing links** (`link.scope === \"anonymous\"`)\n  * **External/guest users** granted access, detected either by:\n    * SharePoint guest login markers like `#ext#` or `urn:spo:guest`, or\n    * An email domain **not** in your tenant domains list.\n* **Drops** any item that has **neither** an anonymous link **nor** an external principal.\n* For items that match, outputs a compact record with **item metadata** and **sharing flags and detailed lists** of the anonymous links and external users found.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "bc28fdb6-4a3a-4c0a-bf35-0bf7ae7227de",
      "name": "Filter sites",
      "type": "n8n-nodes-base.filter",
      "position": [
        672,
        48
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "2358a17a-06b1-460f-99d6-5b9f58b957c2",
              "operator": {
                "type": "string",
                "operation": "notContains"
              },
              "leftValue": "={{ $json.webUrl }}",
              "rightValue": "contentstorage"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "33f787c8-d74e-4a1c-9c6b-834637c5cabe",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        -544
      ],
      "parameters": {
        "color": 7,
        "width": 624,
        "height": 400,
        "content": "## Get Items\nDifferentiates whether to get items of root level drives or to get child items for folders"
      },
      "typeVersion": 1
    }
  ],
  "active": true,
  "settings": {
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "8b1b8a22-d8b5-419e-9671-4418197d8527",
  "connections": {
    "Merge": {
      "main": [
        [
          {
            "node": "Filter Items based on permissions",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter sites": {
      "main": [
        [
          {
            "node": "SharePoint - Get Drives",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Variables": {
      "main": [
        [
          {
            "node": "Sharepoint - Get Sites",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out - Items": {
      "main": [
        [
          {
            "node": "If Item is not a folder",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out - Sites": {
      "main": [
        [
          {
            "node": "Filter sites",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out - Drives": {
      "main": [
        [
          {
            "node": "Call 'Audit SharePoint for externally shared Items and anonymous permissions'",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If Input is a Folder": {
      "main": [
        [
          {
            "node": "SharePoint - Get Child Items",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "SharePoint - Get Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Rename Output for Item": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "SharePoint - Get Items": {
      "main": [
        [
          {
            "node": "Split Out - Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sharepoint - Get Sites": {
      "main": [
        [
          {
            "node": "Split Out - Sites",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If Item is not a folder": {
      "main": [
        [
          {
            "node": "Keept Items and Folders",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Recursive call Get Items",
            "type": "main",
            "index": 0
          },
          {
            "node": "Keept Items and Folders",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Keept Items and Folders": {
      "main": [
        [
          {
            "node": "Return All Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SharePoint - Get Drives": {
      "main": [
        [
          {
            "node": "Split Out - Drives",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Subworkflow - Get Items": {
      "main": [
        [
          {
            "node": "If Input is a Folder",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Recursive call Get Items": {
      "main": [
        [
          {
            "node": "Keept Items and Folders",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "SharePoint - Get Child Items": {
      "main": [
        [
          {
            "node": "Split Out - Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Rename Output for Permissions": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SharePoint - Get Item Permissions": {
      "main": [
        [
          {
            "node": "Rename Output for Permissions",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking \u2018Execute workflow\u2019": {
      "main": [
        [
          {
            "node": "Set Variables",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Call 'Audit SharePoint for externally shared Items and anonymous permissions'": {
      "main": [
        [
          {
            "node": "SharePoint - Get Item Permissions",
            "type": "main",
            "index": 0
          },
          {
            "node": "Rename Output for Item",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}