@clipboard-health/clearance 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -3
- package/bin/ensure.js +5 -1
- package/bin/run.js +5 -1
- package/bin/runCli.js +42 -0
- package/package.json +10 -1
- package/src/index.d.ts +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# @clipboard-health/clearance
|
|
2
2
|
|
|
3
|
-
HTTP/HTTPS
|
|
3
|
+
A local HTTP/HTTPS forward proxy that gates network egress against a
|
|
4
|
+
hostname allowlist. Built for deny-by-default sandboxes — coding agents,
|
|
5
|
+
CI workers, isolated build steps — where you want one choke point the
|
|
6
|
+
sandbox can permit, with every other route to the network closed.
|
|
4
7
|
|
|
5
8
|
The proxy ships with **zero compiled-in opinions** about which hosts to allow.
|
|
6
9
|
Bring your own list — either inline via env or by pointing at one or more
|
|
@@ -100,8 +103,9 @@ kill "$(cat "${XDG_CACHE_HOME:-$HOME/.cache}/clearance/clearance.pid")"
|
|
|
100
103
|
|
|
101
104
|
## Safehouse integration (macOS)
|
|
102
105
|
|
|
103
|
-
Safehouse uses macOS sandbox profiles, so
|
|
104
|
-
only. Safehouse allows network access by
|
|
106
|
+
[Safehouse](https://agent-safehouse.dev/) uses macOS sandbox profiles, so
|
|
107
|
+
this section is for macOS hosts only. Safehouse allows network access by
|
|
108
|
+
default for agent compatibility.
|
|
105
109
|
To force a wrapped agent through this proxy, run the proxy outside
|
|
106
110
|
Safehouse, then append a Safehouse profile that denies direct remote
|
|
107
111
|
egress while leaving `localhost` open for `http://127.0.0.1:19999`.
|
|
@@ -217,3 +221,14 @@ safehouse --env="$HOME/.config/agent-safehouse/clearance.env" \
|
|
|
217
221
|
--append-profile="$HOME/.config/agent-safehouse/clearance-only.sb" \
|
|
218
222
|
-- curl -I https://example.com
|
|
219
223
|
```
|
|
224
|
+
|
|
225
|
+
## Hacking on clearance
|
|
226
|
+
|
|
227
|
+
For developers working on the package itself, the source lives in [`ClipboardHealth/core-utils`](https://github.com/ClipboardHealth/core-utils). After `npm install` in the repo, the bin scripts dispatch through a `runCli` helper that detects no compiled JS and re-execs node with `--conditions @clipboard-health/source`, so the proxy runs straight from TypeScript source — no build step:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
cd ~/dev/c/core-utils
|
|
231
|
+
CLEARANCE_ALLOW_HOSTS=api.example.com node ./packages/clearance/bin/run.js
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Requires Node ≥ 24.3 (native `.ts` type stripping enabled by default).
|
package/bin/ensure.js
CHANGED
package/bin/run.js
CHANGED
package/bin/runCli.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { constants as osConstants } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { pathToFileURL } from "node:url";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Load a side-effecting entrypoint by basename. In published/built mode, dynamically
|
|
9
|
+
* imports the compiled `${name}.js` in-process. In source/dev mode (no compiled output
|
|
10
|
+
* present), spawns a child node that loads the `.ts` source with
|
|
11
|
+
* `--conditions @clipboard-health/source` so cross-package bare imports of
|
|
12
|
+
* `@clipboard-health/*` workspace deps also resolve to source.
|
|
13
|
+
*
|
|
14
|
+
* @param {string} packageRoot
|
|
15
|
+
* @param {string} name
|
|
16
|
+
*/
|
|
17
|
+
export async function runCli(packageRoot, name) {
|
|
18
|
+
const compiledPath = join(packageRoot, "src", `${name}.js`);
|
|
19
|
+
if (existsSync(compiledPath)) {
|
|
20
|
+
await import(pathToFileURL(compiledPath).href);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const sourcePath = join(packageRoot, "src", `${name}.ts`);
|
|
25
|
+
const result = spawnSync(
|
|
26
|
+
process.execPath,
|
|
27
|
+
["--conditions", "@clipboard-health/source", sourcePath, ...process.argv.slice(2)],
|
|
28
|
+
{ stdio: "inherit" },
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
if (result.error !== undefined) {
|
|
32
|
+
throw result.error;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (result.signal !== null) {
|
|
36
|
+
const signalNumber = osConstants.signals[result.signal];
|
|
37
|
+
process.exitCode = signalNumber === undefined ? 1 : 128 + signalNumber;
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
process.exitCode = result.status ?? 1;
|
|
42
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clipboard-health/clearance",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Localhost HTTP/HTTPS egress proxy with hostname allow-listing, plus a macOS Safehouse integration for sandboxed agent processes.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
@@ -24,6 +24,15 @@
|
|
|
24
24
|
"type": "module",
|
|
25
25
|
"main": "./src/index.js",
|
|
26
26
|
"typings": "./src/index.d.ts",
|
|
27
|
+
"exports": {
|
|
28
|
+
"./package.json": "./package.json",
|
|
29
|
+
".": {
|
|
30
|
+
"@clipboard-health/source": "./src/index.ts",
|
|
31
|
+
"types": "./src/index.d.ts",
|
|
32
|
+
"import": "./src/index.js",
|
|
33
|
+
"default": "./src/index.js"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
27
36
|
"publishConfig": {
|
|
28
37
|
"access": "public"
|
|
29
38
|
},
|
package/src/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { LookupAddress } from "node:dns";
|
|
2
2
|
import * as http from "node:http";
|
|
3
|
-
export { resolveAllowlist, type ResolveAllowlistInput } from "./allowlist.
|
|
4
|
-
export { type ClearanceCheckInput, type ClearanceListenerCheck, type ClearanceSpawner, ensureClearance, type EnsureClearanceInput, type EnsureClearanceResult, isClearanceListening, spawnClearance, type SpawnClearanceInput, } from "./launcher.
|
|
3
|
+
export { resolveAllowlist, type ResolveAllowlistInput } from "./allowlist.ts";
|
|
4
|
+
export { type ClearanceCheckInput, type ClearanceListenerCheck, type ClearanceSpawner, ensureClearance, type EnsureClearanceInput, type EnsureClearanceResult, isClearanceListening, spawnClearance, type SpawnClearanceInput, } from "./launcher.ts";
|
|
5
5
|
export declare const CLEARANCE_PACKAGE_NAME = "@clipboard-health/clearance";
|
|
6
6
|
export interface ClearanceConfig {
|
|
7
7
|
allowedHosts: readonly string[];
|