@orchestraworks/worker 0.0.141 → 0.0.143
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 +17 -8
- package/docs/REFERENCE.md +112 -65
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -41,18 +41,19 @@ Run it once, as root on Linux or as an administrator on Windows, on a host that
|
|
|
41
41
|
Each step reads what is there, changes only what is different, and prints `ok: <step>` or
|
|
42
42
|
`changed: <step>`. The first failure stops the run and names the step. You can run it again.
|
|
43
43
|
|
|
44
|
-
`<root>` is the machine-wide root: `/var/lib/
|
|
44
|
+
`<root>` is the machine-wide root: `/var/lib/orchestra/worker` on Linux, `%ProgramData%\orchestra\worker` on Windows.
|
|
45
|
+
A host where an earlier release installed the worker keeps its root at `/var/lib/sfdk/worker` or `%ProgramData%\sfdk\worker`.
|
|
45
46
|
|
|
46
47
|
| Step | When | What it does |
|
|
47
48
|
|---|---|---|
|
|
48
|
-
| preconditions | always | Refuses a host it is not written for. Refuses a host that has booted as a machine: a boot file or `<root>/state` is there. Refuses a running worker service. |
|
|
49
|
+
| preconditions | always | Refuses a host it is not written for. Refuses a host that has booted as a machine: a boot file or `<root>/state` is there. Refuses a running worker service, under its name or the name an earlier release used. |
|
|
49
50
|
| directories | Windows | Creates `<root>`, `C:\software-factory` and its `etc` folder for SYSTEM and Administrators only. Users can also read and run `C:\software-factory`, which holds the programs on the machine path. A folder that is already there is kept as it is. |
|
|
50
51
|
| package | always | Copies this release package to `<root>/package`. The service runs from there, because a self-update replaces the package directory. |
|
|
51
52
|
| agent account | Linux | Creates the `agent` account, uid and gid 1000, home `/home`, and gives `/home` to it. Another account at uid 1000 is kept. |
|
|
52
53
|
| harnesses | `--harness` | Installs the named harness families and their Node under the root. `none` or no flag installs none: a family installs itself on its first turn, in about a minute. |
|
|
53
|
-
| service | always |
|
|
54
|
+
| service | always | Removes the service an earlier release registered, then defines the service, `OrchestraWorker` on Windows and `orchestra-worker.service` on Linux. It restarts after a failure. The step does not start it. |
|
|
54
55
|
| cloud | always | `azure`: at each boot, the start-up task runs `worker boot-files --cloud azure`, which writes the boot files from the VM's userData, and then the worker starts. `aws`: the worker starts at each boot, after the platform's user data, and an Azure start-up task or unit from an earlier run is removed. |
|
|
55
|
-
| egress redirect | `--egress-redirect` | WinDivert and its inbound firewall rule on Windows,
|
|
56
|
+
| egress redirect | `--egress-redirect` | WinDivert and its inbound firewall rule on Windows. On Linux it installs nothing: it checks that the kernel carries the nftables parts the worker's redirect needs, and loads `nf_conntrack`. A Launcher machine does not need it. |
|
|
56
57
|
| Docker | `--docker` | Windows containers, or rootless Docker for the `agent` account. |
|
|
57
58
|
| Node | `--node` | The agent's own Node, on the machine path. On Windows a new Node keeps the packages that `npm install -g` put in its folder. |
|
|
58
59
|
| check | always | Runs `worker check --profile launcher` for `azure`, and `--profile enrolled` for `aws`. |
|
|
@@ -104,7 +105,7 @@ The machine must reach these hosts. The command does not test them:
|
|
|
104
105
|
This command shows `"restartPending":false` when none is:
|
|
105
106
|
|
|
106
107
|
```powershell
|
|
107
|
-
& "$env:ProgramData\
|
|
108
|
+
& "$env:ProgramData\orchestra\worker\package\worker.exe" check --profile launcher --output json
|
|
108
109
|
```
|
|
109
110
|
|
|
110
111
|
6. Generalize with Sysprep:
|
|
@@ -177,6 +178,14 @@ The machine must reach these hosts. The command does not test them:
|
|
|
177
178
|
If the image serves an app, end your own boot step with one request to the app. The first request after
|
|
178
179
|
a boot is slow, so this request takes that delay instead of the first user.
|
|
179
180
|
|
|
181
|
+
### The worker's service name
|
|
182
|
+
|
|
183
|
+
The worker's service is `OrchestraWorker` on Windows, `orchestra-worker.service` on Linux and
|
|
184
|
+
`ai.livingcomputers.orchestra.worker` on macOS. An install replaces the service an earlier release registered
|
|
185
|
+
as `SfdkWorker`, `sfdk-worker.service` or `ai.livingcomputers.sfdk.worker`. Change your own scripts that name
|
|
186
|
+
it. An image an earlier release built keeps its service after a self-update, and
|
|
187
|
+
its start-up task still starts it.
|
|
188
|
+
|
|
180
189
|
### The model key and other tokens
|
|
181
190
|
|
|
182
191
|
Give the agent its model key in one of three ways. Each works on every machine, with or without our
|
|
@@ -187,9 +196,9 @@ egress edge. The edge and its Secrets are an addition, never needed for your own
|
|
|
187
196
|
an environment read returns them, and the VM's startup data carries them. If that is not acceptable,
|
|
188
197
|
use route 2 or 3, or a Secret at our egress edge where one stands in front.
|
|
189
198
|
2. **Baked into the image**, at machine scope, before Sysprep or generalizing. On Windows, that is the
|
|
190
|
-
`Environment` value (a multi-string) of `HKLM\SYSTEM\CurrentControlSet\Services\
|
|
199
|
+
`Environment` value (a multi-string) of `HKLM\SYSTEM\CurrentControlSet\Services\OrchestraWorker`. Keep
|
|
191
200
|
the entries that are there, and add or replace only yours. On Linux, it is a drop-in on
|
|
192
|
-
`
|
|
201
|
+
`orchestra-worker.service`.
|
|
193
202
|
3. **The `onStartAgent` hook** writes the harness's own key file in the agent's home:
|
|
194
203
|
`.claude/.credentials.json` for a Claude sign-in, `.codex/auth.json` for `codex`, or
|
|
195
204
|
`.pi/agent/auth.json` for `pi`. The worker keeps a real value it finds there. A raw Claude API key has
|
|
@@ -205,7 +214,7 @@ The names:
|
|
|
205
214
|
- `pi`: `ORCHESTRA_WORKER_OPENAI_API_KEY` or `ORCHESTRA_WORKER_CLAUDE_OAUTH_TOKEN`.
|
|
206
215
|
`ORCHESTRA_WORKER_PI_PROVIDER` chooses the provider.
|
|
207
216
|
|
|
208
|
-
Never restart `
|
|
217
|
+
Never restart `OrchestraWorker` or `orchestra-worker.service` to load a key. A restart after the worker registered
|
|
209
218
|
stops the machine's work, and the platform parks the VM. The next message starts it again, 1 to 2
|
|
210
219
|
minutes later.
|
|
211
220
|
|
package/docs/REFERENCE.md
CHANGED
|
@@ -12,7 +12,7 @@ The worker exposes no API of its own. Every route it calls is the platform's.
|
|
|
12
12
|
|
|
13
13
|
| path | what it holds |
|
|
14
14
|
|---|---|
|
|
15
|
-
| `cmd/worker/` | the one binary: `run`, `install`, `install-machine`, `boot-files`, `enroll`, `check`, `trust-nested`, `screen`, `version` |
|
|
15
|
+
| `cmd/worker/` | the one binary: `run`, `install`, `install-machine`, `boot-files`, `enroll`, `check`, `trust-nested`, `screen`, `redirect`, `version` |
|
|
16
16
|
| `identity/` | the four identity exchanges — claim, refresh, reattach-challenge, reattach — the holder key, and the loop that keeps the machine token alive |
|
|
17
17
|
| `broker/` | the protocol on the message broker: the connection, the register on every connect, the heartbeat and the status cadence, the pull of this machine's own work consumer, and the publisher every other package sends through |
|
|
18
18
|
| `env/` | the machine-side environment the platform composes onto a launch, read from the names the contract declares |
|
|
@@ -21,7 +21,7 @@ The worker exposes no API of its own. Every route it calls is the platform's.
|
|
|
21
21
|
| `process/` | the agent's setup and the harness process behind each session placement: the start, the stop and the last save a remove asks for, the startup fence over what a previous run left, and the stop of everything when the worker is told to stop |
|
|
22
22
|
| `stream/` | the queue: every placement message and every prompt, steer and cancel pulled off this machine's work consumer, the ACP client that opens a session's harness conversation and runs its turns, each turn's events batched to the platform and published live, and the answer every placement message is owed |
|
|
23
23
|
| `mount/` | the volumes the launch declares, placed on the lanes that mount them: the home volume first, because anything written under a mount point before the mount is hidden by it |
|
|
24
|
-
| `network/` | the transparent redirect
|
|
24
|
+
| `network/` | the transparent redirect the launch describes, as the worker's own nftables table written over netlink with no program from the image: what the worker's own uid reaches directly, and what every uid on the machine reaches through the egress edge |
|
|
25
25
|
| `shim/` | the in-guest transparent proxy: the listener the redirect lands on, the recovery of the destination each connection was actually for, the hop to the egress edge under the machine-identity proof, the WinDivert half that is the Windows redirect, and the loopback feed a separate shim reads this machine's token from |
|
|
26
26
|
| `egress/` | what puts that proxy in place on the virtual-machine lanes: the edge's certificate authority in this machine's trust store, the inbound firewall rule Windows needs, the redirect itself, and the state line an operator reads off the machine's console |
|
|
27
27
|
| `ingress/` | the machine's half of the preview tunnel: the connection this worker holds open to the preview gateway, the challenge and the signed upgrade that authenticate it, and the loopback pipe that carries each viewer request to a port this machine declared and refuses every other |
|
|
@@ -39,6 +39,8 @@ shapes the schema ships, and nothing here re-declares one.
|
|
|
39
39
|
|
|
40
40
|
## The commands
|
|
41
41
|
|
|
42
|
+
Each `ORCHESTRA_` machine variable this page names also has a former `SFDK_` spelling. Until the rename's compatibility period ends ([D50](../../docs/specs/2026-10-03_2446_orchestra_rename_spec.md)), the platform and the worker still write the former spelling beside the new one, and every reader takes the new name first and the former one when the new one is absent.
|
|
43
|
+
|
|
42
44
|
- **`worker run`** claims this machine's identity — or reattaches, where its row is already bound to
|
|
43
45
|
the key this machine holds — and then serves the machine. `run` hands the held identity, with the
|
|
44
46
|
broker credential the claim co-issued, to the registrar seam in `cmd/worker/run.go`, which the
|
|
@@ -48,7 +50,7 @@ shapes the schema ships, and nothing here re-declares one.
|
|
|
48
50
|
Before any of that, `run` starts what the launch describes: it places the declared volumes, puts
|
|
49
51
|
the in-guest egress in place where the launch names an intercept set, opens the egress shim's token
|
|
50
52
|
feed, and — on a machine the cloud can reclaim — watches for the notice that it is going away. Each
|
|
51
|
-
is started only where it is described:
|
|
53
|
+
is started only where it is described: an OpenSandbox pod places its own volumes and its egress
|
|
52
54
|
sidecar installs its own redirect, so a launch there names neither. If one of those duties is
|
|
53
55
|
installed and then dies, `run` ends rather than serving a machine the platform counts as healthy
|
|
54
56
|
with no route off it; the service manager starts the worker again.
|
|
@@ -91,6 +93,13 @@ shapes the schema ships, and nothing here re-declares one.
|
|
|
91
93
|
same answer. Nothing on a machine somebody owns needs privilege: network enforcement is outside the
|
|
92
94
|
machine, at the egress edge and the directional security group.
|
|
93
95
|
|
|
96
|
+
**An install replaces the service an earlier release registered.** It first stops and deletes that
|
|
97
|
+
service in the scope this install registers in. On Windows, the earlier service is the `SfdkWorker`
|
|
98
|
+
service in system scope, or the `SfdkWorker` logon task in user scope. On Linux, the earlier service
|
|
99
|
+
is the `sfdk-worker.service` unit, and on macOS the `ai.livingcomputers.sfdk.worker` job. Then the install
|
|
100
|
+
defines `OrchestraWorker`, `orchestra-worker.service` or `ai.livingcomputers.orchestra.worker`. When the
|
|
101
|
+
removal fails, the install stops and defines nothing new. Change your own scripts that name the old ones.
|
|
102
|
+
|
|
94
103
|
**The machine-wide service is the image role's, and the role is the whole of what asks for it.** An
|
|
95
104
|
`image` gets it — a property list under `/Library/LaunchDaemons`, a unit under `/etc/systemd/system`,
|
|
96
105
|
a Windows service — because the platform builds the image with nobody logged in to it and nobody
|
|
@@ -98,8 +107,10 @@ shapes the schema ships, and nothing here re-declares one.
|
|
|
98
107
|
virtual-machine image is made by `worker install-machine` below, which our bakes run; the `image` role
|
|
99
108
|
stays for a container image, whose own command is the worker.
|
|
100
109
|
|
|
101
|
-
`--root` follows the scope the same way: `~/.
|
|
102
|
-
a `user` install, `/var/lib/
|
|
110
|
+
`--root` follows the scope the same way: `~/.orchestra/worker` (`%LOCALAPPDATA%\orchestra\worker` on
|
|
111
|
+
Windows) for a `user` install, `/var/lib/orchestra/worker` (`%ProgramData%\orchestra\worker`) for the other
|
|
112
|
+
two. Where the earlier release's root already holds the worker's identity or its install, the
|
|
113
|
+
install keeps that root instead. A `user`
|
|
103
114
|
install writes its log under that root, at `log/worker.log`, because no service manager in that scope
|
|
104
115
|
keeps one a person can read.
|
|
105
116
|
|
|
@@ -145,12 +156,14 @@ shapes the schema ships, and nothing here re-declares one.
|
|
|
145
156
|
`--root` and installs under the machine-wide root. Each step reads the current state, changes only what
|
|
146
157
|
differs, reads the result back and prints `ok: <step>` or `changed: <step>`; the first failure stops the
|
|
147
158
|
run. So a second run on a converged host changes nothing, and a run that stopped part way is repaired by
|
|
148
|
-
running it again. It refuses a host that has already booted as a machine
|
|
149
|
-
is there
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
159
|
+
running it again. It refuses a host that has already booted as a machine, where a boot file or
|
|
160
|
+
`<root>/state` is there. Removing one is not a repair. It also refuses a running worker service,
|
|
161
|
+
under its name or the name an earlier release used. On Windows, the command creates three separate
|
|
162
|
+
directories: `<root>`, the install root `C:\software-factory`, and the `etc` directory in the install
|
|
163
|
+
root. Only SYSTEM and Administrators may use these three directories. Users may also read and run the
|
|
164
|
+
install root, whose `bin` and `node` directories are on the machine path. The command keeps a
|
|
165
|
+
directory that is already there, with that directory's permissions. The service step
|
|
166
|
+
removes a service with the earlier release's name, then defines the new one.
|
|
154
167
|
|
|
155
168
|
The service runs from a copy of the release package at `<root>/package`, because the self-update
|
|
156
169
|
replaces the directory the running binary sits in; the step compares that copy's `worker version`
|
|
@@ -178,7 +191,7 @@ shapes the schema ships, and nothing here re-declares one.
|
|
|
178
191
|
this boot does not carry is removed, so a resumed VM never reads its previous launch's file. Each file
|
|
179
192
|
is written under a staged name of its own, created new with its permissions before any byte, and
|
|
180
193
|
renamed into place: on Linux at modes `0600`, `0600` and `0644`, the egress authority being the one the
|
|
181
|
-
agent's programs read, and on Windows readable by SYSTEM and Administrators alone. On Windows it starts `SfdkWorker`
|
|
194
|
+
agent's programs read, and on Windows readable by SYSTEM and Administrators alone. On Windows it starts `OrchestraWorker` last, or `SfdkWorker` on an image an earlier release built; on Linux systemd starts the worker's unit after this one ends.
|
|
182
195
|
- **`worker enroll`** redeems the enrollment token this machine was given, prints the row it was
|
|
183
196
|
issued, and then serves that machine. It does not stop at the redemption, because the holder key
|
|
184
197
|
the redemption bound lives in this process.
|
|
@@ -213,11 +226,15 @@ shapes the schema ships, and nothing here re-declares one.
|
|
|
213
226
|
A pending restart is reported and never refused: Sysprep refuses to generalize while one is pending.
|
|
214
227
|
- **`worker trust-nested [--registry <host>]... [--root <dir>]`** lets the containers this machine
|
|
215
228
|
runs trust the egress edge, which nothing does by default. It reads the authority from
|
|
216
|
-
`
|
|
229
|
+
`ORCHESTRA_EGRESS_CA_FILE`, which the worker sets on every harness process and on the setup script;
|
|
217
230
|
writes it into dockerd's `certs.d` for the well-known registries and each one named; writes
|
|
218
231
|
`k3d-registries.yaml` under the root, whose `ca_file` is the authority's path inside each k3d node;
|
|
219
232
|
and prints the flags `docker run`, compose and `k3d cluster create` need. On a machine that names no
|
|
220
233
|
authority, such as one with no edge in front of it, it says so, writes nothing and succeeds.
|
|
234
|
+
- **`worker redirect`** prints the redirect table this worker wrote, or says that none is installed;
|
|
235
|
+
**`worker redirect remove`** deletes it. Each runs with its caller's own rights, so without
|
|
236
|
+
`CAP_NET_ADMIN` the kernel refuses both, and each exits 0 on an answer and 1 on a failure. Off Linux
|
|
237
|
+
both refuse, naming the operating system. What the table holds is under the in-guest egress below.
|
|
221
238
|
- **`worker version`** prints this binary's version, the release package it belongs to, and the
|
|
222
239
|
protocol versions it speaks.
|
|
223
240
|
|
|
@@ -228,43 +245,46 @@ version it is not.
|
|
|
228
245
|
## The bootstrap a machine is started with
|
|
229
246
|
|
|
230
247
|
Everything above assumes the worker already knows where its platform is. That is the one family of
|
|
231
|
-
names it reads before it can speak to anything
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
environment
|
|
237
|
-
|
|
248
|
+
names it reads before it can speak to anything. `fwp/schema/environment-v1.json` lists them in its
|
|
249
|
+
`bootstrap` list, apart from the other names the platform or the worker sets for a running machine. The
|
|
250
|
+
table below gives each in its former spelling. Each also has a name under `ORCHESTRA_WORKER_`, the
|
|
251
|
+
document's `name`, which the worker reads first; it reads the former spelling when the new one is absent
|
|
252
|
+
or blank. The two enrollment carriers are read under their former spelling alone for now. An
|
|
253
|
+
environment cannot declare a name under `SFDK_` or `ORCHESTRA_`, apart from the release settings the
|
|
254
|
+
document lists under `customerDeclarable`, which the worker reads from its own environment in preference to
|
|
255
|
+
the register answer. The platform composes what is listed here; a value it does not set is a concern this
|
|
256
|
+
machine does not have.
|
|
238
257
|
|
|
239
258
|
| name | what it carries |
|
|
240
259
|
|---|---|
|
|
241
|
-
| `
|
|
242
|
-
| `
|
|
243
|
-
| `
|
|
244
|
-
| `
|
|
245
|
-
| `
|
|
246
|
-
| `
|
|
247
|
-
| `
|
|
248
|
-
| `
|
|
249
|
-
| `
|
|
250
|
-
| `
|
|
251
|
-
| `
|
|
252
|
-
| `
|
|
253
|
-
| `
|
|
254
|
-
| `
|
|
255
|
-
| `
|
|
256
|
-
| `
|
|
257
|
-
| `
|
|
258
|
-
| `
|
|
259
|
-
| `
|
|
260
|
-
| `
|
|
261
|
-
| `
|
|
262
|
-
| `
|
|
263
|
-
| `
|
|
264
|
-
| `
|
|
265
|
-
| `
|
|
266
|
-
| `
|
|
267
|
-
| `
|
|
260
|
+
| `ORCHESTRA_WORKER_CLAIM_ENDPOINT_URL` | the platform's origin, not a route: the paths belong to the protocol |
|
|
261
|
+
| `ORCHESTRA_WORKER_TRANSPORT_TRUST_ROOTS` | the certificate bundle this machine trusts, inline |
|
|
262
|
+
| `ORCHESTRA_WORKER_TRANSPORT_TRUST_ROOTS_FILE` | the same bundle as an absolute path, for a delivery that cannot carry the newlines; setting both is refused |
|
|
263
|
+
| `ORCHESTRA_WORKER_CLAIM_LOCATOR` | the machine row this worker claims as |
|
|
264
|
+
| `ORCHESTRA_WORKER_ENROLLMENT_TOKEN` | the show-once token an enrolling machine redeems; mutually exclusive with the locator |
|
|
265
|
+
| `ORCHESTRA_WORKER_ENROLLMENT_TOKEN_FILE` | the same token as an absolute path; setting both is refused |
|
|
266
|
+
| `ORCHESTRA_WORKER_HOLDER_KEY_ALGORITHM` | which of the protocol's two holder-key algorithms this registration declares |
|
|
267
|
+
| `ORCHESTRA_WORKER_SUBSTRATE` | which evidence this worker gathers, so an unknown value is refused rather than defaulted |
|
|
268
|
+
| `ORCHESTRA_WORKER_CLAIM_AUDIENCE` | who the presented caller-identity request was meant for; required on the virtual-machine lanes |
|
|
269
|
+
| `ORCHESTRA_WORKER_STS_ENDPOINT_URL` | the security-token endpoint the platform will send that request to |
|
|
270
|
+
| `ORCHESTRA_WORKER_SERVICE_ACCOUNT_TOKEN_FILE` | where the audience-bound projected token is mounted, on the Kubernetes lane |
|
|
271
|
+
| `ORCHESTRA_WORKER_TPM_DEVICE_PATH` | the chip's device path where it is not this operating system's default |
|
|
272
|
+
| `ORCHESTRA_WORKER_SUBSTRATE_TOKEN` | the `local` substrate's stand-in factor, inline |
|
|
273
|
+
| `ORCHESTRA_WORKER_SUBSTRATE_TOKEN_FILE` | the same factor as an absolute path; setting both is refused |
|
|
274
|
+
| `ORCHESTRA_WORKER_INTERCEPT_PORTS` | the destination ports whose traffic goes to the egress edge, comma separated; naming none installs no redirect |
|
|
275
|
+
| `ORCHESTRA_WORKER_INTERCEPT_BYPASS` | the shared services the worker's own uid reaches directly, as `[{"host": …, "port": …}]` — our broker and our gateway, and nothing broader |
|
|
276
|
+
| `ORCHESTRA_WORKER_INTERCEPT_SKIP_RANGES` | the private ranges the redirect never takes, for any uid on any port, as comma-separated CIDR ranges; a range that is not wholly private is refused |
|
|
277
|
+
| `ORCHESTRA_WORKER_EDGE_ENDPOINT_URL` | where the redirect sends this machine's traffic; its scheme is the whole TLS statement for that hop |
|
|
278
|
+
| `ORCHESTRA_WORKER_EGRESS_LISTEN_PORT` | where the redirect lands, which is the shim's own listen port |
|
|
279
|
+
| `ORCHESTRA_WORKER_EGRESS_IPV6` | `true` also writes the worker's redirect table for IPv6 |
|
|
280
|
+
| `ORCHESTRA_WORKER_EGRESS_PROXY` | `on`, the default, or `off`; `off` tells each harness that no edge of ours stands in front of this machine, as on an enrolled one. The platform writes `off` into a Launcher machine's boot file only where the deployment names no public egress entrance |
|
|
281
|
+
| `ORCHESTRA_WORKER_LAUNCHER` | `true` on a machine a customer's Launcher created, written by that boot file alone; absent or `false` elsewhere. Such a machine with no `egress-redirect` file under the worker root runs the local egress port on loopback with no redirect |
|
|
282
|
+
| `ORCHESTRA_WORKER_RUNTIME_ENVIRONMENT` | a whole environment folded into one JSON object of string values, for a boot file whose lines cannot carry a line break; each pair is placed unless already set, except that a non-blank pair replaces a name that holds exactly the image's placeholder |
|
|
283
|
+
| `ORCHESTRA_WORKER_VOLUME_MOUNTS` | the volumes this launch declares, as one JSON document |
|
|
284
|
+
| `ORCHESTRA_WORKER_MACHINE_SLUG` | the machine's platform-minted slug: the leading label of its preview hostnames, and what the tunnel's upgrade signs |
|
|
285
|
+
| `ORCHESTRA_WORKER_TUNNEL_ENDPOINT_URL` | where the preview gateway serves its tunnel listener; its scheme is the whole TLS statement for that hop |
|
|
286
|
+
| `ORCHESTRA_WORKER_INGRESS_PORTS` | the loopback ports this machine projects through that tunnel, comma separated; with no reserved ports below, naming none holds no tunnel |
|
|
287
|
+
| `ORCHESTRA_WORKER_INGRESS_ANY_PORT_EXCEPT` | the reserved loopback ports, comma separated; set, the tunnel is held from start, forwards every other port whatever `ORCHESTRA_WORKER_INGRESS_PORTS` says, and the worker registers `ingress-any-port` |
|
|
268
288
|
|
|
269
289
|
**The worker reads that file itself, on every operating system, and no service manager is handed it.**
|
|
270
290
|
Every `worker run` places each pair into its own environment before it serves, leaving alone any name
|
|
@@ -274,16 +294,17 @@ a placeholder the family facts list, whether or not an egress edge stands in fro
|
|
|
274
294
|
customer's own token in `provisionSpec.env` reaches the harness; it rides the machine's startup data in
|
|
275
295
|
plain text. systemd's
|
|
276
296
|
`EnvironmentFile=` is deliberately not used: it processes backslash escapes in an unquoted value, so
|
|
277
|
-
the two characters `\n` that carry a line break inside `
|
|
297
|
+
the two characters `\n` that carry a line break inside `ORCHESTRA_WORKER_RUNTIME_ENVIRONMENT` would arrive as a bare
|
|
278
298
|
`n` and the certificate folded in there would hold no certificate at all. A machine with no file
|
|
279
299
|
starts anyway — that is an enrolled machine's ordinary start — and a line that is not `NAME=VALUE`
|
|
280
300
|
stops the start and is named.
|
|
281
301
|
|
|
282
302
|
Where the file sits is the one thing that differs, and only because of who may write it. On a Linux
|
|
283
|
-
machine the platform launched, cloud-init writes `/etc/sfdk/machine.env`
|
|
303
|
+
machine the platform launched, cloud-init writes `/etc/orchestra/machine.env`, and `/etc/sfdk/machine.env` for a worker
|
|
304
|
+
of an earlier release, from the user data and the run
|
|
284
305
|
reads it; on an Azure machine `worker boot-files` writes the same file from the VM's userData, and
|
|
285
306
|
`<root>\machine.env` on Windows. No install by a person writes there. A `worker` install that registers a service writes
|
|
286
|
-
`<root>/machine.env` under the worker's own root — `C:\ProgramData\
|
|
307
|
+
`<root>/machine.env` under the worker's own root — `C:\ProgramData\orchestra\worker\machine.env` on a default
|
|
287
308
|
machine-wide Windows install — because an install that registers the worker in one person's own session
|
|
288
309
|
cannot write under `/etc`. A Linux run reads both, the machine-wide one first. The platform's user data writes that file on a machine
|
|
289
310
|
it launched, and a person enrolling one writes it or exports the same names in the shell that runs
|
|
@@ -303,8 +324,8 @@ rather than woken, and its row is fresh with it.
|
|
|
303
324
|
|
|
304
325
|
## The in-guest egress
|
|
305
326
|
|
|
306
|
-
|
|
307
|
-
things in place in one order that is not interchangeable:
|
|
327
|
+
Wherever the launch names an intercept set, this worker's own process is the transparent proxy, and
|
|
328
|
+
it puts three things in place in one order that is not interchangeable:
|
|
308
329
|
|
|
309
330
|
1. **The edge's certificate authority into this machine's trust store**, from the file the launch
|
|
310
331
|
wrote (or, where that file is not there, from the URL it names). Windows reads the machine
|
|
@@ -315,9 +336,23 @@ things in place in one order that is not interchangeable:
|
|
|
315
336
|
2. **The listener**, bound before any rule exists, so no connection is ever sent to a port with
|
|
316
337
|
nothing behind it. On Windows an inbound firewall rule is written first as well: the rewritten
|
|
317
338
|
packet arrives as an inbound connection, which Windows Server blocks by default.
|
|
318
|
-
3. **The redirect** —
|
|
319
|
-
by absolute path from `<root>\bin`, where `install-machine --egress-redirect`
|
|
320
|
-
operating system's own search order: opening the driver installs and starts
|
|
339
|
+
3. **The redirect** — the worker's own nftables table on Linux, WinDivert on Windows. The two
|
|
340
|
+
WinDivert files are loaded by absolute path from `<root>\bin`, where `install-machine --egress-redirect`
|
|
341
|
+
places them, and never through the operating system's own search order: opening the driver installs and starts
|
|
342
|
+
a kernel service.
|
|
343
|
+
|
|
344
|
+
On Linux the worker runs no program from the image to install its redirect, so an image needs neither
|
|
345
|
+
`iptables` nor `nft`. It writes one table, `orchestra_worker`, in the `ip` family and, where the launch
|
|
346
|
+
declares IPv6, in `ip6` too, over netlink through `github.com/google/nftables`, in one transaction the
|
|
347
|
+
kernel takes whole or not at all. Each bypassed host is resolved once, when the table is written, and
|
|
348
|
+
the rules hold the addresses it resolved to then. The kernel needs nftables for each family in play
|
|
349
|
+
(`CONFIG_NF_TABLES` with `CONFIG_NF_TABLES_IPV4` or `_IPV6`), `CONFIG_NFT_NAT` and `CONFIG_NFT_REDIR`,
|
|
350
|
+
built in or as modules; a kernel missing one fails the install, and the error names the part.
|
|
351
|
+
|
|
352
|
+
The table is written once, at the start, and the running worker never writes it again, so a table
|
|
353
|
+
`worker redirect remove` deleted stays deleted until the next start; `worker redirect` prints it as
|
|
354
|
+
`nft list table` would. A worker updated in place from a release that installed `iptables` rules keeps
|
|
355
|
+
those rules, which `worker redirect remove` does not touch.
|
|
321
356
|
|
|
322
357
|
Each accepted connection's original destination is recovered (`SO_ORIGINAL_DST` on Linux, the
|
|
323
358
|
redirect's own proxy-port map on Windows; a recovery that misses is refused rather than sent to the
|
|
@@ -332,13 +367,24 @@ this worker calls it before it holds the token the edge would identify it by; an
|
|
|
332
367
|
service, which answers the evidence that call presents. Nothing is uid-wide, so the object store
|
|
333
368
|
stays intercepted and this worker's own content pulls meet the platform's rule at the edge.
|
|
334
369
|
|
|
335
|
-
The redirect takes its Windows form on Windows and its
|
|
370
|
+
The redirect takes its Windows form on Windows and its nftables form everywhere else, whatever the
|
|
336
371
|
substrate. A pod with an egress sidecar runs only the certificate step: the sidecar installs that
|
|
337
|
-
lane's redirect and runs its own shim, which reads the token from the loopback feed below. A
|
|
338
|
-
|
|
339
|
-
redirect itself
|
|
340
|
-
|
|
341
|
-
|
|
372
|
+
lane's redirect and runs its own shim, which reads the token from the loopback feed below. A Launcher
|
|
373
|
+
machine, a Launcher pod included, names an intercept set: where `install-machine --egress-redirect`
|
|
374
|
+
wrote the file `egress-redirect` under the worker root this worker installs the redirect itself, and
|
|
375
|
+
where it did not, as on an image built before that file existed, the worker binds the local egress port
|
|
376
|
+
on loopback alone and each harness reaches it through the proxy names. The machine's token stays in
|
|
377
|
+
this worker either way.
|
|
378
|
+
|
|
379
|
+
The local egress port resolves a destination's name once. Where every address it answers is in a range
|
|
380
|
+
`SFDK_INTERCEPT_SKIP_RANGES` names or is a compiled-in exemption, the port dials that address itself;
|
|
381
|
+
otherwise it forwards the request to the edge by name. `NO_PROXY` lists the same ranges and exemptions
|
|
382
|
+
for a tool that reads ranges, and then names the host of `ORCHESTRA_EGRESS_CA_URL`, so a harness fetches
|
|
383
|
+
the edge's certificate directly rather than through an edge that may refuse it. On an Azure machine the
|
|
384
|
+
compiled-in exemptions are the metadata service and the platform's host address `168.63.129.16`, which
|
|
385
|
+
skip the redirect on Windows and on Linux.
|
|
386
|
+
|
|
387
|
+
The private ranges `ORCHESTRA_WORKER_INTERCEPT_SKIP_RANGES` names are never redirected, for any uid on any port:
|
|
342
388
|
the rules return them ahead of the redirect, a nested container reaches them through its bridge, and
|
|
343
389
|
the Windows filter excludes each range beside the single destinations.
|
|
344
390
|
|
|
@@ -483,21 +529,22 @@ artifacts:
|
|
|
483
529
|
|
|
484
530
|
The worker does not *merge* an environment into a harness process: the family's `passEnv` enumeration in
|
|
485
531
|
`facts/families.json` **is** that process's complete environment. An environment cannot declare an
|
|
486
|
-
`SFDK_` name for it, because
|
|
532
|
+
`ORCHESTRA_` or `SFDK_` name for it, because both are reserved apart from `ORCHESTRA_FDK_` names and the seven
|
|
533
|
+
`ORCHESTRA_WORKER_*` settings, which
|
|
487
534
|
reach the worker and never a harness process. A derived image that bakes a name the list does not carry, such as `ENV JOB_TARGET=…`, gets **silence**,
|
|
488
535
|
not an override: the variable never reaches the command, and a job running under `set -u` aborts on the
|
|
489
536
|
first reference to it. Per-job configuration travels the prompt, the agent's instructions, or a file in the
|
|
490
537
|
image.
|
|
491
538
|
|
|
492
539
|
The worker consumes every `ORCHESTRA_WORKER_<FIELD>` variable itself and drops it from every list,
|
|
493
|
-
`
|
|
540
|
+
`ORCHESTRA_EXTRA_PASSENV` included: those are the sign-in and settings the worker places for the harness, from the
|
|
494
541
|
`settings` table of `facts/families.json` (`docs/architecture/agent-runtime-images.md` § *The worker places
|
|
495
542
|
each harness's sign-in and settings*).
|
|
496
543
|
|
|
497
|
-
Every family's harness process also gets `
|
|
544
|
+
Every family's harness process also gets `ORCHESTRA_SESSION_ID`, which the worker sets from the `sessionId` on
|
|
498
545
|
`session_placement.apply`: the worker adds it itself, so it needs no `passEnv` entry, whatever the worker's
|
|
499
546
|
own environment holds. The `script` family adds only the organization to the command it runs, as
|
|
500
|
-
`ORCHESTRA_ORGANIZATION_ID
|
|
547
|
+
`ORCHESTRA_ORGANIZATION_ID`, from its stored conversation metadata; its command inherits
|
|
501
548
|
the session variable from the harness process. Neither grants egress authority.
|
|
502
549
|
|
|
503
550
|
**On Windows the operating system's own variables are added to that list.** The list is not a filter over
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orchestraworks/worker",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.143",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The Orchestra worker.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -22,10 +22,10 @@
|
|
|
22
22
|
"docs/REFERENCE.md"
|
|
23
23
|
],
|
|
24
24
|
"optionalDependencies": {
|
|
25
|
-
"@orchestraworks/worker-linux-x64": "0.0.
|
|
26
|
-
"@orchestraworks/worker-linux-arm64": "0.0.
|
|
27
|
-
"@orchestraworks/worker-darwin-x64": "0.0.
|
|
28
|
-
"@orchestraworks/worker-darwin-arm64": "0.0.
|
|
29
|
-
"@orchestraworks/worker-win32-x64": "0.0.
|
|
25
|
+
"@orchestraworks/worker-linux-x64": "0.0.143",
|
|
26
|
+
"@orchestraworks/worker-linux-arm64": "0.0.143",
|
|
27
|
+
"@orchestraworks/worker-darwin-x64": "0.0.143",
|
|
28
|
+
"@orchestraworks/worker-darwin-arm64": "0.0.143",
|
|
29
|
+
"@orchestraworks/worker-win32-x64": "0.0.143"
|
|
30
30
|
}
|
|
31
31
|
}
|