Security: forbesfields/coderswitch

Security

SECURITY.md

Security Policy

CoderSwitch is a local macOS menu bar app that stores AI provider credentials, runs a loopback-only proxy, and can import or export credentials for local CLI tools. Treat the app and its local data directory as sensitive.

Supported Versions

CoderSwitch is pre-1.0 software. Security fixes are expected to land on the latest main branch unless a tagged release states otherwise.

Reporting a Vulnerability

Please do not open a public issue that contains API keys, OAuth tokens, local database files, .coderswitchconfig exports, screenshots of credentials, or other sensitive material.

If GitHub private vulnerability reporting is enabled for this repository, use that first. If it is not enabled, contact the maintainer privately through GitHub before publishing details. Include:

  • A concise description of the issue.
  • Steps to reproduce, preferably with test credentials or redacted examples.
  • The affected commit or release.
  • Any evidence of real credential exposure.

Secret Handling

  • Do not commit real API keys, OAuth tokens, .env files, signing identities, provisioning profiles, SQLite app data, .master.key, or .coderswitchconfig exports.
  • API keys and OAuth tokens are encrypted in CoderSwitch's local SQLite database with CryptoKit SecretBox.
  • The current SecretBox root key is stored as a mode-0600 file in ~/Library/Application Support/CoderSwitch/.master.key. This protects against casual database inspection, but it is not equivalent to Keychain protection against same-user malware, broad filesystem access, or copied backups.
  • Config backup files (*.coderswitchconfig) contain decrypted API keys, OAuth tokens, proxy settings, and the proxy admin key. Keep them private and delete them when no longer needed.
  • CLIProxyAPI-compatible auth files written under ~/.cli-proxy-api contain OAuth credentials in plaintext files with local filesystem permissions. This is a local-tool interoperability tradeoff.
  • Google OAuth client secrets should not be committed. If a Google OAuth client still requires a secret for local testing, provide it with CODERSWITCH_GOOGLE_OAUTH_CLIENT_SECRET or a local CoderSwitchGoogleOAuthClientSecret Info.plist value.

Local Proxy Model

The proxy is designed for local use and binds to 127.0.0.1. Protected proxy routes require the generated admin key shown in Settings. Do not expose the proxy port to a LAN, public interface, tunnel, reverse proxy, or container network unless you have added your own access controls.

Use HTTPS custom provider endpoints whenever possible. Plain HTTP should be reserved for explicit local development endpoints such as localhost or 127.0.0.1.

Known Hardening Items

Before broad distribution, the highest-value hardening work is:

  • Move the SecretBox root key from .master.key into macOS Keychain and migrate existing users safely.
  • Add OAuth state generation and validation.
  • Restrict the OAuth callback listener and reject unexpected callback paths.
  • Remove global App Transport Security arbitrary loads and validate custom endpoints before saving them.
  • Move the proxy admin key out of plaintext SQLite storage.
  • Decide whether the app should be sandboxed for public distribution, and document any intentional exceptions.

Dependency and Release Checks

Before publishing a release:

  • Run xcodebuild -scheme CoderSwitch -configuration Debug test.
  • Run git diff --check.
  • Scan the working tree and Git history for secret-like values.
  • Rotate any credential that was ever committed to Git history before pushing the repository publicly.

There aren't any published security advisories

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Security: forbesfields/coderswitch

Security

SECURITY.md

Security Policy

CoderSwitch is a local macOS menu bar app that stores AI provider credentials, runs a loopback-only proxy, and can import or export credentials for local CLI tools. Treat the app and its local data directory as sensitive.

Supported Versions

CoderSwitch is pre-1.0 software. Security fixes are expected to land on the latest main branch unless a tagged release states otherwise.

Reporting a Vulnerability

Please do not open a public issue that contains API keys, OAuth tokens, local database files, .coderswitchconfig exports, screenshots of credentials, or other sensitive material.

If GitHub private vulnerability reporting is enabled for this repository, use that first. If it is not enabled, contact the maintainer privately through GitHub before publishing details. Include:

  • A concise description of the issue.
  • Steps to reproduce, preferably with test credentials or redacted examples.
  • The affected commit or release.
  • Any evidence of real credential exposure.

