# Check my Mac

> How Check my Mac answers each Cloak Watch headline: the four answers, what it reads in packages, versions, trust stores, services and repos, and its limits.

Source: https://docs.subcloak.com/cloak-watch/check-my-mac/

**Check my Mac** answers one question for every headline in the [Feed](https://docs.subcloak.com/cloak-watch/feed/): does this incident touch this Mac? Watch looks at what the incident is about, whether that's a package, an app version, a certificate authority, a service you sign in to or a GitHub workflow, in what your last scan found, and answers **This Mac is affected**, **Relevant to you**, **Not affected** or **Not checked**, with the places behind the answer and what to do about each one.

Everything happens on your Mac. Watch never runs anything to check, never reads a token's value, and never sends what it finds anywhere.

## Where you see it

- **Headlines.** Each headline has a **Check my Mac** box near the top of its page.
- **Live entries.** Selecting an entry in **Live** shows the same box, answered from the packages and extensions on this Mac. See [Check my Mac in the Feed](https://docs.subcloak.com/cloak-watch/feed/#check-my-mac).
- **The Inbox.** When a headline's checks answer **This Mac is affected** or **Relevant to you**, the answer also becomes an Inbox card (package answers come from incident packs instead), so you don't need to open the Feed to see it. See [Inbox cards](#inbox-cards-from-these-checks).

The box reads the inventory from your last scan, so opening a headline doesn't start a scan. Before the first scan it says **Not checked** with **Scan Now**.

## The four answers

| Answer | Glyph | When Watch says it |
|---|---|---|
| **This Mac is affected** | Orange triangle | The Mac has what the incident is about: a package at a listed version, an app or tool in an affected version range, a trust store that still trusts the certificate authority, the incident's workflow, or a file it leaves behind. |
| **Relevant to you** | Info circle, in your accent color | The Mac holds a login, token or config file for a service the incident is about, but Watch can't see your account, so it can't say whether your account was among those affected. Comes with ordered steps. |
| **Not affected** | Green shield | Watch checked and found nothing, and says what it checked. |
| **Not checked** | Grey question mark | Watch can't check it, and says why: there hasn't been a scan yet, the incident names nothing a Mac can look for, it's about container images and no container engine was running at the last scan, or it needs a check this version doesn't know. |

When one of the headline's [incident packs](https://docs.subcloak.com/cloak-watch/feed/#free-and-the-live-feed) has already opened an incident on this Mac, that incident wins: the box says **Affected: yes** with **Open Incident**. When the pack's bad version is here but only a lockfile pins it, so its code never ran, the box says **Not affected** and **Open Incident** opens the card that reminds you to remove the pin.

A brief, a short headline marked **Single source · developing**, is never checked. Its box says **Not checked**: "A single-source brief. Watch checks this Mac once more sources confirm it." Its packages are listed under **Packages named**, for reading only.

### What the box shows

Under the answer, one line says why, for example "3 trust stores on this Mac still trust Example Root CA - G1." Then, when there's more to say:

| Part | What it shows |
|---|---|
| One line per check | When the headline has several checks, each one's answer, worst first. |
| The places | Each place behind an answer: a label (such as **nvm Node v24.15.0** or **macOS**), what Watch saw there, the file's path, and that place's fix. Places that were checked and are fine are listed with a dash. Up to 8 are shown, then **And N more**. |
| **In this order** | Numbered steps, each with a link when there is one, for **Relevant to you** answers. |
| **What Watch checked** | What Watch read for each check, and what it can't see. |

Buttons:

- **Open in Inbox** opens the Inbox card for this headline when there is one.
- **Open Software Update** appears when macOS or Safari is an affected version. It opens **System Settings › General › Software Update**.
- **Scan Now** appears before the first scan.

## What each check reads

A headline lists the checks a Mac can run for it. Some are written into the headline; others come from what every headline already has: its affected packages, the products it names (PHP in a PHP flaw is the PHP engine, not a Packagist package), file paths among its indicators, and workflow file names among its indicators.

Every check reads the inventory Watch already built. Only the host-file check looks at the disk when you open the headline, and only at the exact paths the incident names.

### Packages

Watch looks for each affected package in the [Inventory](https://docs.subcloak.com/cloak-watch/inventory/#packages): lockfiles, installed packages, global installs and download caches. A package matches when it's at a listed version, or inside a listed range such as "8.5 before 8.5.12".

- **This Mac is affected**: for example "quickcache-utils-demo 6.0.0 is installed at a listed version.", with where.
- **Not affected**: for example "Checked 1,240 npm items: no quickcache-utils-demo at a listed version.", or the package is installed at another version.
- **Not checked**: for ecosystems Watch doesn't list.
- **Container images** are looked up in the images each running container engine listed at the last scan (from 1.2.0). When no engine was running, the answer says Watch couldn't look. See [Container images](https://docs.subcloak.com/cloak-watch/container-images/).

### Files an incident leaves

When a headline names files on the Mac by path (for example `~/Library/Caches/example-helper`), Watch checks whether each exists. A file or folder that's there makes the answer **This Mac is affected**, with "Follow What to do below before you delete anything." Watch doesn't open or delete it.

### Versions of macOS, apps and tools

A version check compares the versions of an app or tool on this Mac with the affected ranges the headline gives. Watch reads each version from a file, without running anything:

| What | Where Watch reads the version |
|---|---|
| macOS | `/System/Library/CoreServices/SystemVersion.plist` |
| Safari, Google Chrome, Firefox, Microsoft Edge, Brave, Arc, Docker Desktop, OrbStack, Xcode (including betas), Visual Studio Code, Cursor, Windsurf, Zed, Claude, ChatGPT, Slack, and JetBrains IDEs (IntelliJ IDEA, PyCharm, WebStorm, GoLand and others, and Android Studio) | The app's `Contents/Info.plist`, in `/Applications`, `/Applications/Utilities`, `~/Applications` and `~/Applications/JetBrains Toolbox` |
| Apple's Git (the Command Line Tools' and each Xcode's) and Apple's OpenSSH | The version text inside the program file, for example "2.54.0 (Apple Git-157)" |
| Node.js | nvm, Volta, fnm, asdf and mise version folders; Homebrew's linked `node`; `node_version.h` for the nodejs.org installer |
| Python, Ruby, Go, Java | pyenv, uv and rbenv version folders; the python.org installer's `Info.plist`; `/usr/local/go/VERSION`; a JDK's `release` file in `/Library/Java` or `~/Library/Java` |
| Homebrew formulae (git, openssh, php, python, ruby, go, openjdk, node, codex, gemini-cli) and casks | A formula's linked version (its `opt` link), never an older copy left in the Cellar; a cask's installed version |
| Claude Code, Codex CLI, Gemini CLI | Claude Code's native install folder, and global npm installs |

Each copy is judged on its own: a Mac with two Node versions can have one affected and one fixed. Each affected copy's fix names the release that fixes it on its own branch, for example "Update to 8.4.12 or later."

### Exploited flaws

Separately from headlines, Watch flags any copy of macOS, Safari, a browser or a developer tool above that is missing the fix for a flaw known to be exploited. The list comes in the signed feed and is built from Apple's list of actively exploited macOS and Safari flaws and CISA's Known Exploited Vulnerabilities catalog. Each affected copy gets a Review card, [VER-1](https://docs.subcloak.com/cloak-watch/detections/#ver-1), such as "macOS 26.6.2 has an exploited flaw", naming the flaw and the release that fixes it.

> **Not a CVE scanner:**
> Watch only reports flaws that are known to be exploited, and only in macOS, apps and tools installed on this Mac. It never reports vulnerabilities in the libraries your projects use.

### Trust stores

When a certificate authority (CA) is distrusted, browsers update within hours, but command-line tools and runtimes carry their own lists of trusted CAs. A trust-store check tells you which of those lists on this Mac still trust the CA, and how to fix each one. Watch reads them as files:

| Store | Where | Used by | Fix Watch suggests |
|---|---|---|---|
| Apple system roots | `/System/Library/Security/Certificates.bundle/Contents/Resources/Anchors` | Safari, curl, git, Go tools | None while Apple's revocation list is newer than Apple's block; otherwise install pending macOS updates |
| Apple revocation list | `/private/var/protected/trustd/valid.sqlite3` (only its date) | Every Apple TLS check | Install pending macOS updates and keep the Mac online |
| LibreSSL bundle | `/etc/ssl/cert.pem` | openssl, LibreSSL tools | Only a macOS update changes it |
| Homebrew ca-certificates | `share/ca-certificates/cacert.pem` and `etc/ca-certificates/cert.pem` under `/opt/homebrew` or `/usr/local` | Homebrew curl, openssl@3 | `brew upgrade ca-certificates` |
| Python certifi | Every `certifi/cacert.pem` in pyenv, pipx, uv tools and uv's cache, `~/Library/Python`, python.org Python, conda (Miniconda, Anaconda, Miniforge), Homebrew Python, and your projects' `.venv`, `venv` and `env` | Python requests, httpx | Upgrade certifi in that environment |
| Node.js | The roots compiled into each `node` program from nvm, Volta, fnm, asdf, mise, Homebrew and the nodejs.org installer | Node.js | Install a Node.js release with the updated roots |
| Electron apps | The roots compiled into `Electron Framework` inside apps in `/Applications` and `~/Applications` | The app's Node runtime | Update the app |
| JDKs | `lib/security/cacerts` in `/Library/Java`, `~/Library/Java`, Homebrew openjdk, SDKMAN, and Java bundled inside apps | Java | Update the JDK |
| Roots added to the keychains | The user and admin trust settings, through macOS's Security framework | Everything that uses the keychain | If you don't use it, remove it in Keychain Access |
| Keychain certificates | Certificates in your keychains: their issuer and subject names only | Your signing and client certificates | Replace the certificate with one from another CA |

Watch matches CAs by their public key (the SHA-256 of the certificate's public key, the method Homebrew uses to drop distrusted roots), so every certificate with the same key matches, whatever its name. For each certificate in a store it keeps only the first 16 hex digits of that hash.

Apple distrusts CAs through its revocation list, which updates on its own. So when Apple's roots still list a distrusted CA but this Mac's revocation list is newer than Apple's block, Watch shows Apple's roots as fine, with when the list last updated.

Watch also raises [TRUST-1](https://docs.subcloak.com/cloak-watch/detections/#trust-1) for any root certificate someone added to the keychains' trust settings, with or without a headline.

### Services you're signed in to

When a service you use is breached, a Mac can't know whether your account was among those affected. It can know that you use the service. A service check looks for that service's login, token and config files.

> **Watch never reads the token:**
> Watch checks that a file exists. For a few files it notes the names that say what the login covers, such as registry hosts or profile names, and drops anything that looks like a secret. It never keeps or sends a value, and it doesn't test whether a token still works, because that would mean sending it.

| What Watch reads | Files | What it keeps |
|---|---|---|
| Presence only | Most files, for example `~/.kube/config`, `~/.fly/config.yml`, `~/.codex/auth.json` and `~/.claude.json` | That the file exists, and its dates |
| JSON top-level keys | OpenCode's `~/.local/share/opencode/auth.json` | Provider names, such as `anthropic` and `openai` |
| Docker registries | `~/.docker/config.json` (`auths` and `credHelpers`) | Registry hosts |
| npm auth lines | `~/.npmrc` | Hosts that have an auth line |
| YAML top-level keys | GitHub CLI's `~/.config/gh/hosts.yml` | Hosts |
| INI section names | `~/.aws/credentials`, `~/.aws/config`, `~/.pypirc`, `~/.modal.toml` | Profile names |
| `.netrc` machines | `~/.netrc` | Machine names |
| Terraform credentials | `~/.terraform.d/credentials.tfrc.json` | Hosts |

A folder counts only when something is in it. A shared file such as `~/.docker/config.json` or `~/.netrc` counts for a service only when it has that service's own entry.

Cloak Watch 1.1 knows 45 services: OpenCode, Docker Hub, GitHub, GitLab, npm, PyPI, AWS, Google Cloud, Azure, Kubernetes, Cloudflare, Vercel, Netlify, Fly.io, Heroku, Supabase, Railway, Render, HCP Terraform, Doppler, Pulumi, CircleCI, Hugging Face, Stripe, Anthropic, OpenAI, Google AI (Gemini), Cursor, ngrok, Firebase, Modal, Sentry, Expo, RubyGems, crates.io, 1Password CLI, JFrog, SonarQube Cloud, Snyk, Datadog, Linear, Slack, Postman, DigitalOcean and PlanetScale. Subcloak can add services, or correct a path or a link, through the signed feed, without an app update.

The answer:

- **Relevant to you** when any of the files is there: "This Mac uses Docker Hub (1 file). Watch can't see your Docker Hub account.", with each file and what it names, then the steps under **In this order**:
  1. The headline's own steps, word for word from its source.
  2. Revoke the credentials this Mac holds for the service and create new ones, with a link to the service's page for that when it has one.
  3. When an AI tool stored keys for other providers there (OpenCode's `auth.json` listing `anthropic` and `openai`, say), rotate each of those keys at its provider.
  4. Put the new credentials in the files Watch found, and in your CI secrets.
  5. Review the service's recent activity since the incident started, when the service has an activity log.
- **Not affected** when this Mac has no login or config for the service.
- **Not checked** for a service this version of Watch doesn't know.

The [Inventory's Services tab](https://docs.subcloak.com/cloak-watch/inventory/#services) lists every login and config Watch found.

### Repositories and workflows

When a headline is about planted or compromised GitHub Actions workflows, Watch checks the workflows in the local clones under your [code folders](https://docs.subcloak.com/cloak-watch/settings/#general). A workflow matches when it has one of the incident's workflow file names, names one of its IP addresses, domains or URLs, contains one of its other strings, or uses one of the actions it names (`owner/repo` matches any version; `owner/repo@ref` only that one).

- **This Mac is affected**: one row per matching workflow, such as `shopapp/release.yml`, with why it matched and the fix: check the commit that added it, and if it isn't yours, delete it and rotate every secret the repository has.
- **Not affected**: "No workflow in this Mac's local repositories matches this incident.", with what was read under **What Watch checked**, for example "Read 14 workflows in 6 local repositories for the file name deploy.yml." With no clones, it says "Watch found no local repositories on this Mac."

Watch also checks your repositories on every scan, without a headline: workflows that could leak secrets, tokens in Git remotes, Terraform state and package settings open to dependency confusion. See [REPO-1 to REPO-11](https://docs.subcloak.com/cloak-watch/detections/#repositories-and-ci-repo).

## Inbox cards from these checks

| Card | Tier | When |
|---|---|---|
| **Affected:** and the headline's title | Review | A headline's version, trust-store, service, repository or host-file checks answer **This Mac is affected**. The card lists each place and its fix. |
| **Relevant to you:** and the headline's title | FYI | A headline's checks answer **Relevant to you**. The card carries the same ordered steps. |
| [VER-1](https://docs.subcloak.com/cloak-watch/detections/#ver-1) | Review | An installed copy of macOS, an app or a tool is missing the fix for an exploited flaw. |
| [TRUST-1](https://docs.subcloak.com/cloak-watch/detections/#trust-1) | Review, or FYI for a known debugging proxy's CA | A root certificate was added to the keychains' trust settings. |

Package answers don't make their own cards: those come from the headline's incident packs, which carry the full fix. See [CHK cards](https://docs.subcloak.com/cloak-watch/detections/#headline-checks-chk) in the detection catalogue.

## What Watch never does

- **Never runs anything.** Versions come from plist files and the text inside program files; trust stores and workflows are read as files. Watch never runs `git`, `node`, `docker` or any tool to ask.
- **Never reads token values.** Service checks note that a file exists, plus a few names. Git remote checks keep the remote, host and kind of credential, never the credential.
- **Never sends what it finds.** Every answer is worked out on this Mac from the signed feed Watch already downloaded. See [what leaves your Mac](https://docs.subcloak.com/cloak-watch/settings/#what-leaves-your-mac).
- **Never changes anything.** Check my Mac only answers; fixing is up to you, with the steps it gives.

## Limits

| Watch can't see | Why |
|---|---|
| Your account at a service | Watch sees that this Mac has a login, not what happened to the account. That's why the answer is **Relevant to you**, not **This Mac is affected**. |
| Tokens kept only in the Keychain, a password manager, or a browser | Watch looks for files. Web-only logins leave nothing to find. |
| Images while their runtime is stopped, and trust stores inside containers | Images live inside the container runtime's virtual machine; Watch lists them only while its engine runs, and never looks inside them. |
| Which trust store a running program used | Watch reads every store on disk, not what a process loaded. |
| pip's own built-in copy of certifi | Watch reads `certifi` packages, not the copy inside pip. |
| Repositories that are only on GitHub | Watch reads local clones. The [GitHub connection](https://docs.subcloak.com/cloak-watch/github/), coming soon, adds a headline's workflow checks on GitHub (GH-5) and workflow runs (GH-4). |
| Whether a workflow ran, and your repository's Actions settings | These live on GitHub: only the [GitHub connection](https://docs.subcloak.com/cloak-watch/github/) can see them. |
| Changes since the last full scan, for some places | Apps in `/Applications`, Electron apps, Apple's roots and the keychains are read by the daily full scan or **Scan Now**, not within seconds of a change. |

## From Terminal

[`watchctl`](https://docs.subcloak.com/cloak-watch/watchctl/) runs the same checks without the full package scan:

```bash title="Terminal"
watchctl checks --headlines headlines.json
```

It reads this Mac's trust stores, apps and tools, services and workflows, then prints each headline's answer with its places and steps. `--headlines` takes a file of headlines in the feed's format. Add `--only H-2026-0001,H-2026-0002` to answer only those headlines, `--json` for JSON, `--all` to also list places that are fine, and `--roots DIR,DIR` to choose the code folders.

## Related

  - [Feed](https://docs.subcloak.com/cloak-watch/feed/): Live, Headlines and where the checks come from.
  - [Detection catalogue](https://docs.subcloak.com/cloak-watch/detections/): VER-1, TRUST-1, CHK and REPO cards.
  - [Inventory](https://docs.subcloak.com/cloak-watch/inventory/): Apps & tools, Trust stores and Services tabs.
  - [Settings › Privacy](https://docs.subcloak.com/cloak-watch/settings/#what-leaves-your-mac): Every request Cloak Watch makes.
