SECURITY.md
Rama main · réplica de lectura del repositorio original.
# Security Policy
Intune Preflight is **read-only** and never writes to your tenant. It ships in two shapes with
different security models, and the distinction matters:
- **Self-hosted** (`apps/server`) — authenticates with **application (app-only)** credentials you
supply, and so handles a tenant-wide read credential. **It has no authentication of its own.**
- **Browser** (the static `build:live` bundle) — no server and no secret; the admin signs in
themselves and the token is bounded by their own Intune RBAC.
Security reports are taken seriously for both. Please say which one you are reporting against.
## Reporting a vulnerability
**Please do not open a public issue for security problems.**
Use GitHub's **[Private vulnerability reporting](https://github.com/kevinmalinoski/intune-preflight/security/advisories/new)** ("Report a vulnerability" under the repository's *Security* tab). Include:
- what the issue is and its impact,
- steps to reproduce (redact any real tenant identifiers or secrets),
- affected version / commit.
You'll get an acknowledgement as soon as possible. Once a fix is available, we'll coordinate disclosure.
## Supported versions
This is pre-1.0 software. Security fixes land on `main` and the latest release; older tagged releases are not separately patched.
## Security model & expectations
- **Read-only.** Both builds request only `*.Read.All` Graph scopes and perform no writes. See the permissions table in the [README](README.md).
- **No telemetry, either way.** There are no external calls beyond Microsoft Graph and Entra login.
### Self-hosted server
- **Credentials stay server-side.** `TENANT_ID` / `CLIENT_ID` / `CLIENT_SECRET` live in `.env`, are read only by the server, and are **never** sent to the browser. `.env*` is git-ignored — never commit it.
- **No data leaves your infrastructure.** Tenant data is fetched on demand, cached in memory, and served only to your own browser.
- **It is unauthenticated, and that has not changed.** Deploy it somewhere only trusted admins can reach, and **do not expose it to the public internet.** The sign-in added in 2.2 belongs to the *browser* build; it gives the server nothing. Anyone who can reach the server's port can read the whole tenant's configuration without presenting a credential.
- **App-only means unfiltered.** It deliberately sees the entire tenant, unscoped by scope tags or admin units, which makes the app registration effectively a tenant-wide read key. Grant only the listed permissions and rotate the secret periodically.
### Browser build
- **There is no secret to protect.** A single-page app is a public client; PKCE replaces the client secret. The tenant and client IDs it keeps in `localStorage` appear in every sign-in URL and are not secrets.
- **The session is the tab.** The access token lives in `sessionStorage` and goes when the tab closes; a SPA refresh token is capped at 24 hours and cannot be extended. Tenant data is held in memory only and is never written to disk.
- **It is bounded by the signed-in admin.** Permissions are delegated, so the page can read only what that admin could already read — including their Intune RBAC scope tags — and every read is attributable to them in your sign-in logs.
- **It is designed to be hosted publicly.** That is the difference from the server build. It still requires an app registration you control and an admin consent you grant.
## In scope for reports
Credential handling/leakage, secrets reaching the client, SSRF, injection, dependency vulnerabilities with a practical exploit path, and anything that would let untrusted input exfiltrate tenant data.