<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: YUICHI KANEKO</title>
    <description>The latest articles on Forem by YUICHI KANEKO (@yuichi).</description>
    <link>https://forem.com/yuichi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3854598%2F6df92f63-f347-4a6c-87fc-e2899235cfb9.png</url>
      <title>Forem: YUICHI KANEKO</title>
      <link>https://forem.com/yuichi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/yuichi"/>
    <language>en</language>
    <item>
      <title>keygate: A Fast Pre-Commit Guardrail Against Secret Leaks</title>
      <dc:creator>YUICHI KANEKO</dc:creator>
      <pubDate>Fri, 24 Apr 2026 05:06:55 +0000</pubDate>
      <link>https://forem.com/yuichi/keygate-a-fast-pre-commit-guardrail-against-secret-leaks-1i7o</link>
      <guid>https://forem.com/yuichi/keygate-a-fast-pre-commit-guardrail-against-secret-leaks-1i7o</guid>
      <description>&lt;p&gt;Accidentally committing an API key, password, or private key is still one of the easiest ways to create a serious security incident. The problem gets worse as development speeds up: larger diffs, faster iterations, and more code being drafted by AI coding agents before a human reviews every line.&lt;/p&gt;

&lt;p&gt;That is why I built &lt;strong&gt;keygate&lt;/strong&gt;: a lightweight Git pre-commit hook that scans &lt;strong&gt;only staged added lines&lt;/strong&gt; and blocks likely secrets before they enter repository history.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;keygate&lt;/code&gt; is intentionally narrow in scope. It is not trying to replace full-repository scanners or cloud security platforms. Instead, it focuses on the moment that matters most in local development: &lt;strong&gt;right before &lt;code&gt;git commit&lt;/code&gt; succeeds&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/kanekyuichi/keygate" rel="noopener noreferrer"&gt;https://github.com/kanekyuichi/keygate&lt;/a&gt;&lt;br&gt;
PyPI: &lt;a href="https://pypi.org/project/keygate/" rel="noopener noreferrer"&gt;https://pypi.org/project/keygate/&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Why I built it
&lt;/h2&gt;

&lt;p&gt;Most secret leaks are not dramatic breaches. They start as small mistakes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a real API key copied into a config file during debugging&lt;/li&gt;
&lt;li&gt;a password left in a test fixture&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;.env&lt;/code&gt; value pasted into code "just for now"&lt;/li&gt;
&lt;li&gt;a generated diff that includes credentials no one noticed in review&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once committed, the value is part of Git history. Even if you delete it later, the exposure may already have happened.&lt;/p&gt;

&lt;p&gt;Existing tools are useful, but I wanted something optimized for the local developer workflow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fast enough for a Git hook&lt;/li&gt;
&lt;li&gt;offline by default&lt;/li&gt;
&lt;li&gt;focused on staged changes, not a full repo sweep&lt;/li&gt;
&lt;li&gt;practical about false positives&lt;/li&gt;
&lt;li&gt;usable both by humans and by AI agents&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  What keygate does
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;keygate&lt;/code&gt; combines multiple signals instead of relying on a single regex:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;rule-based detection for known formats such as AWS keys, OpenAI keys, GitHub tokens, Slack tokens, PEM private keys, JWTs, Stripe keys, SendGrid keys, and URLs with embedded credentials&lt;/li&gt;
&lt;li&gt;entropy checks for long random-looking strings&lt;/li&gt;
&lt;li&gt;context scoring for signals like &lt;code&gt;api_key&lt;/code&gt;, &lt;code&gt;password&lt;/code&gt;, assignment syntax, and sensitive paths such as &lt;code&gt;.env&lt;/code&gt; or config files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The final result is scored as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;block&lt;/code&gt; at 70+&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;warn&lt;/code&gt; at 40-69&lt;/li&gt;
&lt;li&gt;ignored below 40&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This keeps the hook fast while avoiding the worst tradeoff in secret scanning: either missing real secrets or becoming so noisy that developers disable it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Built for modern local workflows
&lt;/h2&gt;

&lt;p&gt;I also designed &lt;code&gt;keygate&lt;/code&gt; for the reality that AI agents now write a meaningful share of code changes.&lt;/p&gt;

&lt;p&gt;When tools like Codex or Claude Code generate larger diffs, the safest assumption is not that the agent is malicious, but that &lt;strong&gt;speed increases the chance of unnoticed sensitive values reaching a commit&lt;/strong&gt;. A local guardrail becomes more valuable in that workflow, not less.&lt;/p&gt;

&lt;p&gt;That is why &lt;code&gt;keygate&lt;/code&gt; includes structured JSON output in addition to human-readable CLI output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;keygate scan &lt;span class="nt"&gt;--format&lt;/span&gt; json
keygate scan &lt;span class="nt"&gt;--json&lt;/span&gt;
keygate scan &lt;span class="nt"&gt;--profile&lt;/span&gt; agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That makes it easier for scripts or coding agents to re-run the scan, parse findings, and suggest fixes mechanically.&lt;/p&gt;