Secret Handling

  • Do not commit real API keys, OAuth tokens, .env files, signing identities, provisioning profiles, SQLite app data, .master.key, or .coderswitchconfig exports.
  • API keys and OAuth tokens are encrypted in CoderSwitch's local SQLite database with CryptoKit SecretBox.
  • The current SecretBox root key is stored as a mode-0600 file in ~/Library/Application Support/CoderSwitch/.master.key. This protects against casual database inspection, but it is not equivalent to Keychain protection against same-user malware, broad filesystem access, or copied backups.
  • Config backup files (*.coderswitchconfig) contain decrypted API keys, OAuth tokens, proxy settings, and the proxy admin key. Keep them private and delete them when no longer needed.
  • CLIProxyAPI-compatible auth files written under ~/.cli-proxy-api contain OAuth credentials in plaintext files with local filesystem permissions. This is a local-tool interoperability tradeoff.
  • Google OAuth client secrets should not be committed. If a Google OAuth client still requires a secret for local testing, provide it with CODERSWITCH_GOOGLE_OAUTH_CLIENT_SECRET or a local CoderSwitchGoogleOAuthClientSecret Info.plist value.

Local Proxy Model

The proxy is designed for local use and binds to 127.0.0.1. Protected proxy routes require the generated admin key shown in Settings. Do not expose the proxy port to a LAN, public interface, tunnel, reverse proxy, or container network unless you have added your own access controls.

Use HTTPS custom provider endpoints whenever possible. Plain HTTP should be reserved for explicit local development endpoints such as localhost or 127.0.0.1.

Known Hardening Items

Before broad distribution, the highest-value hardening work is:

  • Move the SecretBox root key from .master.key into macOS Keychain and migrate existing users safely.
  • Add OAuth state generation and validation.
  • Restrict the OAuth callback listener and reject unexpected callback paths.
  • Remove global App Transport Security arbitrary loads and validate custom endpoints before saving them.
  • Move the proxy admin key out of plaintext SQLite storage.
  • Decide whether the app should be sandboxed for public distribution, and document any intentional exceptions.

Dependency and Release Checks

Before publishing a release:

  • Run xcodebuild -scheme CoderSwitch -configuration Debug test.
  • Run git diff --check.
  • Scan the working tree and Git history for secret-like values.
  • Rotate any credential that was ever committed to Git history before pushing the repository publicly.

There aren't any published security advisories

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Security: forbesfields/coderswitch

Security

SECURITY.md

Security Policy

CoderSwitch is a local macOS menu bar app that stores AI provider credentials, runs a loopback-only proxy, and can import or export credentials for local CLI tools. Treat the app and its local data directory as sensitive.

Supported Versions

CoderSwitch is pre-1.0 software. Security fixes are expected to land on the latest main branch unless a tagged release states otherwise.

Reporting a Vulnerability

Please do not open a public issue that contains API keys, OAuth tokens, local database files, .coderswitchconfig exports, screenshots of credentials, or other sensitive material.

If GitHub private vulnerability reporting is enabled for this repository, use that first. If it is not enabled, contact the maintainer privately through GitHub before publishing details. Include:

  • A concise description of the issue.
  • Steps to reproduce, preferably with test credentials or redacted examples.
  • The affected commit or release.
  • Any evidence of real credential exposure.

Secret Handling

  • Do not commit real API keys, OAuth tokens, .env files, signing identities, provisioning profiles, SQLite app data, .master.key, or .coderswitchconfig exports.
  • API keys and OAuth tokens are encrypted in CoderSwitch's local SQLite database with CryptoKit SecretBox.
  • The current SecretBox root key is stored as a mode-0600 file in ~/Library/Application Support/CoderSwitch/.master.key. This protects against casual database inspection, but it is not equivalent to Keychain protection against same-user malware, broad filesystem access, or copied backups.
  • Config backup files (*.coderswitchconfig) contain decrypted API keys, OAuth tokens, proxy settings, and the proxy admin key. Keep them private and delete them when no longer needed.
  • CLIProxyAPI-compatible auth files written under ~/.cli-proxy-api contain OAuth credentials in plaintext files with local filesystem permissions. This is a local-tool interoperability tradeoff.
  • Google OAuth client secrets should not be committed. If a Google OAuth client still requires a secret for local testing, provide it with CODERSWITCH_GOOGLE_OAUTH_CLIENT_SECRET or a local CoderSwitchGoogleOAuthClientSecret Info.plist value.

Local Proxy Model

