SecureClipboard
May 31, 2026 · View on GitHub
macOS menu bar app that automatically scans clipboard content with secretlint and masks detected secrets. Secure by default.
Motivation
Secrets copied to the clipboard can accidentally end up in unintended places — a Linear issue title, a Slack message, a search bar. You don't always notice what's in your clipboard before pasting. SecureClipboard masks secrets at the moment of copy, so even accidental pastes are safe.
When you intentionally need the raw value, select "Copy Original Text" from the menu bar to retrieve the unmasked content. The raw value is automatically cleared from the clipboard after 90 seconds (same as 1Password). This two-step process ensures secrets are only exposed when you explicitly choose to, and never linger on the clipboard.
Requirements
- macOS 14 (Sonoma) or later
- Apple Silicon or Intel Mac
Install
curl -fSL https://github.com/secretlint/secure-clipboard/releases/latest/download/SecureClipboard.app.zip -o /tmp/SecureClipboard.app.zip
unzip -o /tmp/SecureClipboard.app.zip -d /Applications
xattr -cr /Applications/SecureClipboard.app
open /Applications/SecureClipboard.app
Uninstall
rm -rf /Applications/SecureClipboard.app
rm -f /usr/local/bin/secure-pbpaste /usr/local/bin/secure-pbcopy
Features
- Monitors clipboard changes (500ms polling)
- Text: scans with secretlint, replaces secrets with
*** - Image: OCR via Vision framework, scans extracted text, redacts secret regions with natural-looking crystallize + blur effect
- Menu bar icon turns red on detection with macOS notification
- "Copy Original Text" / "Copy Original Image" menu items to retrieve unmasked content (auto-cleared after 90 seconds, same as 1Password). Marked as concealed so clipboard managers (Alfred, etc.) don't record it.
- CLI tools:
secure-pbpasteandsecure-pbcopybundled in the app - Auto-updates secretlint binary from GitHub releases
- Localized (English / Japanese)
Demo
Copy text containing a secret — SecureClipboard will automatically replace it with *** in your clipboard.
Try it: copy the following Slack token and paste it somewhere.
xoxb-1234567890123-1234567890123-AbCdEfGhIjKlMnOpQrStUvWx
After copying, your clipboard will contain:
*********************************************************
If you need the raw (unmasked) text, click the menu bar icon and select "Copy Original Text". The clipboard is automatically cleared after 90 seconds.
Supported secret types: AWS, GitHub, Slack, GCP, Azure, npm, Docker, and more. You can also define custom patterns.
Configuration
Config file: ~/.config/secure-clipboard/config.json (open via menu: "Open config.json")
{
"rules": [
{ "id": "@secretlint/secretlint-rule-preset-recommend" }
],
"patterns": [
{ "name": "mask-example", "pattern": "/INTERNAL_\\w+/i", "action": "mask" },
{ "name": "discard-example", "pattern": "/CONFIDENTIAL/i", "action": "discard" }
],
"skipScanAppIdentifiers": [
"com.1password.1password",
"com.runningwithcrayons.alfred.clipping"
],
"scanDelaySeconds": 0,
"clearClipboardAfterSeconds": null
}
rules
secretlint rules for detecting known secrets. @secretlint/secretlint-rule-preset-recommend detects AWS, GitHub, Slack, GCP, Azure, npm, Docker, and more. Removing this rule disables all built-in secret detection.
patterns
Custom patterns with two actions:
| Text | Image | |
|---|---|---|
"action": "mask" | Matched portions replaced with *** | Secret regions redacted with crystallize + blur effect |
"action": "discard" | Entire clipboard replaced with [DISCARDED: <name>] | Entire image replaced with red warning image |
Patterns use /regex/flags syntax. Supported flags: i (case-insensitive), m (multiline), s (dotAll).
Each pattern can also take an optional allows array of regexes. Matches that overlap any allows regex are excluded from detection (same semantics as secretlint's allows).
{
"patterns": [
{
"name": "discard-aaa",
"pattern": "/aaa/",
"action": "discard",
"allows": ["/https?:\\/\\/[^\\s]*aaa/"]
}
]
}
In the example above, bare aaa discards the clipboard, but aaa inside a URL is allowed.
scanDelaySeconds
Seconds to wait before scanning clipboard content. Default: 0 (immediate). During the delay, the raw value remains in the clipboard for normal paste operations. If the clipboard changes during the delay, the previous scan is cancelled.
{
"scanDelaySeconds": 5
}
clearClipboardAfterSeconds
Seconds after the last clipboard change before the clipboard is automatically cleared. Default: null (disabled). This helps avoid accidentally pasting stale content copied earlier. The timer effectively resets on every clipboard change: if you copy something new within the interval, only the latest content is cleared. Set to null or 0 to disable.
{
"clearClipboardAfterSeconds": 60
}
This applies to all clipboard changes, including copies from apps listed in skipScanAppIdentifiers (those copies are not scanned, but are still cleared). It does not affect "Copy Original Text" / "Copy Original Image", which keep their own fixed 90-second auto-clear window.
skipScanAppIdentifiers
Identifiers to skip scanning for. Each value is matched against:
- The frontmost app's bundle identifier at the moment of copy
- The
org.nspasteboard.sourcestring on the pasteboard, if present - Any pasteboard type string on the clipboard
Use the frontmost bundle ID for apps like 1Password where the app is active when copying (com.1password.1password).
Clipboard managers such as Alfred write a distinctive pasteboard type when re-copying from their history. To ignore re-copies from Alfred's clipboard history, add com.runningwithcrayons.alfred.clipping (the pasteboard type).
Config changes are picked up on the next clipboard copy — no restart required.
CLI Tools
SecureClipboard bundles secure-pbpaste and secure-pbcopy — drop-in replacements for pbpaste and pbcopy that automatically mask secrets.
Unlike regular pbcopy, raw text never touches the clipboard. secure-pbcopy sends text to the running app via IPC (Unix Domain Socket), the app scans and masks it, and only the masked text is written to the clipboard. If the app is not running, it is automatically launched in the background.
Install via menu bar: click the SecureClipboard icon → "Install CLI Tools". This creates symlinks in /usr/local/bin/ (requires admin password).
Or manually:
ln -sf /Applications/SecureClipboard.app/Contents/MacOS/secure-pbpaste /usr/local/bin/secure-pbpaste
ln -sf /Applications/SecureClipboard.app/Contents/MacOS/secure-pbcopy /usr/local/bin/secure-pbcopy
Usage:
secure-pbpaste # outputs clipboard text with secrets masked
echo "text" | secure-pbcopy # copies text to clipboard with secrets masked
Development
# Download secretlint binary
bash scripts/download-secretlint.sh 11.7.1
# Build
swift build --disable-sandbox
# Test
swift test --disable-sandbox
# Build .app bundle
bash scripts/build-app.sh
--disable-sandbox is required for NSPasteboard access.
Architecture
SecureClipboard/
├── SecureClipboardApp.swift # App entry, menu bar setup
├── AppConfig.swift # Config loading (config.json)
├── ClipboardMonitor.swift # NSPasteboard polling, change detection
├── SecretScanner.swift # secretlint binary subprocess
├── ClipboardRewriter.swift # Clipboard overwrite (text + image)
├── ImageSecretDetector.swift # Vision OCR + secret scan
├── IPCServer.swift # Unix Domain Socket server for CLI tools
├── StatusState.swift # Observable app state
├── MenuBarView.swift # Menu bar UI
├── SecretlintUpdater.swift # Auto-update from GitHub releases
└── Resources/
├── secretlintrc.json # Default secretlint config
├── en.lproj/ # English strings
└── ja.lproj/ # Japanese strings
SecureClipboardCLI/
└── SecurePBMain.swift # secure-pbpaste/secure-pbcopy binary
License
MIT