Security & data handling

What Tenant Hawk can see, what it stores, and how you shut it off

You are being asked to consent an app into your tenant, so this page skips the marketing. Everything below is verifiable: the permission list matches what Microsoft shows you on the admin consent screen, and after connecting you can audit it any time under Entra ID → Enterprise applications → Tenant Hawk → Permissions.

The access model

Application permissions, admin consent, read-only

Access is granted through Microsoft's standard admin-consent flow — the same one you use for any multi-tenant app. Every scope we request is a read-only (.Read) permission. There is no write permission in the manifest, so Tenant Hawk cannot change users, licenses, policies, or settings even if it wanted to.

No credentials touch our systems

Consent happens on login.microsoftonline.com, so no one ever types a Microsoft password into Tenant Hawk. Scans authenticate with short-lived app-only tokens acquired from Microsoft at runtime via the client-credentials flow. No access tokens, refresh tokens, or secrets for your tenant are written to our database.

Findings, not content

Scan results store what you see in the dashboard: check outcomes, severity, affected object names, and license counts. We do not store email bodies, files, or Teams message content — the checks that touch those surfaces read timestamps and settings only, as documented per permission below.

Deletion is real deletion

Disconnecting a tenant deletes its connection row, and every scan, finding, and configuration snapshot cascades with it at the database level. Deleting your account removes everything.

Every permission we request, and why

15 Microsoft Graph application permissions power all 70 checks. This table is generated from the same registry the scan engine runs on, so it cannot drift from what the app actually uses. If a future check needs a new scope, it will appear here — and on your consent screen — before it ships.

Application.Read.All7 checks

Grants: App registrations and enterprise apps (service principals), including credential metadata.

We use it for: Finding client secrets and certificates about to expire, ownerless or unused apps, and enterprise apps holding more permissions than they use. We read credential expiry dates — never the secret values themselves, which Microsoft does not expose.

Powers: Expiring app secrets and certs · Expiring enterprise app secrets · Over-permissioned enterprise apps · Unused enterprise apps · Ownerless app registrations · Ownerless enterprise apps · Multi-tenant apps with credentials

AuditLog.Read.All1 check

Grants: Entra sign-in and audit log entries.

We use it for: Sign-in activity for enterprise apps, so unused apps are flagged from real usage rather than guesswork.

Powers: Unused enterprise apps

Channel.ReadBasic.All1 check

Grants: Teams channel names and metadata.

We use it for: Detecting private channels whose owners have all left or been disabled.

Powers: Ownerless private channels

ChannelMessage.Read.All2 checks

Grants: Messages in Teams channels.

We use it for: Channel activity only: during a deep scan we request the single most recent message per channel and keep its timestamp to detect inactive and never-used channels. Message content is not stored and does not appear in any finding.

Powers: Inactive Teams channels · Empty Teams channels

Device.Read.All3 checks

Grants: Entra device records.

We use it for: Comparing Entra device records against Intune enrollment to catch drift, and flagging devices with stale sign-ins.

Powers: Entra devices not in Intune · Intune enrollments without Entra device · Stale Entra device sign-ins

DeviceManagementManagedDevices.Read.All5 checks

Grants: Intune managed device inventory.

We use it for: Stale device sync, compliance state, personally owned enrollments, and the Entra-vs-Intune reconciliation above.

Powers: Stale Intune device sync · Non-compliant Intune devices · Entra devices not in Intune · Intune enrollments without Entra device · Personally owned Intune enrollments

Directory.Read.All10 checks

Grants: Directory objects: groups, role assignments, organizational relationships.

We use it for: Privileged role assignments, empty and ownerless groups, and Teams whose owners are gone.

Powers: Privileged role assignments · Disabled users outside offboarding groups · Empty groups · Ownerless groups · Ownerless Microsoft Teams · Empty Microsoft Teams · Groups with risky naming patterns · Over-permissioned enterprise apps · Apps with Global Administrator role · Privileged users without MFA

Mail.ReadBasic.All3 checks

Grants: Mailbox metadata — not message bodies or attachments.

We use it for: Mailbox settings only: external forwarding addresses and stale automatic replies. We never read, store, or index email content.

Powers: External mailbox forwarding · Mailbox forwarding enabled · Stale mailbox auto-replies

Organization.Read.All9 checks

Grants: Tenant subscription and SKU information.

We use it for: License seat counts against assignments — the source for dollar figures on unused, disabled-user, and expiring licenses.