The proxy is designed for local use and binds to 127.0.0.1. Protected proxy routes require the generated admin key shown in Settings. Do not expose the proxy port to a LAN, public interface, tunnel, reverse proxy, or container network unless you have added your own access controls.

Use HTTPS custom provider endpoints whenever possible. Plain HTTP should be reserved for explicit local development endpoints such as localhost or 127.0.0.1.

Known Hardening Items

Before broad distribution, the highest-value hardening work is:

  • Move the SecretBox root key from .master.key into macOS Keychain and migrate existing users safely.
  • Add OAuth state generation and validation.
  • Restrict the OAuth callback listener and reject unexpected callback paths.
  • Remove global App Transport Security arbitrary loads and validate custom endpoints before saving them.
  • Move the proxy admin key out of plaintext SQLite storage.
  • Decide whether the app should be sandboxed for public distribution, and document any intentional exceptions.

Dependency and Release Checks

Before publishing a release:

  • Run xcodebuild -scheme CoderSwitch -configuration Debug test.
  • Run git diff --check.
  • Scan the working tree and Git history for secret-like values.
  • Rotate any credential that was ever committed to Git history before pushing the repository publicly.

There aren't any published security advisories

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Security: forbesfields/coderswitch

Security

SECURITY.md

Security Policy

CoderSwitch is a local macOS menu bar app that stores AI provider credentials, runs a loopback-only proxy, and can import or export credentials for local CLI tools. Treat the app and its local data directory as sensitive.

Supported Versions

CoderSwitch is pre-1.0 software. Security fixes are expected to land on the latest main branch unless a tagged release states otherwise.

Reporting a Vulnerability

Please do not open a public issue that contains API keys, OAuth tokens, local database files, .coderswitchconfig exports, screenshots of credentials, or other sensitive material.

If GitHub private vulnerability reporting is enabled for this repository, use that first. If it is not enabled, contact the maintainer privately through GitHub before publishing details. Include:

  • A concise description of the issue.
  • Steps to reproduce, preferably with test credentials or redacted examples.
  • The affected commit or release.
  • Any evidence of real credential exposure.

Secret Handling

  • Do not commit real API keys, OAuth tokens, .env files, signing identities, provisioning profiles, SQLite app data, .master.key, or .coderswitchconfig exports.
  • API keys and OAuth tokens are encrypted in CoderSwitch's local SQLite database with CryptoKit SecretBox.
  • The current SecretBox root key is stored as a mode-0600 file in ~/Library/Application Support/CoderSwitch/.master.key. This protects against casual database inspection, but it is not equivalent to Keychain protection against same-user malware, broad filesystem access, or copied backups.
  • Config backup files (*.coderswitchconfig) contain decrypted API keys, OAuth tokens, proxy settings, and the proxy admin key. Keep them private and delete them when no longer needed.
  • CLIProxyAPI-compatible auth files written under ~/.cli-proxy-api contain OAuth credentials in plaintext files with local filesystem permissions. This is a local-tool interoperability tradeoff.
  • Google OAuth client secrets should not be committed. If a Google OAuth client still requires a secret for local testing, provide it with CODERSWITCH_GOOGLE_OAUTH_CLIENT_SECRET or a local CoderSwitchGoogleOAuthClientSecret Info.plist value.

Local Proxy Model

The proxy is designed for local use and binds to 127.0.0.1. Protected proxy routes require the generated admin key shown in Settings. Do not expose the proxy port to a LAN, public interface, tunnel, reverse proxy, or container network unless you have added your own access controls.

Use HTTPS custom provider endpoints whenever possible. Plain HTTP should be reserved for explicit local development endpoints such as localhost or 127.0.0.1.

Known Hardening Items

Before broad distribution, the highest-value hardening work is:

  • Move the SecretBox root key from .master.key into macOS Keychain and migrate existing users safely.
  • Add OAuth state generation and validation.
  • Restrict the OAuth callback listener and reject unexpected callback paths.
  • Remove global App Transport Security arbitrary loads and validate custom endpoints before saving them.
  • Move the proxy admin key out of plaintext SQLite storage.
  • Decide whether the app should be sandboxed for public distribution, and document any intentional exceptions.

Dependency and Release Checks

Before publishing a release:

  • Run xcodebuild -scheme CoderSwitch -configuration Debug test.
  • Run git diff --check.
  • Scan the working tree and Git history for secret-like values.
  • Rotate any credential that was ever committed to Git history before pushing the repository publicly.

