Detecting and removing dangerous secrets on dev workstations before Shai-Hulud does :: Recyclebin.zipDetecting and removing dangerous secrets on dev workstations before Shai-Hulud does<br>2026-05-25Guillaume Ross<br>Credential theft from developer workstations#<br>Let’s use a combination of open-source tools to detect problematic clear-text secrets on workstations and to ensure they’re not so easy for malware/scripts to steal.<br>PyPI, npm, VS Code Extensions, OpenVSX, brew and other package managers expand the attack surface on workstations. While companies still lie to themselves that “all code changes are reviewed”, millions of developers have code execution access to workstations, and those developers can get compromised by various threat actors. Now that non-technical users run agents which pull the same packages, the issue is spreading to every workstation.<br>There are many controls we can apply to workstations, but it can be difficult to do so, especially for smaller organizations.<br>So what do most companies do? It varies but typically goes from nothing to hope our endpoint security tools block this.<br>How can we make this better with open-source tools?#<br>The solution is straightforward, but requires a few tools:<br>A tool to find secrets and output results. bagel<br>A tool to check results for compliance. fleet + osquery<br>Integration to tools like Slack and Identity Providers. fleet<br>The high-level workflow looks like this:<br>flowchart TD<br>A[bagel scans workstation<br>on schedule via LaunchAgent] --> B[Scan results written as JSON]<br>B --> C[Fleet reads results<br>via osquery + parse_json]<br>C --> D{Policy check:<br>any critical findings?}<br>D -->|No| E[Workstation passes policy]<br>D -->|Yes| F[Workstation fails policy]<br>F --> G[Slack notification<br>sent to developer]<br>F --> H[IdP queries Fleet policy on SSO attempt]<br>H -- Entra Conditional Access Check --> I[SSO blocked until remediated]<br>Bagel#<br>An open-source tool by Boost Security, bagel scans a user’s home directory for secrets commonly used by developers. It is configurable, with probes for SSH keys, GitHub credentials, cloud provider credentials, and more. It outputs JSON, and includes the severity and location of each finding, but of course does not log the actual secrets. Bagel, written in Go, is fast and focused, looking for secrets in the same places where malware usually does. Think of it as an analogue of trufflehog, but for workstations instead of repos.<br>As it is a command-line tool, it can easily be scheduled with a LaunchAgent, and as its output is JSON, it is easy to integrate with other tools to build a solution instead of just telling developers to “run bagel and clean up”.<br>Fleet#<br>Fleet is an open-source platform for IT and security, which uses osquery for telemetry. Think of it as an MDM (mobile device management) and osquery server, managed via GitOps (recommended).<br>Fleet provides the following features that are critical to making our secret scanning more robust than a simple ad-hoc effort:<br>Package deployment.<br>Policy queries, or “checks”. These queries are considered to pass if results are returned, and to fail if there are none.<br>A Fleet-specific osquery table for parsing JSON.<br>An API to integrate third-party tools like IdPs to check on compliance status, as well as webhook notifications to integrate to orchestration tools like n8n, SIEM, etc.<br>Fleebag#<br>As a proof of concept, I figured it would be relatively easy to hook these up together.<br>Fleebag (for fleet-bagel as I am an expert at naming things) is a simple vibe-coded repository containing the following:<br>Scripts to create a macOS installation package of bagel, with a LaunchAgent running it on a schedule, outputting logs to a standard destination.<br>A Fleet query for all secrets that bagel found on each workstation.<br>A Fleet policy query that passes if fleebag results are fresh and contain no critical findings, which you can tune to your desired severity.<br>An example macOS profile to grant bagel full disk access, so you don’t have to rely on end users approving security prompts on macOS.<br>Example query#<br>This query is for macOS, as is the rest of fleebag, though with bagel and fleet this can easily be adjusted to other platforms by tweaking paths and swapping LaunchAgent files with cron jobs or scheduled tasks.<br>WITH findings_base AS (<br>-- One group per finding element: parent is exactly 'findings/N'.<br>-- NOT LIKE 'findings/%/%' excludes findings/N/metadata, findings/N/locations, etc.<br>-- Without this guard those sub-groups produce NULL-filled rows with only a timestamp.<br>SELECT<br>pj.path,<br>pj.parent,<br>MAX(CASE WHEN pj.key = 'severity' THEN pj.value END) AS severity,<br>MAX(CASE WHEN pj.key = 'id' THEN pj.value END) AS rule_id,<br>MAX(CASE WHEN pj.key = 'probe' THEN pj.value END) AS probe,<br>MAX(CASE WHEN pj.key = 'path' THEN pj.value END) AS file_path,<br>MAX(CASE WHEN pj.key = 'fingerprint' THEN pj.value END) AS fingerprint,<br>MAX(CASE WHEN pj.key = 'title' THEN pj.value END) AS title<br>FROM...