Repository navigation
[Seatbelt] Proposal: Learning Mode - #1609
Conversation
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved design gaps can hide capture-failure details during SDK timeouts, leave workloads running after abrupt MXC exit, and retain reports without exposing their paths to callers.
3 open issues
What changed in this PR
This documentation-only PR proposes Seatbelt denial capture for macOS, extending MXC’s existing ProcessContainer learning workflow. It defines the feature and API contracts ahead of implementation for #1591.
Changes:
- Defines block and allow modes, report formats, collection limits, and cleanup behavior.
- Plans compatible Rust, .NET, and Node APIs after contract
1.1.0publication. - Specifies staged delivery, macOS validation, and documentation updates.
| File | Description |
|---|---|
docs/development/architecture/designs/1591-seatbelt-learning-mode/README.md |
Defines feature behavior, security, ownership, and delivery plans. |
docs/development/architecture/designs/1591-seatbelt-learning-mode/api.md |
Proposes SDK types, request mapping, compatibility, and validation. |
Review effort: Balanced
Gudge (MGudgin)
left a comment
There was a problem hiding this comment.
Focused follow-up on the proposal's network example. Verified the current PR diff against GitHub and checked Seatbelt's declared network support in seatbelt_runner.rs:270-280 and the existing backend guide's network field table. This is a specification correction, not a reported runtime regression.
Verified pre-existing issues attributed to this PR: none. Seatbelt's existing lack of remote-port rules is not itself a defect; the finding concerns the new example's claim. The other three findings already have review threads and are not duplicated here.
| ## Inputs, results, and SDK differences | ||
|
|
||
| - **`mode`, `outputPath`:** see the | ||
| [field table](README.md#proposed-behavior). Omitting `captureDenials` | ||
| (`None` / `null` / `undefined`) disables capture. | ||
| - **`retainEtl`:** for Seatbelt, keeps the run's `.seatbelt.log`. Default | ||
| `false`. | ||
| - **SDK target still `1.0.0`:** a Seatbelt `captureDenials` value is rejected | ||
| with the same errors. Errors: | ||
| - Rust: `MxcError` with `ErrorCode::MalformedRequest`. | ||
| - .NET: `ArgumentException`. | ||
| - Node: `MxcError` with code `malformed_request`. | ||
| - **Results:** use the existing `CaptureDenialsResult`. For Seatbelt, | ||
| `etlPath` holds the `.seatbelt.log` path when retained, and | ||
| `captureDenialsError` is never set. Capture failures come back as run or | ||
| wait errors. When the run also times out, the capture failure is in the | ||
| process warnings. | ||
| - **Caller cleanup:** yes. Delete `outputPath`, its `.verbose.json` sibling, | ||
| and any `etlPath` file when done. | ||
| - **Discovery:** `v1::available_backends()` / `MxcPlatform.GetAvailableBackends` / | ||
| `getAvailableBackends()` list `captureDenials` for `seatbelt`. The type and | ||
| value already exist. See | ||
| [backend availability](README.md#backend-applicability-and-availability) | ||
| for what discovery can't detect. | ||
| - **SDK differences:** No. |
There was a problem hiding this comment.
thought: perhaps I should update this section but it would be a bit more clearer if we had a table for inputs and results separated.
| - macOS callers can't tell which permissions a sandboxed workload needs. When | ||
| a Seatbelt run fails, the only evidence is the workload's own error output. | ||
| Windows ProcessContainer already solves this with `captureDenials`. | ||
| - This adds `seatbelt.captureDenials`. MXC records the accesses the policy | ||
| did not grant and writes a report in the | ||
| [Windows report format](../../../../logging-access-denied.md#output-file-the-caller-consumes). |
There was a problem hiding this comment.
question: to confirm, do all versions of seatbelt have this capability?
There was a problem hiding this comment.
I'd be very surprised if it isn't 10+ years old, but I'll double check.
| - `docs/development/architecture/versioning.md`: the V2 rename of `retainEtl` | ||
| and `etlPath`. |
There was a problem hiding this comment.
issue: I thought above we said that we wouldn't do the breaking change in this feature? Or was this left over after updating the spec?
There was a problem hiding this comment.
Not implemented in this spec - will be tracked in a separate issue tagged V2.0.
Gudge (MGudgin)
left a comment
There was a problem hiding this comment.
Approved the current spec revision (47d9b596806cb3414cb6fedaddcccb4a888c76a0). The four prior findings are addressed in the proposal: timeout capture failures are exposed through process warnings; report files are removed on termination failure; the abrupt-exit text now acknowledges workloads can survive MXC while the collector exits; and the network example no longer implies Seatbelt can grant only remote port 443. The surviving-workload limitation is documented, not fixed by this proposal. This PR changes specifications only; implementation and macOS runtime validation remain planned for follow-up work.

macOS callers can't tell which permissions a sandboxed workload needs. When a Seatbelt run fails, the only evidence is the workload's own error output. Windows ProcessContainer already solves this with
captureDenials.This spec adds
seatbelt.captureDenials. MXC records the accesses the policy did not grant and writes reports.Proposal README: docs/development/architecture/designs/1591-seatbelt-learning-mode/README.md
Proposal api.md: docs/development/architecture/designs/1591-seatbelt-learning-mode/api.md
Microsoft Reviewers: Open in CodeFlow