feat: one-stop safe deployment and operation skill

- add references/safe-operation.md: credentials, client settings, secrets,
  blast radius, monitoring, incident response, update discipline
- SKILL.md, READMEs, AGENTS.md, llms.txt now present four parts: deploy,
  egress, operate, respond — gate remains the enforcement core
- version 1.3.0, installer pin updated
This commit is contained in:
yinyues2 committed 2026-10-27 01:52:28 +08:00
1 parent 89e81d1678
commit 6af4f23d89
9 files changed
+216 -30

No files matched your search

+10 -6
View File
@@ -6,16 +6,20 @@ file, then load [`skills/claude-egress-guard/SKILL.md`](skills/claude-egress-gua
## What this repository is
A deployment skill plus an installer for a fail-closed egress gate in front of
Claude Code. It is not a proxy and not a VPN: it makes the `claude` binary refuse
to start unless traffic leaves through one verified exit.
A one-stop deployment and operation skill for Claude Code on Linux: host
preflight, fail-closed egress gate, safe-operation baseline and incident drills.
It is not a proxy and not a VPN: it makes the `claude` binary refuse to start
unless traffic leaves through one verified exit, then covers what keeps that true
over time.
## Read order
1. `skills/claude-egress-guard/SKILL.md` — the contract (facts, tiers, guardrails).
2. `skills/claude-egress-guard/references/agent-playbook.md` — commands and decision points.
3. `skills/claude-egress-guard/references/troubleshooting.md` — when a check fails.
4. `SECURITY.md` — threat model, known limitations, what is out of scope.
2. `skills/claude-egress-guard/references/zero-to-deployed.md` — phase-by-phase for a fresh host.
3. `skills/claude-egress-guard/references/safe-operation.md` — credentials, settings, secrets, monitoring, incident response.
4. `skills/claude-egress-guard/references/agent-playbook.md` — commands and decision points.
5. `skills/claude-egress-guard/references/troubleshooting.md` — when a check fails.
6. `SECURITY.md` — threat model, known limitations, what is out of scope.
## Operating contract
+17
View File
@@ -3,6 +3,23 @@
All notable changes to this project are documented here. The format follows
Keep a Changelog; versions use semantic versioning.
## [1.3.0] - 2026-10-27
### Changed
- Repositioned from "an egress gate" to a one-stop Claude Code deployment and
operation skill. The binary gate stays the enforcement core; the skill now names
four parts explicitly — deploy, egress, operate, respond — in `SKILL.md`, both
READMEs, `AGENTS.md` and `llms.txt`.
### Added
- `references/safe-operation.md`: credential handling, client settings (no proxy
in `settings.json`, keep permission prompts, review hooks and MCP servers,
one installation), secrets in the working tree, working-directory blast radius,
monitoring, incident response for exit changes / verification requests / leaked
credentials / suspected bypass, and update discipline.
## [1.2.0] - 2026-10-27
### Added
+16 -7
View File
@@ -2,9 +2,8 @@
[![ci](https://github.com/yinyues2/claude-egress-guard/actions/workflows/ci.yml/badge.svg)](https://github.com/yinyues2/claude-egress-guard/actions/workflows/ci.yml)
**A deployment skill for agents, plus a one-command installer for humans, that
pins Claude Code on a Linux host to one egress and refuses to start when that
path is unavailable.**
**A one-stop skill and installer for running Claude Code safely on a Linux host:
from a bare machine to a gated client, then keeping it that way.**
Claude Code on a VPS is easy to install and easy to leak. A shell alias or a
`claude()` function only covers interactive shells: Python, `sh -c`, cron,
@@ -12,10 +11,20 @@ systemd units and anything calling `/usr/bin/claude` walk straight past it, and
proxy that dies mid-session silently turns into a direct connection from the
datacenter IP.
This project closes that gap at the binary level: the `claude` command itself
becomes a gate that verifies the proxy's real exit address, injects the proxy
environment, and optionally jails the whole process tree with a kernel IP allow
list. Anything unexpected refuses to start. There is no fallback.
So the project is organized in four parts, with one enforcement core:
| Part | What it covers | Entry point |
| --- | --- | --- |
| **Deploy** | eligibility, host baseline, proxy proven stable, client installed but not launched, first login through the gate | `preflight`, [`zero-to-deployed.md`](skills/claude-egress-guard/references/zero-to-deployed.md) |
| **Egress** | one verified exit, proxy injection, kernel jail for the whole process tree, self-heal after updates, no fallback | `install`, `verify --deep`, `drill`, `set-exit` |
| **Operate** | credentials, client settings, secrets, blast radius, backups, monitoring | [`safe-operation.md`](skills/claude-egress-guard/references/safe-operation.md) |
| **Respond** | exit changed, verification request, leaked credential, suspected bypass | [`safe-operation.md`](skills/claude-egress-guard/references/safe-operation.md) §6 |
The enforcement core is still the binary gate: `claude` itself verifies the
proxy's real exit address, injects the proxy environment, and optionally jails the
whole process tree with a kernel IP allow list. Anything unexpected refuses to
start; there is no fallback. The other three parts exist so that the gate is
installed in the right order and stays meaningful after the first week.
---
+15 -6
View File
@@ -1,18 +1,27 @@
# claude-egress-guard(中文说明)
**给 agent 用的部署 skill,也是给人用的一键安装脚本:把 Linux 上的 Claude Code
钉死在一个出口上,出口不对就拒绝启动。**
[![ci](https://github.com/yinyues2/claude-egress-guard/actions/workflows/ci.yml/badge.svg)](https://github.com/yinyues2/claude-egress-guard/actions/workflows/ci.yml)
**一站式 skill + 一键安装:在 Linux 上安全地部署和运行 Claude Code——从裸机到可用、
可审计的客户端,以及出问题时知道怎么处置。**
在 VPS 上跑 Claude Code,最容易出问题的不是安装,而是**出口泄漏**:写在
`/etc/profile.d` 里的 `claude()` 函数只覆盖交互式 shell,Python、`sh -c`、
cron、systemd 和任何直接调用 `/usr/bin/claude` 的路径都会绕过去;代理中途挂掉时,
客户端还会悄悄从机房 IP 直连出去。
这个项目在**二进制层**补上这个洞:`claude` 命令本身变成闸门,启动前核验代理的真实
出口地址,注入代理变量,并可选地把整个进程树关进内核级 IP 白名单。任何异常都拒绝
启动,没有「继续执行」的分支。
所以项目分成四块,只有一个是强制核心:
| 部分 | 覆盖什么 | 入口 |
| --- | --- | --- |
| **部署** | 资格判断、主机基线、代理先稳定、装客户端但不启动、首次登录走闸门 | `preflight`、[`zero-to-deployed.md`](skills/claude-egress-guard/references/zero-to-deployed.md) |
| **出口** | 固定出口、注入代理、内核白名单、更新自愈、失败不回落 | `install`、`verify --deep`、`drill`、`set-exit` |
| **运行** | 凭据、客户端设置、密钥卫生、影响范围、备份、监控 | [`safe-operation.md`](skills/claude-egress-guard/references/safe-operation.md) |
| **处置** | 出口变化、被要求验证、凭据泄漏、怀疑绕过 | [`safe-operation.md`](skills/claude-egress-guard/references/safe-operation.md) §6 |
强制核心仍然是二进制闸门:`claude` 命令本身核验代理的真实出口地址、注入代理变量,
可选地把整个进程树关进内核级 IP 白名单。任何异常都拒绝启动,没有回落。另外三块存在
的意义,是让这道闸门**按正确顺序装上**,并且在第一周之后仍然有意义。
---
+1 -1
View File
@@ -11,7 +11,7 @@
set -u
REPO="yinyues2/claude-egress-guard"
PINNED_REF="v1.2.0"
PINNED_REF="v1.3.0"
SELF_DIR=$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd -P)
WORK=""
+4 -2
View File
@@ -1,11 +1,13 @@
# claude-egress-guard
> A deployment skill for agents, plus a one-command installer, that pins Claude
> Code on a Linux host to one verified egress and refuses to start otherwise.
> A one-stop skill and installer for running Claude Code safely on a Linux host:
> host preflight, fail-closed egress gate, safe-operation baseline, incident drills.
## Docs
- [Skill](https://github.com/yinyues2/claude-egress-guard/blob/main/skills/claude-egress-guard/SKILL.md): deployment contract — four facts, three authorization tiers, install/verify/drill, guardrails
- [Zero to deployed](https://github.com/yinyues2/claude-egress-guard/blob/main/skills/claude-egress-guard/references/zero-to-deployed.md): nine phases from eligibility to maintenance
- [Safe operation](https://github.com/yinyues2/claude-egress-guard/blob/main/skills/claude-egress-guard/references/safe-operation.md): credentials, client settings, secrets, blast radius, monitoring, incident response
- [Agent playbook](https://github.com/yinyues2/claude-egress-guard/blob/main/skills/claude-egress-guard/references/agent-playbook.md): step-by-step commands, allow-list rules, evidence record
- [Troubleshooting](https://github.com/yinyues2/claude-egress-guard/blob/main/skills/claude-egress-guard/references/troubleshooting.md): symptom → cause → fix
- [AGENTS.md](https://github.com/yinyues2/claude-egress-guard/blob/main/AGENTS.md): machine entry point
+23 -7
View File
@@ -1,7 +1,7 @@
---
name: claude-egress-guard
description: "Use when pinning Claude Code to one egress on Linux — installs a fail-closed gate, kernel net jail, and drills it."
version: 1.2.0
description: "Use when deploying or auditing Claude Code on Linux — one-stop safe setup: preflight, egress gate, operation baseline, incident drills."
version: 1.3.0
author: claude-egress-guard contributors
license: Apache-2.0
platforms: [linux]
@@ -11,12 +11,24 @@ metadata:
category: devops
---
# Claude Egress Guard
# Claude Code: safe deployment and operation
Install a fail-closed egress gate in front of Claude Code on a Linux host: every
invocation must pass an exit-address check, the client and its children get proxy
variables, and (by default) the whole process tree is jailed with a kernel-level
IP allow list. Anything unexpected refuses to start instead of falling back.
A one-stop skill for running Claude Code on a Linux host you control: bring a bare
machine to a working, gated client, keep it inside one verified egress, and know
what to do when something goes wrong.
Four parts, in the order they matter:
| Part | What it covers | Where |
| --- | --- | --- |
| **Deploy** | eligibility, host baseline, proxy proven stable, client installed but not launched, first login through the gate | `references/zero-to-deployed.md`, `preflight` |
| **Egress** | one verified exit, proxy injection, kernel jail for the whole process tree, self-heal after updates, no fallback | `install` / `verify --deep` / `drill` / `set-exit` |
| **Operate** | credentials, client settings, secrets, working-directory blast radius, backups, monitoring | `references/safe-operation.md` §1-5 |
| **Respond** | exit change, verification request, leaked credential, suspected bypass | `references/safe-operation.md` §6 |
The enforcement core is still one binary: `claude` becomes a gate that refuses to
start when the exit is not the one you configured. The rest of the skill exists so
that the gate is installed in the right order, and stays meaningful afterwards.
## When to use
@@ -28,6 +40,9 @@ IP allow list. Anything unexpected refuses to start instead of falling back.
already polluted.
- The operator asks to "lock down", "pin", or "verify" the Claude egress, or to
prove it still works after a package update.
- The operator asks whether an existing Claude deployment is *safe* in general:
credentials, client settings, secrets, backups, monitoring, and what to do in
an incident. Audit against `references/safe-operation.md`.
- The host is fresh and the operator has never had an account: start with
`references/zero-to-deployed.md` instead of improvising an order of operations.
@@ -190,4 +205,5 @@ Left: <what the operator still has to do, if anything>
- `references/agent-playbook.md` — full command sequence, allow-list rules, evidence record
- `references/zero-to-deployed.md` — phase-by-phase runbook for a fresh host with no account
- `references/safe-operation.md` — credentials, client settings, secrets, blast radius, monitoring, incident response
- `references/troubleshooting.md` — symptom → cause → fix table
@@ -0,0 +1,129 @@
# Safe operation baseline
The gate decides where traffic leaves. This file decides everything else that
makes a Claude Code deployment safe to keep running: credentials, client
settings, secrets, backups, monitoring and what to do when something looks wrong.
It applies after `references/zero-to-deployed.md` has taken you to a working,
gated host.
## 1. Credentials
- `~/.claude/.credentials.json` is a **session**, not a config file. Mode 600,
owned by the account that runs Claude. Never copy it to another machine, never
put it in a backup that leaves the host.
- Re-login is the rotation mechanism. If the file may have leaked: `claude auth
logout`, sign out the other sessions from the provider's account page, log in
again, then check usage for anything you do not recognise.
- Login codes are single use and short lived. Do not paste them into a chat, a
ticket, a log or a shell history. If an orchestrator passes one through stdin,
it must not echo it.
- Never store a provider token in `CLAUDE.md`, `settings.json`, a git remote URL
or a shell profile.
## 2. Client settings
The gate owns egress. The client must not have a second opinion:
- **No proxy in `~/.claude/settings.json`.** A value there can win over the
environment the gate exports, which is the quietest way to send traffic around
the gate.
- **Keep permission prompts on** unless the directory is a throwaway sandbox.
A blanket "allow everything" setting turns every prompt injection into a shell.
- **Review hooks and MCP servers before enabling them.** Both execute code with
your privileges; a hook added for convenience is a startup script with your
keys in scope.
- **One installation.** `npx`, a second global install, or a wrapper that calls
the real binary are ungated paths. Remove them or accept that the gate does not
cover them.
## 3. Secrets in the working tree
- Keep API keys in a `.env` with mode 600, or in a secret manager. Not in
`CLAUDE.md`, not in committed examples, not in prompts.
- Add `.env`, `*.pem`, `*.key` and `credentials*` to `.gitignore` before the first
commit, not after the first leak.
- `~/.claude/` and the project's `.claude/` should not be world-readable:
`chmod 700 ~/.claude`, `chmod -R go-rwx .claude` where it exists.
- When you paste logs into an issue, strip addresses, tokens, account identifiers
and full config files. Documentation ranges (`203.0.113.0/24`) exist for this.
## 4. Working directory and blast radius
- Run Claude in a dedicated directory, not `/` and not your home root. A
mistaken `rm` or a wide refactor should hit a project, not a system.
- Keep the project under git. Review diffs before accepting bulk edits; a clean
`git diff` is the cheapest safety net there is.
- Do not run unattended, long-lived agents against production credentials. If you
must, give them a scoped token and a directory they cannot escape.
- Snapshot before large changes (`git stash`, a tarball, a provider snapshot).
## 5. Monitoring
- `LOG_REFUSALS=1` turns "did it ever refuse?" into `journalctl -t
claude-egress-guard`. Check it weekly; a burst of refusals means the proxy is
unstable, not that the gate is broken.
- After every package update: `claude-egress-guard verify --deep`. The self-heal
is best effort, verification is proof.
- Keep a one-line change log for policy edits (who changed `EXPECTED_IP`,
`ALLOW_IPS` or `STRICT_NET`, and why). Six months later this is the only thing
that explains an incident.
- Record the version you are on. `claude --version`, `claude-egress-guard status`.
## 6. Incident response
Match the symptom, then act in order. Stop the bleeding before you investigate.
### Exit changed or a leak is suspected
1. Stop new sessions; let running ones finish or kill them deliberately.
2. Confirm the current exit: `claude-egress-guard status`, then a trace through
the proxy.
3. If the proxy moved, `set-exit --ip NEW --country CC`; if it is dead, leave the
gate refusing. A refusing gate is working correctly.
4. Read `journalctl -t claude-egress-guard` for when refusals started.
5. Only then review IP history and decide whether the provider needs to hear
from you.
### The provider asks for verification, or the session is signed out
1. Do not retry from a different address. Address hopping during a review is the
worst possible signal.
2. Stop automation that would keep opening sessions.
3. Follow the provider's instructions truthfully, or stop and reassess
eligibility. Never supply documents or numbers that are not yours.
4. Preserve logs and the deployment record; do not delete evidence.
### A credential may have leaked
1. `claude auth logout` on the host.
2. Revoke sessions from the provider's account page.
3. Re-login through the gate, then `verify --deep`.
4. Check usage and recent activity for anything you cannot explain.
5. Fix the path it leaked through (git history, a pasted log, a world-readable
file) before moving on.
### A bypass is suspected
1. `claude-egress-guard status` — is the gate still installed at both paths?
2. `npx`, a second install, a wrapper, a container: list every way `claude` can
start on that host.
3. For a running process, `cat /proc/<pid>/cgroup` should show a `run-r...scope`
when `STRICT_NET=1`. If it does not, that process did not come through the
gate.
4. Fix the entry point, then drill again.
## 7. Update discipline
| Change | Follow-up |
| --- | --- |
| Claude Code update | `verify --deep`, one real prompt |
| OS upgrade | re-check systemd version, IPv6 setting, DNS resolvers, then `verify --deep` |
| Proxy change | `set-exit`, then `verify` |
| Policy change | record it, then `verify --deep` |
| Host rebuild | follow `zero-to-deployed.md` from phase 1; do not copy credentials |
## 8. What stays out of scope
Account registration, payment, identity verification, and anything that would
misrepresent who you are or where you are. Those are the operator's, permanently.
@@ -14,7 +14,7 @@
# Everything it replaces is copied to the backup directory first.
set -u
VERSION="1.2.0"
VERSION="1.3.0"
MARKER="claude-egress-guard"
CONF_REL="/etc/claude-egress-guard.conf"