Build1 publisher3 min readPublished
A dependency-free Node gate classifies a context bundle against eleven regexes before it ships
The policy lives in a JSON file a reviewer can read without reading the code, and the gate resolves overlapping matches by severity, so a JWT found inside a log line is denied instead of merely warned on.
The Engineer · Build desk

What happened
- A dev.to article builds an egress gate for LLM context bundles plus a hash-chained ledger meant to be replayed months later, written in plain Node with no dependencies.
- The gate walks the bundle once, classifies every text file against a JSON policy, and exits with a distinct status a shell pipeline can branch on.
- The policy defines four classes: live credentials and tenant identifiers are denied, personal identifiers are redacted, and unresolved security notes only produce a warning.
- Because a JWT inside a log line can match more than one class, overlap resolves by severity, with deny ranked above redact and redact above warn.
- Exit 0 permits the send, exit 2 reports that the tool was called wrong, and exit 3 says a file in the bundle belongs on the machine and nowhere else.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- cost Every credential format a vendor invents next is a policy edit before the gate can see it, and that maintenance lands on whoever inherits the JSON file.
- decision Keeping the class list in data lets a security reviewer approve or reject the policy without reading the gate, so policy sign-off no longer waits on a code review.
- exposure Anything the pattern list misses does not merely go unblocked; it leaves with exit 0, and a later replay of the ledger will show an approved send that was never actually inspected.
- capability A sealed per-send record means you can answer from a local file which classes of bytes crossed the boundary in September, instead of from whatever a provider's terms page says now.
Eleven regular expressions carry the whole control [20]. Four of them match live credentials: an AKIA prefix followed by exactly sixteen uppercase-or-digit characters, a PEM private key header, `ghp_` followed by exactly thirty-six characters, and a three-segment JWT whose first segment starts with `eyJ` [5]. Those lengths are exact. A token in a different format, or one with a segment under eight characters, does not match, and the gate passes the file [25].
The tenant class is where I would expect the first real miss. It denies a `.internal` hostname, a `10.x.x.x` address, and an ARN carrying a twelve-digit account field [6]. 172.16/12 and 192.168/16 are private ranges too, and neither appears in the list [22]. The article's own argument for the class treats a twelve-digit account ID as part of a reconnaissance report you mailed out by hand [15]; the pattern only fires when that ID sits inside an `arn:aws:` string [23].
Redaction is the action that keeps the workflow usable for anyone touching support tickets [7]. The card pattern matches any sixteen digits in four groups with optional separators, and there is no checksum test [7], so a sixteen-digit trace ID is replaced with a tag of the form `[personal:9f3c21ab77e041d8]` [9][24].
Each class maps to exactly one action, which the article gives as the reason the gate never has to improvise at runtime [19]. That constraint is why per-file exceptions are meant to be written as explicit exclusions instead of loosening a global pattern [12]. A loosened pattern changes the verdict for every file in the bundle.
For this to transfer, your material has to be text, because the walk classifies text files [13]. The credentials you carry have to use the formats in the list, which the article concedes is the weak point: the patterns are "as good as the list you maintain and no better" [4]. And somebody owns the JSON file after the person who wrote it moves on.
Timing is the argument for drawing the boundary locally. Terms, subprocessors and retention windows move on their own schedule, so the page you read in March is not evidence about what happened in September [2]. A hash-chained ledger you can replay months later is the part that answers which classes crossed and when [1]. The code excerpt in the published article stops in the middle of its import list, so the chaining routine itself is not in the text.
Read the disclosure at the top: the article was prepared as part of MonkeyCode's product outreach [17], and it names MonkeyCode's free model access and free server option as egress paths to classify before using them in a real workflow [16]. The failure it describes is ordinary. When the only cost is a key and a terminal, most of us paste an entire directory on the first afternoon, `.env` and `terraform.tfstate` included [18].
What to watch
- Whether the card pattern gains a Luhn check, which would stop sixteen-digit request IDs being redacted as personal data.
- Whether MonkeyCode's free server option ships egress logging of its own; that changes what the gate has to catch locally.
- Any vendor rotating to a new token prefix leaves the live class blind until someone edits the policy file.