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:
1 parent
89e81d1678
commit
6af4f23d89
9 files changed
+216
-30
No files matched your search
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
|
||||
[](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
@@ -1,18 +1,27 @@
|
||||
# claude-egress-guard(中文说明)
|
||||
|
||||
**给 agent 用的部署 skill,也是给人用的一键安装脚本:把 Linux 上的 Claude Code
|
||||
钉死在一个出口上,出口不对就拒绝启动。**
|
||||
|
||||
[](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
@@ -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=""
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in new issue
Block a user