{
  "id": "CB-M365-POWER-019",
  "standard": "m365",
  "version": "main",
  "url": "https://baselines.cirsec.org/b/m365/CB-M365-POWER-019",
  "json": "https://baselines.cirsec.org/b/m365/CB-M365-POWER-019.json",
  "yaml": "https://baselines.cirsec.org/b/m365/CB-M365-POWER-019.yml",
  "profiles_effective": [
    "baseline",
    "hardened"
  ],
  "license": "Text CC BY 4.0, code Apache-2.0",
  "attribution": "CIRSEC Baselines, https://baselines.cirsec.org",
  "control": {
    "id": "CB-M365-POWER-019",
    "title": "Restrict Fabric public API access by service principals to approved groups",
    "finding": {
      "title": "Any service principal can call Fabric public APIs",
      "description": "Every application registered in the tenant can use its service principal to call Fabric APIs, within the permissions it is granted on workspaces and items."
    },
    "status": "active",
    "profiles": [
      "baseline"
    ],
    "risk": {
      "severity": "medium"
    },
    "assessment": "manual",
    "tags": [
      "fabric",
      "power-bi",
      "service-principals",
      "api",
      "workload-identities"
    ],
    "applicability": {
      "requires": [
        "Power BI / Microsoft Fabric"
      ]
    },
    "description": "The Fabric tenant setting **Service principals can call Fabric public APIs** (Developer\nsettings) is **Disabled**, or **Enabled** only for specific security groups that contain the\nservice principals of approved applications. Credentials of those service principals are stored\nin a key vault and reviewed with the other workload identities.\n",
    "rationale": "Service principals authenticate without MFA or Conditional Access for users, often with long-lived\nsecrets. If any of them can call Fabric APIs, a leaked secret of an unrelated application becomes\na way to read or change analytics content wherever that principal was granted access. Allowing\nonly a named group keeps API access to the applications that were reviewed for it.\n",
    "impact": "Applications whose service principal is outside the allowed groups receive authorization errors\non Fabric APIs. Microsoft enables this setting by default for new tenants: inventory the\napplications that use Fabric APIs (sign-in logs, admin monitoring) and add their service\nprincipals to the group before restricting.\n",
    "setting": {
      "location": "Fabric admin portal > Tenant settings > Developer settings > Service principals can call Fabric public APIs",
      "default_value": "Enabled for the entire organization (new tenants)",
      "recommended_value": "Disabled, or Enabled for specific security groups"
    },
    "audit": {
      "manual": "1. Sign in to Microsoft Fabric (https://app.fabric.microsoft.com) as a Fabric Administrator.\n2. Open **Settings** > **Admin portal** > **Tenant settings** > **Developer settings** and\n   expand **Service principals can call Fabric public APIs**.\n3. Check that it is **Disabled**, or **Enabled** for **Specific security groups** whose members\n   are approved service principals.\n4. Alternative, read only: in `GET https://api.fabric.microsoft.com/v1/admin/tenantsettings`,\n   read the entry `ServicePrincipalAccessPermissionAPIs`.\n5. Fail if the setting is enabled for the entire organization.\n"
    },
    "remediation": {
      "manual": "1. Create a security group for the service principals of approved applications and add them.\n2. In **Tenant settings** > **Developer settings** > **Service principals can call Fabric public\n   APIs**, select **Disabled**, or **Enabled** with **Specific security groups** and the group.\n   Select **Apply**. Role: Fabric Administrator.\n3. API equivalent: `POST\n   https://api.fabric.microsoft.com/v1/admin/tenantsettings/ServicePrincipalAccessPermissionAPIs/update`\n   with the target state.\n",
      "rollback": "Set the setting back to its previous scope.\n"
    },
    "references": [
      {
        "title": "Developer admin settings",
        "url": "https://learn.microsoft.com/fabric/admin/service-admin-portal-developer",
        "publisher": "Microsoft",
        "kind": "vendor-doc",
        "accessed": "2026-10-24"
      },
      {
        "title": "CISA SCuBA Power BI baseline",
        "url": "https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/powerbi.md",
        "publisher": "CISA",
        "kind": "standard",
        "accessed": "2026-10-24"
      }
    ],
    "mappings": [
      {
        "framework": "cisa-scuba-m365",
        "framework_version": "2.0.0",
        "id": "MS.POWERBI.4.1v1",
        "relation": "equivalent"
      },
      {
        "framework": "nist-800-53r5",
        "framework_version": "5.1.1",
        "id": "AC-6(5)",
        "relation": "related"
      },
      {
        "framework": "nist-800-53r5",
        "framework_version": "5.1.1",
        "id": "AC-4",
        "relation": "related"
      }
    ],
    "threats": [
      {
        "framework": "mitre-attack",
        "id": "T1059.009"
      },
      {
        "framework": "mitre-attack",
        "id": "T1078.004"
      }
    ],
    "related_controls": [
      {
        "id": "CB-M365-POWER-020",
        "type": "related"
      },
      {
        "id": "CB-M365-POWER-021",
        "type": "related"
      },
      {
        "id": "CB-M365-APPS-001",
        "type": "related"
      }
    ],
    "authors": [
      {
        "name": "Alice",
        "github": "Sn0wAlice"
      }
    ],
    "introduced_in": "0.1.0",
    "created": "2026-10-24",
    "updated": "2026-10-24"
  }
}