{
  "id": "aFT2sZLs4uXK2nN9",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Audit permissions in Confluence to ensure compliance",
  "tags": [
    {
      "id": "0FRymMOqi6UCCYTI",
      "name": "free",
      "createdAt": "2025-12-25T11:06:36.527Z",
      "updatedAt": "2025-12-25T11:06:36.527Z"
    },
    {
      "id": "ks1tninGT7ZLrbrc",
      "name": "template",
      "createdAt": "2025-12-31T15:16:19.399Z",
      "updatedAt": "2025-12-31T15:16:19.399Z"
    }
  ],
  "nodes": [
    {
      "id": "d3b5305d-3096-48e0-8bcf-25d821cb1eb2",
      "name": "When clicking \u2018Execute workflow\u2019",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -1200,
        -288
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "9b661e69-3b88-400f-94be-b265c16ee0f2",
      "name": "Set Variables",
      "type": "n8n-nodes-base.set",
      "position": [
        -976,
        -288
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "0d1afc81-e801-46dc-b23e-a6a2b00e69e3",
              "name": "atlassianDomain",
              "type": "string",
              "value": "https://yourDomain.atlassian.net"
            },
            {
              "id": "67cd8d60-6c1b-4913-be82-866f80dbea3b",
              "name": "spaceKeys",
              "type": "string",
              "value": "space1, space2"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "ea0116b4-db91-4e07-99c3-1d71aadcf4ce",
      "name": "Confluence - GQL Space Anonymous Access",
      "type": "n8n-nodes-base.graphql",
      "position": [
        -304,
        -480
      ],
      "parameters": {
        "query": "query SpacePermissionsAnonymousQuery($spaceKey: String!) {\n  spacePermissions(spaceKey: $spaceKey) {\n    filteredSubjectsWithPermissions(\n      permissionDisplayType: ANONYMOUS\n      first: 25\n      after: \"\"\n      filterText: \"\"\n    ) {\n      nodes {\n        permissions\n        filteredPrincipalSubjectKey {\n          id\n          displayName\n        }\n      }\n    }\n  }\n}\n",
        "endpoint": "={{ $('Set Variables').first().json.atlassianDomain }}/gateway/api/graphql",
        "variables": "={\n    \"spaceKey\": \"{{ $json.key }}\"\n}",
        "operationName": "SpacePermissionsAnonymousQuery",
        "authentication": "basicAuth"
      },
      "credentials": {
        "httpBasicAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "87456de1-b701-44d6-ab13-cb6d9e6a508b",
      "name": "Split Out Spaces",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        -528,
        -288
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "results"
      },
      "typeVersion": 1
    },
    {
      "id": "41b8829b-43f5-40b3-a899-ef39eb2a1c82",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1248,
        -608
      ],
      "parameters": {
        "width": 416,
        "height": 176,
        "content": "## Confluence API Reference\n* [V2 Get Spaces](https://developer.atlassian.com/cloud/confluence/rest/v2/api-group-space/#api-spaces-get)\n\n## Atlassian GraphQL API Reference\n* [GraphQL API](https://developer.atlassian.com/cloud/confluence/graphql/#overview)"
      },
      "typeVersion": 1
    },
    {
      "id": "f95c8e6a-1352-4732-8530-aee6d963b5a3",
      "name": "Confluence - GQL Space Public Links Enabled",
      "type": "n8n-nodes-base.graphql",
      "position": [
        -304,
        -288
      ],
      "parameters": {
        "query": "query usePublicLinkSpaceTogglePublicLinkSpaceQuery($spaceId: ID!) {\n  publicLinkSpace(spaceId: $spaceId) {\n    name\n    spaceId\n    spaceKey\n    spaceAlias\n    status\n\n    stats {\n      publicLinks {\n        active\n      }\n    }\n\n    isPolicySetForClassificationLevel\n  }\n\n  publicLinkSiteStatus {\n    status\n  }\n}",
        "endpoint": "={{ $('Set Variables').first().json.atlassianDomain }}/gateway/api/graphql",
        "variables": "={\n  \"spaceId\": \"{{ $json.id }}\"\n}",
        "operationName": "usePublicLinkSpaceTogglePublicLinkSpaceQuery",
        "authentication": "basicAuth"
      },
      "credentials": {
        "httpBasicAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "f6e09ea9-fd84-41ab-9913-0e51ef17c462",
      "name": "Confluence - GQL Space Pages with Public Link",
      "type": "n8n-nodes-base.graphql",
      "position": [
        -304,
        -96
      ],
      "parameters": {
        "query": "query PublicLinkPagesTablePublicLinksByCriteriaQuery(\n  $spaceId: ID!\n  $status: [PublicLinkStatus!]\n  $after: String\n  $title: String\n  $type: [String]\n  $first: Int = 25\n  $orderBy: PublicLinksByCriteriaOrder = DATE_ENABLED\n  $isAscending: Boolean = true\n) {\n  publicLinksByCriteria(\n    spaceId: $spaceId\n    status: $status\n    after: $after\n    first: $first\n    orderBy: $orderBy\n    isAscending: $isAscending\n    title: $title\n    type: $type\n  ) {\n    nodes {\n      id\n      status\n      publicLinkUrlPath\n      lastEnabledBy\n      lastEnabledDate\n      title\n      type\n\n      lastEnabledByUser {\n        displayName\n        permissionType\n      }\n\n    }\n  }\n}\n",
        "endpoint": "={{ $('Set Variables').first().json.atlassianDomain }}/gateway/api/graphql",
        "variables": "={\n  \"first\": 250,\n  \"orderBy\": \"TITLE\",\n  \"isAscending\": true,\n  \"spaceId\": \"{{ $json.id }}\",\n  \"status\": [\n    \"ON\",\n    \"BLOCKED_BY_PRODUCT\",\n    \"BLOCKED_BY_SPACE\"\n  ],\n  \"title\": \"\",\n  \"after\": \"\"\n}",
        "operationName": "PublicLinkPagesTablePublicLinksByCriteriaQuery",
        "authentication": "basicAuth"
      },
      "credentials": {
        "httpBasicAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "b10d93b6-6ac8-4354-9d5e-d8873ceb6456",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        144,
        -304
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition",
        "numberInputs": 3
      },
      "typeVersion": 3.2
    },
    {
      "id": "03305bb6-7859-4230-924f-646be6281e2a",
      "name": "Set Anonymous Access",
      "type": "n8n-nodes-base.set",
      "position": [
        -80,
        -480
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "c0f098ce-6833-4da2-ba11-ef06630c891e",
              "name": "anonymousAccess",
              "type": "object",
              "value": "={{ $json }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "a9b2fd3c-2832-4808-94bd-d162c599b8a7",
      "name": "Set Space Public Links Enabled",
      "type": "n8n-nodes-base.set",
      "position": [
        -80,
        -288
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "0f5ac1dc-934c-47bf-bbf7-80cda7e335bb",
              "name": "publicLinksEnabled",
              "type": "object",
              "value": "={{ $json }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "a81ca969-1fdd-4098-8cd5-39a59f41cb9b",
      "name": "Set Space Pages with Public Link",
      "type": "n8n-nodes-base.set",
      "position": [
        -80,
        -96
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "a06554b5-ab7a-4901-915b-799e420e26da",
              "name": "pagesWithPublicLink",
              "type": "object",
              "value": "={{ $json }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "6a6a72e0-d94a-419e-9247-5acac4f481ea",
      "name": "Confluence - Get Spaces",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -752,
        -288
      ],
      "parameters": {
        "url": "={{ $json.atlassianDomain }}/wiki/api/v2/spaces",
        "options": {},
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBasicAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "keys",
              "value": "={{ $json.spaceKeys }}"
            },
            {
              "name": "type",
              "value": "=global"
            }
          ]
        }
      },
      "credentials": {
        "httpBasicAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "ed46e380-27a3-4ece-9bc6-d6816b20fb23",
      "name": "Build Report",
      "type": "n8n-nodes-base.set",
      "position": [
        352,
        -288
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "3504b147-2c5f-4598-979c-3bbe835da4a9",
              "name": "spaceKey",
              "type": "string",
              "value": "={{ $json.publicLinksEnabled.data.publicLinkSpace.spaceKey }}"
            },
            {
              "id": "f6a2439a-b3c3-449d-a2f9-41fe51dc292f",
              "name": "anonymousAccess",
              "type": "array",
              "value": "={{ $json.anonymousAccess.data.spacePermissions.filteredSubjectsWithPermissions.nodes }}"
            },
            {
              "id": "84e39679-e023-402f-b4d1-1a59c849c0a1",
              "name": "publicLinksEnabled",
              "type": "string",
              "value": "={{ $json.publicLinksEnabled.data.publicLinkSpace.status }}"
            },
            {
              "id": "f121cc4c-5b82-4393-8eee-55817d21a084",
              "name": "pagesWithPublicLink",
              "type": "array",
              "value": "={{\n$json.pagesWithPublicLink.data.publicLinksByCriteria.nodes.map(p => ({\n      id: p.id,\n      title: p.title,\n      status: p.status,\n      publicUrl: $('Set Variables').first().json.atlassianDomain+p.publicLinkUrlPath,\n      lastEnabledBy: p.lastEnabledByUser\n    }))\n}}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "21685f3c-5e89-4bcc-b9ae-70145229e033",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -384,
        -592
      ],
      "parameters": {
        "color": 7,
        "width": 464,
        "height": 672,
        "content": "## Atlassian GraphQL\nChecks for Anonymous access, public links enabled and pages with public links"
      },
      "typeVersion": 1
    },
    {
      "id": "40e120ea-a9da-4454-99eb-e5dd43701085",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2016,
        -16
      ],
      "parameters": {
        "color": 6,
        "width": 752,
        "height": 144,
        "content": "### Notes\n- Uses **Atlassian GraphQL API**\n- Pages with blocked links are still included for visibility.\n- Current GraphQL page query fetches up to **250 pages per space**.\n- Need help? \u2709\ufe0f **office@sus-tech.at**\n"
      },
      "typeVersion": 1
    },
    {
      "id": "dfc2bba5-c267-49b7-8899-616ffcb0217d",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2016,
        -608
      ],
      "parameters": {
        "width": 752,
        "height": 576,
        "content": "## How it works\nThis workflow audits Confluence spaces for public exposure risks, focusing on anonymous access and public links. A **Set Variables** node defines the Atlassian domain and the list of space keys to evaluate.\n\nUsing the **Confluence API v2**, the workflow retrieves all matching spaces and processes them one by one. For each space, multiple checks run in parallel using GraphQL.\n\nThese queries detect:\n  - **Anonymous access permissions** on spaces\n  - Whether **public links are enabled** at space level\n  - Pages with **active or blocked public links**\n\n\nThe results from all queries are combined into a single, structured output that highlights spaces and pages that may be publicly accessible. This makes it easier to review risks, confirm compliance or share findings with security and documentation owners.\n\n## Setup steps\n1. Open the **Set Variables** node and configure:\n   - `atlassianDomain`: Your Confluence base URL  \n   - `spaceKeys`: Comma-separated list of space keys (for example `ENG,HR`)  \n2. Create an **HTTP Basic Auth** credential in n8n using your Atlassian email address and API token.\n3. Assign this credential to all HTTP and GraphQL nodes in the workflow.\n4. Verify the credential has permission to read spaces, space permissions and GraphQL endpoints.\n5. (Optional) Extend the workflow with email, Slack, or CSV export nodes using the output.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "5706378f-31ba-4c80-9a64-1a508f7bcc5c",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -816,
        -352
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 224,
        "content": "## Confluence API v2"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "98a2fe63-c660-47fa-bae7-682ed90c05fa",
  "connections": {
    "Merge": {
      "main": [
        [
          {
            "node": "Build Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Report": {
      "main": [
        []
      ]
    },
    "Set Variables": {
      "main": [
        [
          {
            "node": "Confluence - Get Spaces",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out Spaces": {
      "main": [
        [
          {
            "node": "Confluence - GQL Space Pages with Public Link",
            "type": "main",
            "index": 0
          },
          {
            "node": "Confluence - GQL Space Public Links Enabled",
            "type": "main",
            "index": 0
          },
          {
            "node": "Confluence - GQL Space Anonymous Access",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Anonymous Access": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Confluence - Get Spaces": {
      "main": [
        [
          {
            "node": "Split Out Spaces",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Space Public Links Enabled": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Set Space Pages with Public Link": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "When clicking \u2018Execute workflow\u2019": {
      "main": [
        [
          {
            "node": "Set Variables",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Confluence - GQL Space Anonymous Access": {
      "main": [
        [
          {
            "node": "Set Anonymous Access",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Confluence - GQL Space Public Links Enabled": {
      "main": [
        [
          {
            "node": "Set Space Public Links Enabled",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Confluence - GQL Space Pages with Public Link": {
      "main": [
        [
          {
            "node": "Set Space Pages with Public Link",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}