intuneatlas /intuneatlas Star

./intuneatlas

Flatten every Intune profile into one settings index, keyed on the CSP path.

The portal is organised around policies. Devices apply a merged set of settings. This reads your tenant read-only and rebuilds that merge, a couple of thousand settings, then serves it as something you can actually read: grouped, searchable by CSP path, with the conflicts and coverage gaps surfaced. Runs on your machine. Headless when you want a file and an exit code instead.

MIT TypeScript v0.6.2 · alpha 1,284 Graph API · read-only
$ npx intuneatlas ui --tenant contoso.onmicrosoft.com

indexes read-only, serves on localhost · nothing leaves your machine · headless scan for CI

intuneatlas ui — contoso.onmicrosoft.com
$ npx intuneatlas ui --tenant contoso.onmicrosoft.com

   device code sign-in — admin@contoso.onmicrosoft.com (read-only)
   41 policies  1,847 settings indexed in 3m 41s
   11 findings · 3 critical

   http://localhost:7878
localhost:7878/settings 1,847 indexed · 11 findings
Quality update deferral Windows · 2 policies · 412 devices 14 days  /  2 days Conflict
Tamper protection · 2 notes Windows · Defender & ASR Rules · 1,312 devices Off Below baseline
Download mode Windows · Delivery Optimization · no groups assigned HTTP only Not deployed
Escrow recovery key to Intune macOS · FileVault · 342 devices Enabled Baseline

What it reports

Four states. Only one of them is quiet.

Every setting in the index lands in exactly one. Anything already correct stays grey, so the output is a worklist rather than a wall of green ticks.

Conflict

Two profiles disagree

Same path, different values, overlapping assignment. Both sources are printed with their value so you know which one to rescope.

Below baseline

Weaker than the benchmark

Checked against whichever baseline you point it at. Every finding carries a rationale and a citation, not just a severity.

Not deployed

Configured, reaching nothing

The profile looks healthy in the portal but targets no group. Silent, and invisible in every per-policy view.

Documented

Someone wrote down why

Notes live in a file in your repo, keyed by path. Findings print with their thread attached, so context survives the person who set it.

Baselines

A baseline is just YAML in a directory.

Ships with the Microsoft security baselines and CIS Level 1 and 2. Fork them, or keep your own alongside them. House rules and benchmark rules evaluate identically, and both print their source.

baselines/windows/defender.yml yaml
- id: defender.tamper-protection
  name: Tamper protection
  platform: windows
  path: ./Device/Vendor/MSFT/Defender/Configuration/TamperProtection
  expect: enabled
  severity: critical
  rationale: >
    Any process running as SYSTEM can silently disable real-time
    scanning while tamper protection is off.
  source: Microsoft Defender for Endpoint hardening guidance

- id: update.quality-deferral
  name: Quality update deferral
  platform: windows
  path: ./Device/Vendor/MSFT/Policy/Config/Update/DeferQualityUpdatesPeriodInDays
  expect:
    max: 7
  severity: high
  source: CIS Microsoft Windows 11 Benchmark, L1
Baseline rules are the easiest thing to contribute and the most useful. If your team has a house rule with a real justification behind it, that's a pull request: one file, one block, no TypeScript required.

Run it

Open it, query it, or wire it into CI.

One index, four entry points. The default command builds it and serves it on localhost; the rest hand you a single value, a file, or an exit code instead.

Read the index

Web UI — intuneatlas ui

Every setting grouped by category, searchable by CSP path, with sources, note threads, and the review gate for staged changes. Runs on your machine against the report on disk, with no server and no upload.

Single value

get — intuneatlas get <path>

One setting, every profile that sets it, and each value. Five lines of output, pipeable, no index served and no browser opened.

Scheduled

Headless scan

JSON or SARIF to disk and a non-zero exit when the tenant drifts past your threshold. The Docker image takes an app registration from the environment.

Continuous

GitHub Action

The headless scan on a cron, with findings as PR annotations. Fails the run at your chosen severity.

scheduled run — sarif to disk, non-zero on drift
$ intuneatlas scan --baseline cis-l1 --fail-on high --format sarif

  41 policies · 1,847 settings · 11 findings (3 critical, 3 high, 3 medium, 2 low)
  wrote ./intuneatlas.sarif
  exit 1  — 6 findings at or above `high`

.github/workflows/tenant-drift.yml yaml
on:
  schedule: [{ cron: "0 7 * * 1" }]

jobs:
  drift:
    runs-on: ubuntu-latest
    steps:
      - uses: intuneatlas/scan-action@v1
        with:
          baseline: cis-l1
          fail-on: high        # exit non-zero at high or critical
          notes: ./intune-notes.yml

Project status

Alpha, and honest about it.

Windows coverage is solid because that's where the contributors' fleets are. Apple and Android are thinner. Here's exactly where things stand at v0.6.2.

  • Windows configuration & update ringsFull CSP path resolution, conflict detection, settings catalog stable
  • Compliance policies & tenant defaultsIncluding the secureByDefault check that catches unmanaged devices stable
  • Enrollment, ADE tokens, certificate expiryExpiry warnings for ADE and APNs stable
  • macOS & iOS payloadsIndexes and reports, but payload key mapping is incomplete, so some settings show a raw identifier partial
  • Android EnterpriseWork profile restrictions only. Fully managed and dedicated devices are not mapped yet partial
  • Write-back / deploy staged changesBehind --experimental-write. Review gate works; rollback does not yet experimental
  • App protection & Conditional Access policiesOut of scope for now. Different object model, would deserve its own index not planned
Not affiliated with, endorsed by, or supported by Microsoft. Intune and Microsoft Graph are Microsoft trademarks. This project reads a tenant through the documented Graph API and nothing else. If a scan ever surprises you, open an issue and paste the redacted report.

Contribute

Baseline rules and platform coverage, mostly.

Two contributor paths. Writing a rule needs tenant experience and no TypeScript; extending platform coverage needs the opposite. Both are wanted.

Every baseline rule needs a citation: a benchmark section, vendor guidance, or a documented tenant observation. "It's more secure" isn't reviewable, and a rule nobody can trace gets removed the first time it fires a false positive on someone's fleet.