Repository navigation
egress shapes and address vetting, chat webhook URLs as credentials, a scratch window - #9
Merged
Merged
Conversation
pip-audit turned the probe's gate red on a new advisory against the SDK's transitive mcp pin (fix versions 1.30.0 / 2.2.0). Upgraded in the probe's venv, relocked with scripts/relock.sh (only this pin and mcp-types moved), audit clean. Unrelated to the rest of this branch and kept apart so it cherry-picks alone.
The output guard names the kind (chat webhook url) for Feishu/Lark, Slack, DingTalk, WeCom and Discord incoming hooks, and the redactor masks the token half while keeping the host, so a case file still says which chat was posted to. A second deployment running copies of these files read a function's environment on 2026-10-12 and such a URL went into its transcript, two logs and the model call; nothing here named the shape, and this family posts its own cards through exactly such URLs. Fixtures are visibly fake on purpose: the estate guard refuses anything shaped like a real token.
…heir own
HOOKPROBE_SCRATCH_DAYS (default 7): the agent subprocess gets TMPDIR={workdir}/scratch, and that directory plus $HOME/.cache/claude-cli-nodejs are swept daily on their own window, whatever HOOKPROBE_RETENTION_DAYS says. A scratch folder is old only when nothing under it was written inside the window, so a job still writing into its own folder is left alone.
Measured on two probe volumes: the CLI's MCP transport logs had grown since 2026-09-04 (113 and 364 files) carrying whatever tools returned, with retention.prune never naming them and the case-file window defaulting to keep-forever because case files are recall. A second deployment found a day-old scratch holding other teams' configs. Passed through every compose that passes the retention knob; reference regenerated.
…ere its kind says EGRESS_ALLOW takes @aws-api (<service>[.<region>].amazonaws.com, any service, any region) and @aws-s3 (a bucket in every spelling), and the work compose's default uses them instead of .amazonaws.com, which also admitted every hostname anyone can get under that suffix: an instance's public name, a load balancer, an API Gateway stage, somebody else's EKS cluster. A cluster endpoint the planner is given goes on the operator's list by name; the shapes do not match it on purpose. An unknown @ rule stops the container at start. A listed name is vetted at the address: the proxy resolves it, refuses any answer that is loopback, link-local, private, reserved or the host machine's mapped address (IPv4-in-IPv6 included), and connects to the address it vetted, never a second lookup. Compose peers go in EGRESS_INTERNAL and must resolve inside the compose network; both deploy composes name theirs. The name is checked before any lookup. A name that does not resolve is a 502, not a 403. Decision note beside it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three gaps a second deployment running copies of these files found in use over the past week, each one measured here before it was closed. The same-file fixes were kept small; the decision note is
.agents/notes/implemented/2026-10-19-the-allowlist-names-shapes-and-a-name-must-resolve-where-its-kind-says.md.1. The egress allowlist names shapes, and a listed name is vetted at the address (
deploy/sidecars/proxy.py).amazonaws.comadmitted every hostname anyone can obtain under that suffix: an EC2 instance's public name, a load balancer, an API Gateway stage, somebody else's EKS cluster — attacker-controlled destinations inside the allowlist.EGRESS_ALLOWnow takes@aws-api(<service>[.<region>].amazonaws.com) and@aws-s3(a bucket in every spelling); the work compose default uses them, and a cluster endpoint the planner is given goes on the operator's list by name (the shapes do not match it, on purpose). An unknown@rule stops the container at start.EGRESS_INTERNALand must resolve inside the compose network; both deploy composes name theirs. The name is checked before any lookup; a name that does not resolve is a 502, not a 403 (the agent is told 403 means do not retry).2. A chat bot's incoming-webhook URL is a credential (
hookprobe/hookprobe/gate.py,redact.py)The output guard names the kind
chat webhook urlfor Feishu/Lark, Slack, DingTalk, WeCom and Discord hooks, and the redactor masks the token half while keeping the host. The sibling's action job read a function's environment on 2026-10-12 and such a URL went into its transcript, two logs and the model call; nothing here named the shape, and this family posts its own cards through exactly such URLs.3. Scratch and the CLI's own logs get a retention window of their own (
HOOKPROBE_SCRATCH_DAYS, default 7)Measured on two probe volumes: the CLI's MCP transport logs under
home/.cache/claude-cli-nodejshad grown since 2026-09-04 (113 and 364 files) carrying whatever tools returned, withretention.prunenever naming them andHOOKPROBE_RETENTION_DAYSdefaulting to keep-forever because case files are recall. The agent subprocess now getsTMPDIR={workdir}/scratch, and that directory plus the CLI cache are swept daily on their own window: a scratch folder is old only when nothing under it was written inside the window. Passed through every compose that passes the retention knob; reference regenerated.Operator side, done here: the work stack's
.envline forEGRESS_ALLOWnow carries the two shapes and its three cluster endpoints by name instead of.amazonaws.com(backup beside it). Nothing is running; it applies at the next recreate.Gate: STACK GATE GREEN locally; CI read back below before merging.
Also on this branch, first commit, unrelated:
pip-auditwent red on a new advisory against the SDK's transitivemcppin (CVE-2026-59951); upgraded to 2.3.0 in the venv and relocked. Kept as its own commit so it cherry-picks alone. Dependabot's open #6–#8 still need the same relock treatment for their bumps.