> ## Documentation Index
> Fetch the complete documentation index at: https://docs.breachlens.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Scan GitHub posture

> Audit the account's own configuration — branch protection, required reviewers, Dependabot alerts — across every repo, and understand the one extra permission it needs.

Code scanning reads what's *in* your repos. **Posture scanning** reads how your GitHub account itself is *configured* — the guardrails around the code:

* Branch protection on default branches
* Required reviewers before merge
* Dependabot vulnerability alerts enabled
* Delete-branch-on-merge, signed commits, and similar hygiene
* Organization-level settings (2FA enforcement, base member permissions)

It runs across **every repository the App installation can see — public and private** — and rolls the results up per account so you can see which repos are missing which guardrails.

<Note>
  Posture reuses the same [GitHub App installation](/scanning/repositories#add-a-repository) as code scanning. You don't connect anything new — you grant one additional permission.
</Note>

## The one extra permission: `Administration: Read`

Most posture checks read repository **configuration**, which lives behind GitHub's `Administration` permission — not `Contents`. Without it, BreachLens can enumerate your repos but can't read their branch-protection or Dependabot settings.

Crucially, when a check can't be read, BreachLens does **not** report it as passing. It reports it as **Unevaluated** — because *unknown is not the same as clean*. A repo you couldn't fully check should never look green.

<CardGroup cols={2}>
  <Card title="With Administration: Read" icon="circle-check">
    Every posture check evaluates to Pass or Fail. Coverage is complete; the account's real hygiene is visible.
  </Card>

  <Card title="Without it" icon="circle-question">
    Repos still appear, but config-dependent checks show as **Unevaluated** with a coverage banner telling you exactly what you're not seeing and why.
  </Card>
</CardGroup>

<Steps>
  <Step title="Grant the permission">
    On GitHub, open the BreachLens App installation → **Permissions** → set **Administration** to **Read-only**, then save.
  </Step>

  <Step title="Accept it on each installation">
    Adding a permission to a published App marks it **pending** on every existing installation. An org owner must click **Review request → Accept** on each one before it takes effect — GitHub does not apply it retroactively on its own.
  </Step>

  <Step title="Re-run the scan">
    Trigger a fresh posture scan (below). Previously **Unevaluated** checks now resolve to Pass or Fail, and the coverage banner clears.
  </Step>
</Steps>

<Warning>
  `Administration: Read` is an admin-level grant, so procurement may want to review it. It is **read-only** — it lets BreachLens *read* protection rules and org settings, never change them. Organization-wide checks (member 2FA, base permissions) additionally need the App installed at the **org** level, not just on a personal account.
</Warning>

## Run a posture scan

<Steps>
  <Step title="Open the account">
    Go to **GitHub Accounts** and click the account (or org) you want to audit.
  </Step>

  <Step title="Run the scan">
    Click **Run scan** and choose the **GitHub posture** tier — or start it from the account's **Scans** tab. A posture scan is fast; it inspects configuration, not code.
  </Step>
</Steps>

## Read the results

The account detail page surfaces posture three ways:

| Panel                   | Tells you                                                                                                                                                           |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Overview → Coverage** | How many repos and checks came back **Unevaluated**, and the fix (grant `Administration: Read`). Hidden entirely once coverage is complete.                         |
| **Linked repositories** | Per-repo **failing** vs **unevaluated** counts, kept separate so a clean-looking repo can't hide a gap. Click a repo to jump to its posture findings, pre-filtered. |
| **Findings**            | Every Fail as a finding, with severity, the rule that fired, and remediation.                                                                                       |

<Note>
  Failing and unevaluated are counted separately everywhere — in tiles, per-repo chips, and the "hottest checks" list. A repo with 12 failing checks and 4 unevaluated reads exactly that, never a blended number. This is deliberate: an *unknown* check is a coverage gap to close, not a violation to fix.
</Note>

## Fixing a failing check

Open any posture finding to see **how** it's remediated. Each check is classified as either an API-flippable setting (branch protection, secret scanning, Dependabot alerts) or a manual fix (a CODEOWNERS or SECURITY.md commit, an org-owner action), with the exact steps in the drawer.

<Note>
  **Two checks overlap tiers you already run.** GitHub's native **secret scanning** and **Dependabot alerts** detect problems BreachLens already covers — so the drawer says so instead of pushing you to pay twice. Enabling GitHub secret scanning mainly buys you **push protection** (blocking a secret *before* it's committed), and on private repos and GitHub Enterprise Server it's a **paid** feature (GitHub Secret Protection / Advanced Security; it's free on public repos). Turn it on for the prevention, not for detection you already have.
</Note>

### Fix on GitHub (one-click)

Two repo-level checks can be flipped straight from the finding drawer, through the BreachLens GitHub App — no leaving the app:

| Check                 | What the button turns on                                          |
| --------------------- | ----------------------------------------------------------------- |
| **Secret scanning**   | Secret scanning **and** push protection (`security_and_analysis`) |
| **Dependabot alerts** | Repository vulnerability alerts                                   |

Both are **additive and non-destructive** — they only *enable* a security feature, never remove protection or delete data. The button is **confirm-gated** (you approve *"This changes the repository's GitHub settings directly"* before anything happens), and it never claims a success it didn't get. After it applies, re-run the posture scan to confirm the check now passes.

Everything else stays deliberately out of one-click scope. Branch protection (a read-modify-write with many variants), organization-level settings, and the destructive *archive* check show the manual steps instead — enabling them blind would be the wrong default.

<Warning>
  **One-click writes need `Administration: write`.** The BreachLens GitHub App requests this permission so it can flip repo settings; each installation must **accept the pending permission request** on GitHub before the button works. Until it's granted, the drawer shows the button but the action returns the exact grant-and-retry instruction rather than failing silently — grant it in **GitHub → your org → Installed GitHub Apps → BreachLens → Review request**, then retry.
</Warning>

## Keep it honest over time

Posture drifts — a repo that had branch protection yesterday can lose it today. Re-run posture on a schedule to turn this one-time audit into an ongoing control; the **⇆ Diff** on each scan shows exactly what changed since the last run.

## Next steps

<CardGroup cols={2}>
  <Card title="Monitor posture continuously" icon="repeat" href="/pipeline/continuous-monitoring">
    Schedule nightly posture re-scans and route drift to Slack / Teams / Jira.
  </Card>

  <Card title="Scan a repository" icon="code" href="/scanning/repositories">
    The code side — SAST, SCA, secrets, and IaC — plus the full GitHub App permission matrix.
  </Card>
</CardGroup>
