You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .agents/skills/debug-openshell-cluster/SKILL.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -182,7 +182,7 @@ Component images (server, sandbox) can reach kubelet via two paths:
182
182
183
183
**Local/external pull mode** (default local via `mise run cluster`): Local images are tagged to the configured local registry base (default `127.0.0.1:5000/openshell/*`), pushed to that registry, and pulled by k3s via `registries.yaml` mirror endpoint (typically `host.docker.internal:5000`). The `cluster` task pushes prebuilt local tags (`openshell/*:dev`, falling back to `localhost:5000/openshell/*:dev` or `127.0.0.1:5000/openshell/*:dev`).
184
184
185
-
Gateway image builds now stage a partial Rust workspace from `deploy/docker/Dockerfile.images`. If cargo fails with a missing manifest under `/build/crates/...`, verify that every current gateway dependency crate (including `openshell-driver-kubernetes`) is copied into the staged workspace there.
185
+
Gateway image builds now stage a partial Rust workspace from `deploy/docker/Dockerfile.images`. If cargo fails with a missing manifest under `/build/crates/...`, or an imported symbol exists locally but is missing in the image build, verify that every current gateway dependency crate (including `openshell-driver-kubernetes` and `openshell-ocsf`) is copied into the staged workspace there.
186
186
187
187
```bash
188
188
# Verify image refs currently used by openshell deployment
2. Use full YAML replacement when the change is broad or touches non-network fields:
428
+
`openshell policy get work-session --full > policy.yaml`
429
+
Modify the policy to allow the blocked actions (use `generate-sandbox-policy` skill for content)
430
+
`openshell policy set work-session --policy policy.yaml --wait`
431
+
3. Verify: `openshell policy list work-session`
428
432
429
433
The user does not need to disconnect -- policy updates are hot-reloaded within ~30 seconds (or immediately when using `--wait`, which polls for confirmation).
Incrementally merge live network policy changes into the current sandbox policy. Multiple flags in one invocation are applied as one atomic batch and create at most one new revision.
274
+
275
+
| Flag | Default | Description |
276
+
|------|---------|-------------|
277
+
|`--add-endpoint <SPEC>`| repeatable |`host:port[:access[:protocol[:enforcement]]]`. Adds or merges an endpoint. `access`: `read-only`, `read-write`, `full`. `protocol`: `rest`, `sql`. `enforcement`: `enforce`, `audit`. |
278
+
|`--remove-endpoint <SPEC>`| repeatable |`host:port`. Removes the endpoint or just the requested port from a multi-port endpoint. |
279
+
|`--add-allow <SPEC>`| repeatable |`host:port:METHOD:path_glob`. Adds REST allow rules to an existing `protocol: rest` endpoint. |
280
+
|`--add-deny <SPEC>`| repeatable |`host:port:METHOD:path_glob`. Adds REST deny rules to an existing `protocol: rest` endpoint that already has an allow base. |
281
+
|`--remove-rule <NAME>`| repeatable | Deletes a named network rule. |
282
+
|`--binary <PATH>`| repeatable | Adds binaries to each `--add-endpoint` rule. Valid only with `--add-endpoint`. |
283
+
|`--rule-name <NAME>`| none | Overrides the generated rule name. Valid only when exactly one `--add-endpoint` is provided. |
284
+
|`--dry-run`| false | Preview the merged policy locally without sending an update to the gateway. |
285
+
|`--wait`| false | Wait for the sandbox to confirm the new policy revision is loaded. |
286
+
|`--timeout <SECS>`| 60 | Timeout for `--wait`. |
287
+
288
+
Notes:
289
+
290
+
-`--add-allow` and `--add-deny` currently operate only on `protocol: rest` endpoints.
291
+
-`--wait` cannot be combined with `--dry-run`.
292
+
- Use `policy set` when replacing the full policy or changing static sections.
293
+
271
294
### `openshell policy set <name> --policy <PATH>`
272
295
273
-
Update the policy on a live sandbox. Only the dynamic `network_policies` field can be changed at runtime.
296
+
Replace the full policy on a live sandbox. Only the dynamic `network_policies` field can be changed at runtime.
Copy file name to clipboardExpand all lines: architecture/security-policy.md
+32-2Lines changed: 32 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -162,6 +162,24 @@ This guarantees that the same logical policy always produces the same hash regar
162
162
163
163
**Idempotent updates**: `UpdateSandboxPolicy` compares the deterministic hash of the submitted policy against the latest stored revision's hash. If they match, the handler returns the existing version and hash without creating a new revision. The CLI detects this (the returned version equals the pre-call version) and prints `Policy unchanged` instead of `Policy version N submitted`. This makes repeated `policy set` calls safe and idempotent.
164
164
165
+
### Incremental Merge Updates
166
+
167
+
`UpdateConfigRequest.merge_operations` supports batched incremental changes to the dynamic `network_policies` section. The CLI exposes this as `openshell policy update`.
`--add-allow` and `--add-deny` target existing `protocol: rest` endpoints only. `--binary` may be repeated with `--add-endpoint`, and `--rule-name` is allowed only when exactly one `--add-endpoint` is present.
178
+
179
+
Each `openshell policy update` invocation is atomic at the revision level: the CLI sends one `merge_operations` batch, the server merges the whole batch into the latest policy, validates the result, and persists at most one new revision. Concurrency is handled with optimistic retries on the `(sandbox_id, version)` uniqueness boundary. If another writer wins first, the server refetches the latest policy, reapplies the full batch, revalidates it, and retries. This preserves batch atomicity without serializing all sandbox policy writes behind a sandbox-global mutex.
180
+
181
+
The gateway emits per-sandbox OCSF `CONFIG:*` audit lines when incremental merge operations are applied and when draft chunks are approved or removed. These audit lines are streamed through the existing gateway log path, so operators can inspect the exact logical mutation that produced a policy revision without waiting for the sandbox poll loop to reload that revision.
@@ -255,6 +284,7 @@ Both `set` and `delete` require interactive confirmation (or `--yes` to bypass).
255
284
256
285
When a global policy is active, sandbox-scoped policy mutations are blocked:
257
286
-`policy set <sandbox>` returns `FailedPrecondition: "policy is managed globally"`
287
+
-`policy update <sandbox>` returns `FailedPrecondition: "policy is managed globally"`
258
288
-`rule approve`, `rule approve-all` return `FailedPrecondition: "cannot approve rules while a global policy is active"`
259
289
- Revoking a previously approved draft chunk is blocked (it would modify the sandbox policy)
260
290
- Rejecting pending chunks is allowed (does not modify the sandbox policy)
@@ -270,7 +300,7 @@ See [Gateway Settings Channel](gateway-settings.md#global-policy-lifecycle) for
270
300
271
301
When `--full` is specified, the server includes the deserialized `SandboxPolicy` protobuf in the `SandboxPolicyRevision.policy` field (see `crates/openshell-server/src/grpc.rs` -- `policy_record_to_revision()` with `include_policy: true`). The CLI converts this proto back to YAML via `policy_to_yaml()`, which uses a `BTreeMap` for `network_policies` to produce deterministic key ordering. See `crates/openshell-cli/src/run.rs` -- `policy_to_yaml()`, `policy_get()`.
272
302
273
-
See `crates/openshell-cli/src/main.rs` -- `PolicyCommands` enum, `crates/openshell-cli/src/run.rs` -- `policy_set()`, `policy_get()`, `policy_list()`.
0 commit comments