There aren't any published security advisories

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Security: forbesfields/coderswitch

Security

SECURITY.md

Security Policy

CoderSwitch is a local macOS menu bar app that stores AI provider credentials, runs a loopback-only proxy, and can import or export credentials for local CLI tools. Treat the app and its local data directory as sensitive.

Supported Versions

CoderSwitch is pre-1.0 software. Security fixes are expected to land on the latest main branch unless a tagged release states otherwise.

Reporting a Vulnerability

Please do not open a public issue that contains API keys, OAuth tokens, local database files, .coderswitchconfig exports, screenshots of credentials, or other sensitive material.

If GitHub private vulnerability reporting is enabled for this repository, use that first. If it is not enabled, contact the maintainer privately through GitHub before publishing details. Include:

  • A concise description of the issue.
  • Steps to reproduce, preferably with test credentials or redacted examples.
  • The affected commit or release.
  • Any evidence of real credential exposure.

Secret Handling

  • Do not commit real API keys, OAuth tokens, .env files, signing identities, provisioning profiles, SQLite app data, .master.key, or .coderswitchconfig exports.
  • API keys and OAuth tokens are encrypted in CoderSwitch's local SQLite database with CryptoKit SecretBox.
  • The current SecretBox root key is stored as a mode-0600 file in ~/Library/Application Support/CoderSwitch/.master.key. This protects against casual database inspection, but it is not equivalent to Keychain protection against same-user malware, broad filesystem access, or copied backups.
  • Config backup files (*.coderswitchconfig) contain decrypted API keys, OAuth tokens, proxy settings, and the proxy admin key. Keep them private and delete them when no longer needed.
  • CLIProxyAPI-compatible auth files written under ~/.cli-proxy-api contain OAuth credentials in plaintext files with local filesystem permissions. This is a local-tool interoperability tradeoff.
  • Google OAuth client secrets should not be committed. If a Google OAuth client still requires a secret for local testing, provide it with CODERSWITCH_GOOGLE_OAUTH_CLIENT_SECRET or a local CoderSwitchGoogleOAuthClientSecret Info.plist value.

Local Proxy Model

The proxy is designed for local use and binds to 127.0.0.1. Protected proxy routes require the generated admin key shown in Settings. Do not expose the proxy port to a LAN, public interface, tunnel, reverse proxy, or container network unless you have added your own access controls.

Use HTTPS custom provider endpoints whenever possible. Plain HTTP should be reserved for explicit local development endpoints such as localhost or 127.0.0.1.

Known Hardening Items

Before broad distribution, the highest-value hardening work is:

  • Move the SecretBox root key from .master.key into macOS Keychain and migrate existing users safely.
  • Add OAuth state generation and validation.
  • Restrict the OAuth callback listener and reject unexpected callback paths.
  • Remove global App Transport Security arbitrary loads and validate custom endpoints before saving them.
  • Move the proxy admin key out of plaintext SQLite storage.
  • Decide whether the app should be sandboxed for public distribution, and document any intentional exceptions.

Dependency and Release Checks

Before publishing a release:

  • Run xcodebuild -scheme CoderSwitch -configuration Debug test.
  • Run git diff --check.
  • Scan the working tree and Git history for secret-like values.
  • Rotate any credential that was ever committed to Git history before pushing the repository publicly.

There aren't any published security advisories

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Security: forbesfields/coderswitch

Security

SECURITY.md

Security Policy

CoderSwitch is a local macOS menu bar app that stores AI provider credentials, runs a loopback-only proxy, and can import or export credentials for local CLI tools. Treat the app and its local data directory as sensitive.

Supported Versions

CoderSwitch is pre-1.0 software. Security fixes are expected to land on the latest main branch unless a tagged release states otherwise.

Reporting a Vulnerability

Please do not open a public issue that contains API keys, OAuth tokens, local database files, .coderswitchconfig exports, screenshots of credentials, or other sensitive material.

If GitHub private vulnerability reporting is enabled for this repository, use that first. If it is not enabled, contact the maintainer privately through GitHub before publishing details. Include:

  • A concise description of the issue.
  • Steps to reproduce, preferably with test credentials or redacted examples.
  • The affected commit or release.
  • Any evidence of real credential exposure.

