@openape/nest 0.2.1 → 0.3.0
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 +67 -0
- package/dist/index.mjs +1451 -111
- package/dist/node-WKMHQLLZ-IJUWLHGB.mjs +20 -0
- package/package.json +3 -2
package/README.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# @openape/nest
|
|
2
|
+
|
|
3
|
+
Local control-plane daemon. Manages OpenApe agents on a single machine — provisions macOS users, hands the bridge lifecycle off to launchd, exposes a localhost HTTP API gated by DDISA grant tokens.
|
|
4
|
+
|
|
5
|
+
## What it does
|
|
6
|
+
|
|
7
|
+
- Runs as a long-lived launchd-managed daemon under your user account (`~/Library/LaunchAgents/ai.openape.nest.plist`)
|
|
8
|
+
- Accepts API calls on `127.0.0.1:9091` for agent lifecycle ops (`spawn`, `destroy`, `list`, `status`)
|
|
9
|
+
- Every API call requires a DDISA-signed grant token in the `Authorization: Bearer …` header
|
|
10
|
+
- Bridge processes (`openape-chat-bridge` per agent) are NOT supervised in-daemon — they run as system-domain LaunchDaemons (one plist per agent in `/Library/LaunchDaemons/eco.hofmann.apes.bridge.<agent>.plist`) installed by `apes agents spawn --bridge`. launchd is the right OS-level supervisor on macOS; trying to duplicate that in the daemon crashloops without adding value.
|
|
11
|
+
|
|
12
|
+
## Setup (one-time)
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
apes nest install # install + load the launchd plist
|
|
16
|
+
apes nest enroll # daemon gets its own DDISA agent identity
|
|
17
|
+
apes nest authorize # set the YOLO policy — covers the inner
|
|
18
|
+
# `apes agents spawn` calls the daemon makes
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
After that, day-to-day lifecycle goes through `apes nest`:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
apes nest spawn igor18 # provision a new agent
|
|
25
|
+
apes nest list # show agents this nest knows about
|
|
26
|
+
apes nest status # health-check
|
|
27
|
+
apes nest destroy igor18 # tear down
|
|
28
|
+
apes nest uninstall # remove the launchd plist
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Why every API call needs a grant token
|
|
32
|
+
|
|
33
|
+
Without auth the API is gated only by "process running as the logged-in human can reach localhost:9091" — a compromised local process inherits everything. The grant-token requirement closes that gap and gives every call an audit record at the IdP. The flow:
|
|
34
|
+
|
|
35
|
+
1. `apes nest <op>` looks for an existing approved `'always'`/`'timed'` grant matching the operation.
|
|
36
|
+
2. If none, requests a fresh grant from the IdP. **First-time** grants for human callers wait for human approval (one approval covers the lifetime of the grant — `'always'` is the default for nest-CLI calls).
|
|
37
|
+
3. Token (RFC-7519 JWT signed by the IdP) is fetched and presented as `Authorization: Bearer …`.
|
|
38
|
+
4. The Nest verifies signature against the IdP's JWKS, checks `aud=nest`, `iss=<IdP URL>`, `target_host=<local hostname>`, and exact-matches the embedded `command` claim against the route. Fails: `401` (auth) or `403` (command mismatch).
|
|
39
|
+
|
|
40
|
+
### Grant-scope conventions
|
|
41
|
+
|
|
42
|
+
| CLI | Grant `command` | Reuse semantics |
|
|
43
|
+
|---|---|---|
|
|
44
|
+
| `apes nest list` | `["nest","list"]` | One approval, reused forever. |
|
|
45
|
+
| `apes nest status` | `["nest","status"]` | One approval, reused forever. |
|
|
46
|
+
| `apes nest spawn <name>` | `["nest","spawn"]` (no name baked in) | One approval, any future spawn. Trade-off: a compromised local process running as the human can spawn arbitrary agents under that grant. Acceptable because spawn is reversible and audited. |
|
|
47
|
+
| `apes nest destroy <name>` | `["nest","destroy","<name>"]` | Per-name. Destroying each agent is its own approval. Destructive ops keep tighter scoping by design. |
|
|
48
|
+
|
|
49
|
+
Direct `curl` to the API is supported but you must fetch a grant token yourself. See `tests/auth-negative.sh` for an example token-fetch.
|
|
50
|
+
|
|
51
|
+
## Negative-test smoke
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
bash apps/openape-nest/tests/auth-negative.sh
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Verifies: no-bearer → 401, garbage-bearer → 401, wrong-audience → 401, command-mismatch → 403.
|
|
58
|
+
|
|
59
|
+
## Why no in-daemon bridge supervisor
|
|
60
|
+
|
|
61
|
+
Earlier versions ran a per-agent process supervisor inside the Nest daemon to keep `openape-chat-bridge` instances alive. It was removed because:
|
|
62
|
+
|
|
63
|
+
- `apes agents spawn --bridge` already installs a system-domain `LaunchDaemon` per agent. launchd KeepAlive's it as the agent UID with the right PATH (the bridge binary is at `/Users/<agent>/.bun/bin/openape-chat-bridge`).
|
|
64
|
+
- The supervisor's children inherited the daemon's PATH (the human user's PATH, which doesn't include any agent's `~/.bun/bin`), so they crashlooped on `Command not found: openape-chat-bridge` while the launchd-domain bridge ran fine.
|
|
65
|
+
- Each crashloop produced an auto-approved YOLO grant — pushing one notification per cycle.
|
|
66
|
+
|
|
67
|
+
Single-source-of-truth on launchd. The Nest is now an API surface in front of `apes agents spawn|destroy`, nothing more.
|