Protect your Mac
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.
Check my Mac answers one question for every headline in the 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
Section titled “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.
- 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.
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
Section titled “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 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
Section titled “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
Section titled “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
Section titled “Packages”Watch looks for each affected package in the Inventory: 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.
Files an incident leaves
Section titled “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
Section titled “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
Section titled “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, such as “macOS 26.6.2 has an exploited flaw”, naming the flaw and the release that fixes it.
Trust stores
Section titled “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 for any root certificate someone added to the keychains’ trust settings, with or without a headline.
Services you’re signed in to
Section titled “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.
| 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:
- The headline’s own steps, word for word from its source.
- 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.
- When an AI tool stored keys for other providers there (OpenCode’s
auth.jsonlistinganthropicandopenai, say), rotate each of those keys at its provider. - Put the new credentials in the files Watch found, and in your CI secrets.
- 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 lists every login and config Watch found.
Repositories and workflows
Section titled “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. 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.
Inbox cards from these checks
Section titled “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 | Review | An installed copy of macOS, an app or a tool is missing the fix for an exploited flaw. |
| 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 in the detection catalogue.
What Watch never does
Section titled “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,dockeror 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.
- Never changes anything. Check my Mac only answers; fixing is up to you, with the steps it gives.
Limits
Section titled “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, 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 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
Section titled “From Terminal”watchctl runs the same checks without the full package scan:
watchctl checks --headlines headlines.jsonIt 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.