Secret Handling

  • Do not commit real API keys, OAuth tokens, .env files, signing identities, provisioning profiles, SQLite app data, .master.key, or .coderswitchconfig exports.
  • API keys and OAuth tokens are encrypted in CoderSwitch's local SQLite database with CryptoKit SecretBox.
  • The current SecretBox root key is stored as a mode-0600 file in ~/Library/Application Support/CoderSwitch/.master.key. This protects against casual database inspection, but it is not equivalent to Keychain protection against same-user malware, broad filesystem access, or copied backups.
  • Config backup files (*.coderswitchconfig) contain decrypted API keys, OAuth tokens, proxy settings, and the proxy admin key. Keep them private and delete them when no longer needed.
  • CLIProxyAPI-compatible auth files written under ~/.cli-proxy-api contain OAuth credentials in plaintext files with local filesystem permissions. This is a local-tool interoperability tradeoff.
  • Google OAuth client secrets should not be committed. If a Google OAuth client still requires a secret for local testing, provide it with CODERSWITCH_GOOGLE_OAUTH_CLIENT_SECRET or a local CoderSwitchGoogleOAuthClientSecret Info.plist value.

Local Proxy Model

The proxy is designed for local use and binds to 127.0.0.1. Protected proxy routes require the generated admin key shown in Settings. Do not expose the proxy port to a LAN, public interface, tunnel, reverse proxy, or container network unless you have added your own access controls.

Use HTTPS custom provider endpoints whenever possible. Plain HTTP should be reserved for explicit local development endpoints such as localhost or 127.0.0.1.

Known Hardening Items

Before broad distribution, the highest-value hardening work is:

  • Move the SecretBox root key from .master.key into macOS Keychain and migrate existing users safely.
  • Add OAuth state generation and validation.
  • Restrict the OAuth callback listener and reject unexpected callback paths.
  • Remove global App Transport Security arbitrary loads and validate custom endpoints before saving them.
  • Move the proxy admin key out of plaintext SQLite storage.
  • Decide whether the app should be sandboxed for public distribution, and document any intentional exceptions.

Dependency and Release Checks

Before publishing a release:

  • Run xcodebuild -scheme CoderSwitch -configuration Debug test.
  • Run git diff --check.
  • Scan the working tree and Git history for secret-like values.
  • Rotate any credential that was ever committed to Git history before pushing the repository publicly.

There aren't any published security advisories

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Security: forbesfields/coderswitch

Security

SECURITY.md

Security Policy

CoderSwitch is a local macOS menu bar app that stores AI provider credentials, runs a loopback-only proxy, and can import or export credentials for local CLI tools. Treat the app and its local data directory as sensitive.

Supported Versions

CoderSwitch is pre-1.0 software. Security fixes are expected to land on the latest main branch unless a tagged release states otherwise.

Reporting a Vulnerability

Please do not open a public issue that contains API keys, OAuth tokens, local database files, .coderswitchconfig exports, screenshots of credentials, or other sensitive material.

If GitHub private vulnerability reporting is enabled for this repository, use that first. If it is not enabled, contact the maintainer privately through GitHub before publishing details. Include:

  • A concise description of the issue.
  • Steps to reproduce, preferably with test credentials or redacted examples.
  • The affected commit or release.
  • Any evidence of real credential exposure.

Secret Handling

  • Do not commit real API keys, OAuth tokens, .env files, signing identities, provisioning profiles, SQLite app data, .master.key, or .coderswitchconfig exports.
  • API keys and OAuth tokens are encrypted in CoderSwitch's local SQLite database with CryptoKit SecretBox.
  • The current SecretBox root key is stored as a mode-0600 file in ~/Library/Application Support/CoderSwitch/.master.key. This protects against casual database inspection, but it is not equivalent to Keychain protection against same-user malware, broad filesystem access, or copied backups.
  • Config backup files (*.coderswitchconfig) contain decrypted API keys, OAuth tokens, proxy settings, and the proxy admin key. Keep them private and delete them when no longer needed.
  • CLIProxyAPI-compatible auth files written under ~/.cli-proxy-api contain OAuth credentials in plaintext files with local filesystem permissions. This is a local-tool interoperability tradeoff.
  • Google OAuth client secrets should not be committed. If a Google OAuth client still requires a secret for local testing, provide it with CODERSWITCH_GOOGLE_OAUTH_CLIENT_SECRET or a local CoderSwitchGoogleOAuthClientSecret Info.plist value.

Local Proxy Model