&lt;h2&gt;
  
  
  Handling false positives without breaking flow
&lt;/h2&gt;

&lt;p&gt;A secret scanner is only useful if developers can live with it every day. &lt;code&gt;keygate&lt;/code&gt; includes three escape hatches for expected findings:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Inline ignore comments with a required reason&lt;/li&gt;
&lt;li&gt;Allowlist rules in &lt;code&gt;keygate.toml&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A baseline file for existing findings you want to suppress safely&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The baseline stores fingerprints rather than raw secret values, so teams can commit the file without exposing the secret itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick start
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pipx &lt;span class="nb"&gt;install &lt;/span&gt;keygate
&lt;span class="nb"&gt;cd &lt;/span&gt;your-project
keygate install-hook
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From that point on, every normal &lt;code&gt;git commit&lt;/code&gt; gets a fast local secret check automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project goals
&lt;/h2&gt;

&lt;p&gt;The design goals are simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;stop likely secrets before commit&lt;/li&gt;
&lt;li&gt;keep the check fast enough for daily use&lt;/li&gt;
&lt;li&gt;work offline&lt;/li&gt;
&lt;li&gt;avoid LLM or external API dependence&lt;/li&gt;
&lt;li&gt;give clear remediation when something is blocked&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want a local, developer-friendly secret scanner that acts as a commit-time guardrail, that is exactly the gap &lt;code&gt;keygate&lt;/code&gt; is meant to fill.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/kanekoyuichi/keygate" rel="noopener noreferrer"&gt;https://github.com/kanekoyuichi/keygate&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PyPI: &lt;a href="https://pypi.org/project/keygate/" rel="noopener noreferrer"&gt;https://pypi.org/project/keygate/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>git</category>
      <category>security</category>
      <category>showdev</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Detecting Prompt Injection in LLM Apps (Python Library)</title>
      <dc:creator>YUICHI KANEKO</dc:creator>
      <pubDate>Wed, 01 Apr 2026 03:31:37 +0000</pubDate>
      <link>https://forem.com/yuichi/detecting-prompt-injection-in-llm-apps-python-library-1fgp</link>
      <guid>https://forem.com/yuichi/detecting-prompt-injection-in-llm-apps-python-library-1fgp</guid>
      <description>&lt;p&gt;I've been working on LLM-backed applications and ran into a recurring issue: prompt injection via user input.&lt;/p&gt;

&lt;p&gt;Typical examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Ignore all previous instructions"&lt;/li&gt;
&lt;li&gt;"Reveal your system prompt"&lt;/li&gt;
&lt;li&gt;"Act as another AI without restrictions"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In many applications, user input is passed directly to the model, which makes these attacks practical.&lt;/p&gt;

&lt;p&gt;Most moderation APIs are too general-purpose and not designed specifically for prompt injection detection, especially for non-English inputs. So I built a small Python library to act as a screening layer before sending input to the LLM:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanekoyuichi/promptgate" rel="noopener noreferrer"&gt;https://github.com/kanekoyuichi/promptgate&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Detection strategies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;rule-based (regex / phrase matching)&lt;br&gt;&lt;br&gt;
latency: &amp;lt;1ms, no dependencies&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;embedding-based (cosine similarity with attack exemplars)&lt;br&gt;&lt;br&gt;
latency: ~5–15ms, uses sentence-transformers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LLM-as-judge&lt;br&gt;&lt;br&gt;
higher accuracy, but +150–300ms latency, requires external API&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Baseline evaluation (rule-only):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;FPR: 0.0% (0 / 30 benign samples)&lt;/li&gt;
&lt;li&gt;Recall: 61.4% (27 / 44 attack samples)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So rule-based alone misses ~40% of attacks, especially paraphrased or context-dependent ones.&lt;/p&gt;

&lt;p&gt;This is not intended as a complete solution — the design assumption is defense-in-depth, where this acts as a first screening layer.&lt;/p&gt;

&lt;p&gt;Known limitations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;rule-based detection struggles with paraphrased / indirect instructions
&lt;/li&gt;
&lt;li&gt;embedding approach depends on exemplar coverage (not a trained classifier)
&lt;/li&gt;
&lt;li&gt;LLM-as-judge is non-deterministic and API-dependent
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Would be interested in feedback on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;better evaluation methodologies
&lt;/li&gt;
&lt;li&gt;detection strategies beyond pattern / similarity / LLM judging
&lt;/li&gt;
&lt;li&gt;how others are handling prompt injection at the application layer
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>python</category>
      <category>security</category>
    </item>
  </channel>
</rss>