Powers: Licenses on disabled accounts · Unused license seats · Subscription status warnings · Unused Copilot license seats · Licensed inactive Copilot users · Copilot on disabled accounts · Low Copilot adoption · Copilot users without MFA · Licensed inactive mailboxes

Policy.Read.All2 checks

Grants: Conditional Access and authentication policies.

We use it for: Conditional Access coverage gaps (including policies stuck in report-only) and legacy authentication exposure.

Powers: Conditional Access coverage · Legacy authentication

Reports.Read.All28 checks

Grants: Microsoft 365 usage reports (aggregated activity per user, site, mailbox, and team).

We use it for: The activity backbone for most hygiene checks: MFA registration, inactive users, stale SharePoint sites, mailbox and Teams activity. These are the same reports in your admin center — pre-aggregated by Microsoft, no message or file content.

Powers: MFA registration gaps · Sites with external sharing · Stale SharePoint sites · High-storage SharePoint sites · Empty SharePoint sites · Ownerless SharePoint sites · Sites with inactive files · Stale Microsoft Teams · Teams with no active channels · Guest-heavy Teams · Licensed inactive Copilot users · Low Copilot adoption · Copilot Chat-only users · Copilot users without MFA · Copilot Chat-only usage pattern · Inactive mailboxes · High-storage mailboxes · Licensed inactive mailboxes · Privileged users without MFA · SharePoint sites with unused pages · Stale SharePoint site pages · SharePoint anonymous links · Stale OneDrive accounts · High-storage OneDrive accounts · High-storage stale team sites · Shared mailboxes without delegates · Inactive shared mailboxes · Unused resource mailboxes

RoleManagement.Read.All1 check

Grants: Role management and PIM configuration.

We use it for: Detecting standing (always-on) privileged access that should be eligible-only.

Powers: Standing privileged role access

SharePointTenantSettings.Read.All1 check

Grants: Tenant-level SharePoint settings.

We use it for: The org-wide external sharing posture check.

Powers: Org-wide SharePoint sharing policy

Team.ReadBasic.All6 checks

Grants: Team names and basic metadata.

We use it for: Team-level checks: disabled owners, outdated or unverified Teams apps.

Powers: Inactive Teams channels · Empty Teams channels · Ownerless private channels · Teams with disabled owners · Outdated Teams apps · Unverified Teams apps

User.Read.All15 checks

Grants: User profiles, account status, license assignments, and sign-in activity timestamps.

We use it for: The core of licensing and lifecycle checks: disabled accounts still holding licenses, inactive users (interactive and non-interactive sign-ins both considered), and guest sprawl.

Powers: Guest account sprawl · Licenses on disabled accounts · Inactive user accounts · Disabled users outside offboarding groups · Licensed inactive Copilot users · Copilot on disabled accounts · Low Copilot adoption · Copilot users without MFA · External mailbox forwarding · Mailbox forwarding enabled · Licensed inactive mailboxes · Stale guest accounts · Guest invitation spike · Users without a manager · Teams with disabled owners

What we store, and for how long

A scan produces findings — check outcomes with severity, the display names of affected objects (a user, group, site, or app name), and aggregate numbers like seat counts and estimated monthly waste. That is what we retain, because it is what renders your dashboard, trends, and reports.

We keep scan history while the tenant stays connected so you can track your score over time. Disconnect the tenant and that history is deleted — not archived, deleted, enforced by cascading foreign keys in our schema. Account deletion removes your user record and everything attached to it.

Tenant Hawk runs on Amazon Web Services. All traffic is encrypted in transit with TLS, and the database is encrypted at rest. Payments are handled by Stripe; we never see card numbers. The full subprocessor list is in the privacy policy.

Revoking access

Two independent kill switches, in either order:

  1. 1

    In Tenant Hawk

    Settings → Connections → Disconnect. This deletes the connection and all scan history for that tenant from our database immediately.

  2. 2

    In Microsoft Entra

    Entra ID → Enterprise applications → Tenant Hawk → Delete. This revokes consent on Microsoft's side; our tokens stop working within minutes and no future scan can run.

  3. 3

    Both work independently

    You don't need our cooperation to lock us out — revoking in Entra cuts access even if you never touch Tenant Hawk again. We recommend doing both so stored results are deleted too.

Don't take our word for it

The admin consent screen Microsoft shows you lists every permission above — compare them before you approve. After connecting, the app appears under Enterprise applications in your Entra portal with the same read-only scopes, and your audit log records exactly what it reads. If your security review needs more than this page, email support@tenanthawk.io and a human will answer the questionnaire.