The proxy is designed for local use and binds to 127.0.0.1. Protected proxy routes require the generated admin key shown in Settings. Do not expose the proxy port to a LAN, public interface, tunnel, reverse proxy, or container network unless you have added your own access controls.

Use HTTPS custom provider endpoints whenever possible. Plain HTTP should be reserved for explicit local development endpoints such as localhost or 127.0.0.1.

Known Hardening Items

Before broad distribution, the highest-value hardening work is:

  • Move the SecretBox root key from .master.key into macOS Keychain and migrate existing users safely.
  • Add OAuth state generation and validation.
  • Restrict the OAuth callback listener and reject unexpected callback paths.
  • Remove global App Transport Security arbitrary loads and validate custom endpoints before saving them.
  • Move the proxy admin key out of plaintext SQLite storage.
  • Decide whether the app should be sandboxed for public distribution, and document any intentional exceptions.

Dependency and Release Checks

Before publishing a release:

  • Run xcodebuild -scheme CoderSwitch -configuration Debug test.
  • Run git diff --check.
  • Scan the working tree and Git history for secret-like values.
  • Rotate any credential that was ever committed to Git history before pushing the repository publicly.

There aren't any published security advisories

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Security: forbesfields/coderswitch

Security

SECURITY.md

Security Policy

CoderSwitch is a local macOS menu bar app that stores AI provider credentials, runs a loopback-only proxy, and can import or export credentials for local CLI tools. Treat the app and its local data directory as sensitive.

Supported Versions

CoderSwitch is pre-1.0 software. Security fixes are expected to land on the latest main branch unless a tagged release states otherwise.

Reporting a Vulnerability

Please do not open a public issue that contains API keys, OAuth tokens, local database files, .coderswitchconfig exports, screenshots of credentials, or other sensitive material.

If GitHub private vulnerability reporting is enabled for this repository, use that first. If it is not enabled, contact the maintainer privately through GitHub before publishing details. Include:

  • A concise description of the issue.
  • Steps to reproduce, preferably with test credentials or redacted examples.
  • The affected commit or release.
  • Any evidence of real credential exposure.

Secret Handling

  • Do not commit real API keys, OAuth tokens, .env files, signing identities, provisioning profiles, SQLite app data, .master.key, or .coderswitchconfig exports.
  • API keys and OAuth tokens are encrypted in CoderSwitch's local SQLite database with CryptoKit SecretBox.
  • The current SecretBox root key is stored as a mode-0600 file in ~/Library/Application Support/CoderSwitch/.master.key. This protects against casual database inspection, but it is not equivalent to Keychain protection against same-user malware, broad filesystem access, or copied backups.
  • Config backup files (*.coderswitchconfig) contain decrypted API keys, OAuth tokens, proxy settings, and the proxy admin key. Keep them private and delete them when no longer needed.
  • CLIProxyAPI-compatible auth files written under ~/.cli-proxy-api contain OAuth credentials in plaintext files with local filesystem permissions. This is a local-tool interoperability tradeoff.
  • Google OAuth client secrets should not be committed. If a Google OAuth client still requires a secret for local testing, provide it with CODERSWITCH_GOOGLE_OAUTH_CLIENT_SECRET or a local CoderSwitchGoogleOAuthClientSecret Info.plist value.

Local Proxy Model

The proxy is designed for local use and binds to 127.0.0.1. Protected proxy routes require the generated admin key shown in Settings. Do not expose the proxy port to a LAN, public interface, tunnel, reverse proxy, or container network unless you have added your own access controls.

Use HTTPS custom provider endpoints whenever possible. Plain HTTP should be reserved for explicit local development endpoints such as localhost or 127.0.0.1.

Known Hardening Items

Before broad distribution, the highest-value hardening work is:

  • Move the SecretBox root key from .master.key into macOS Keychain and migrate existing users safely.
  • Add OAuth state generation and validation.
  • Restrict the OAuth callback listener and reject unexpected callback paths.
  • Remove global App Transport Security arbitrary loads and validate custom endpoints before saving them.
  • Move the proxy admin key out of plaintext SQLite storage.
  • Decide whether the app should be sandboxed for public distribution, and document any intentional exceptions.

Dependency and Release Checks

Before publishing a release:

  • Run xcodebuild -scheme CoderSwitch -configuration Debug test.
  • Run git diff --check.
  • Scan the working tree and Git history for secret-like values.
  • Rotate any credential that was ever committed to Git history before pushing the repository publicly.

There aren't any published security advisories