Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
198a99e
feat(sandbox): implement base protocol and dataclasses (T1)
brandwe Jun 18, 2026
7722047
feat(sandbox): implement policy building and clamping (T2)
brandwe Jun 18, 2026
2cfcf2d
feat(sandbox): implement binary resolution and SHA256 verification (T3)
brandwe Jun 18, 2026
c442c4a
feat(sandbox): implement macOS Seatbelt runner and factory (T4)
brandwe Jun 18, 2026
6c2788f
feat(sandbox): T5 - Add run_code MCP tool
brandwe Jun 18, 2026
5435d01
feat(sandbox): T6 - Add setup_sandbox.sh script
brandwe Jun 18, 2026
83ead74
fix(sandbox): Fix platform naming conflict and binary resolution
brandwe Jun 18, 2026
78d8387
docs: Add Claude Code sandbox testing guide
brandwe Jun 18, 2026
f985b72
feat(sandbox): T6.5 - Add write_local_file demonstration tool
brandwe Jun 18, 2026
a7f6df2
docs: Add MXC sandbox security demonstration guide
brandwe Jun 18, 2026
10ebf67
feat(sandbox): T7 - Add Phase 2 session isolation stub
brandwe Jun 18, 2026
3610fc4
docs: T8 - Complete MXC sandbox documentation
brandwe Jun 18, 2026
3e6b9f1
test(sandbox): T9 - Add adversarial integration tests
brandwe Jun 18, 2026
15d6b43
test: Add MXC sandbox demonstration scripts
brandwe Jun 18, 2026
f2ae0fc
feat(sandbox): Build real MXC binary from source
brandwe Jun 18, 2026
a353159
fix(sandbox): harden clamp_to_ceiling with canonicalize-then-containment
brandwe Jun 20, 2026
68b6c3a
docs: Add upstream feedback note for microsoft/mxc (macOS symlink can…
brandwe Jun 20, 2026
bee96c7
feat(setup): support side-by-side test Agent Identity chains
brandwe Jun 20, 2026
9137e3a
demo(sandbox): Add presentation demo script for MXC least-privilege
brandwe Jun 22, 2026
0895753
feat(config): honor ENTRABOT_ENV_FILE override in _load_dotenv
brandwe Jun 22, 2026
f151d43
demo(sandbox): add --config-only mode + fix lint
brandwe Jun 22, 2026
c2bb676
fix(demo): re-exec demo_sandbox.py under repo venv
brandwe Jun 22, 2026
836d565
docs: add MXC sandbox setup HOWTO + README title
brandwe Jun 22, 2026
5062422
chore: gitignore test/backup MCP configs (.mcp.*.json, .mcp.json.bak.*)
brandwe Jun 22, 2026
a2165eb
fix(sandbox): gate write_local_file behind ENTRABOT_ENABLE_UNSAFE_WRITE
brandwe Jun 22, 2026
c07cbc4
docs(sandbox): document host tool containment (the honesty fix)
brandwe Jun 23, 2026
1c95977
fix(sandbox): teach the agent run_code is its LOCAL filesystem path
brandwe Jun 23, 2026
1752693
feat(sandbox): purpose-named read_local_file / write_local_file tools
brandwe Jun 23, 2026
611f38a
docs: point agent + guide at read_local_file/write_local_file
brandwe Jun 23, 2026
87a5276
feat(sandbox): Windows MXC processcontainer integration + local-file fix
brandwe Jun 27, 2026
c17ed6e
fix(mcp): run boot auth off the event loop so MCP handshake stays res…
brandwe Jun 29, 2026
db623f5
chore(tests): fix pre-existing ruff errors and a flaky scratch-dir test
brandwe Jun 29, 2026
352bc4c
fix(sandbox): grant interpreter dirs so Windows write_local_file can …
brandwe Jul 2, 2026
8d8c44e
docs(sandbox): add MXC Windows processcontainer upstream-feedback note
brandwe Jul 2, 2026
4f6e36f
chore(demo): add Windows demo launcher, rename fixture to entrabot-in…
brandwe Jul 2, 2026
922c1e5
fix(sandbox): grant parent dir for Windows local reads + one-time DAC…
brandwe Jul 2, 2026
a4e15ee
docs(mxc-feedback): file- vs dir-level read grant + prepare-system-dr…
brandwe Jul 2, 2026
d611353
fix(hooks): don't report a failed Teams send as "sent"
brandwe Jul 2, 2026
13f3c5a
fix(sandbox): tree-kill wxc-exec on timeout so a 30s cap cannot hang …
brandwe Jul 6, 2026
74ceb49
docs(mxc-feedback): Issue 5 - pre-containment wedge with zero ETW eve…
brandwe Jul 6, 2026
644a120
docs(mxc-feedback): Issue 5 hardened - wedge is reproducible from lon…
brandwe Jul 6, 2026
329d56a
fix(promises): surface httpx errors with a named type instead of an e…
brandwe Jul 6, 2026
6d83af4
docs(status): 2026-07-06 handoff - sandbox wedge dossier, cursor fix …
brandwe Jul 6, 2026
6e71ae5
docs(mxc-feedback): Issue 6 - zero ProcessModel ETW for ANY processco…
brandwe Jul 6, 2026
5aff056
docs(status): record MXC blocker escalation email sent 2026-07-06
brandwe Jul 6, 2026
6496910
chore: ignore local uv lockfile
brandwe Jul 10, 2026
b323dde
fix(sandbox): canonicalize with host path semantics
brandwe Jul 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
"hooks": [
{
"type": "command",
"command": "echo '{\"hookSpecificOutput\":{\"hookEventName\":\"PostToolUse\",\"additionalContext\":\"Teams message sent. The background channel will push any replies automatically — no need to call watch_teams_replies unless you want to block and wait.\"}}'",
"command": "python3 scripts/hooks/report_teams_send.py",
"timeout": 5
}
]
Expand Down
12 changes: 10 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ venv/
.mypy_cache/
.pyright/
.openclaw-state.json
.entrabot-state.json
.entrabot-state.json.bak.*
.entrabot-state*.json
.entrabot-state*.json.bak.*
.mcp.json
.mcp.json.bak.*
.mcp.*.json
a365.config.json
a365.generated.config.json
ToolingManifest.json
Expand Down Expand Up @@ -51,3 +53,9 @@ pip.ini
docs/runbooks/session-*.md
docs/superpowers/
.entraclaw-state.json
.mxc-build/mxc-src/
# MXC Windows SDK fetched on demand by scripts/setup_sandbox.ps1 (large; the
# pinned SHA256 in src/entrabot/sandbox/binary.py is the trust anchor, not the
# committed bytes).
.mxc-build/npm/
uv.lock
31 changes: 31 additions & 0 deletions .mxc-build/target/release/.mxc-exec-mac.mock
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env bash
# Test MXC mock - executes commands for testing entrabot plumbing
# Mimics MXC 0.6.0-alpha schema

# Read MXC config from stdin (JSON)
if [ -t 0 ]; then
CONFIG="{}"
else
CONFIG=$(cat)
fi

# Extract command from MXC schema: process.commandLine
COMMAND=$(echo "$CONFIG" | python3 -c "
import json, sys
try:
c = json.load(sys.stdin)
print(c.get('process', {}).get('commandLine', ''))
except:
print('')
" 2>/dev/null || echo "")

if [ -z "$COMMAND" ]; then
echo '{"error": "No command specified in process.commandLine"}' >&2
exit 1
fi

# Execute with timeout (real MXC would apply sandboxing)
timeout 30s bash -c "$COMMAND" 2>&1
EXIT_CODE=$?

exit $EXIT_CODE
Binary file added .mxc-build/target/release/mxc-exec-mac
Binary file not shown.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Entrabot: Identity Research for Microsoft 365 Agents
# Entrabot: Identity Research for Microsoft 365 Agents using Autopilot


Entrabot is a Python MCP server that gives a device-local agent its own Entra **Agent ID** and an **Agent User** that has all the capabilities of a human user in a Microsoft tenant. It can have a Teams presence and be invited to meetings to chat with your colleagues 1:1, a mailbox it can monitor and respond to, create and edit Word documents, make PowerPoint presentations, and allows you to access your CLI. The agent signs in autonomously, sends Teams messages from its own account, and writes audit events against its own object ID. It runs on macOS, Linux, and Windows, and works with Claude Code, Copilot CLI, or any MCP-speaking client.
Expand Down Expand Up @@ -35,6 +35,7 @@ entrabot is the device-side glue for a set of platform primitives Microsoft ship

- **Entra Agent ID** — the four-object hierarchy: Agent Identity Blueprint → BlueprintPrincipal → Agent Identity → Agent User. Confidential clients only; no public-client flows; tokens carry `idtyp=user` for the Agent User leaf. ([platform learning](docs/platform-learnings/agent-id-blueprints-and-users.md))
- **Microsoft Agent 365** — the control plane: admin-center inventory, OTel observability, Work IQ MCP servers (Mail, Calendar, Teams, SharePoint, OneDrive, Word, User, Copilot, Dataverse), AI-teammate lifecycle. GA 2026-05-01. ([platform learning](docs/platform-learnings/microsoft-agent-365.md))
- **MXC Sandbox** — OS-enforced containment for local code execution. Process-level isolation with positive-allowlist filesystem access, network blocking, and operator-set capability ceilings. Opt-in `run_code` tool (disabled by default). Phase 1 ships macOS Seatbelt; Windows AppContainer and Linux seccomp-bpf coming next. Phase 2 will bind sessions to Agent User identity for M365 audit attribution. ([setup guide](docs/guides/mxc-sandbox.md) · [ADR-007](docs/decisions/007-mxc-sandbox-integration.md))
- **Conditional Access for agents** — GA. Apply CA policies to Agent Identity sign-ins the same way you apply them to users.
- **ID Protection for agents** — GA. Risk scoring and remediation against the agent's own object.
- **FastMCP** — the Python MCP server framework. entrabot registers every Teams, Outlook, Files, Word, audit, and identity tool through it.
Expand Down Expand Up @@ -96,7 +97,7 @@ source .venv/bin/activate
claude --dangerously-load-development-channels server:entrabot
```

`setup.sh` is idempotent. It provisions the Blueprint, BlueprintPrincipal, Agent Identity, and Agent User; assigns a Teams-capable license; uploads a self-signed certificate to Entra; and writes `.env` plus `.mcp.json` with no secrets on disk. Full walkthrough — including Windows, cloud memory, cross-tenant group chats, and the Work IQ Word setup — is in [`docs/getting-started/quickstart.md`](docs/getting-started/quickstart.md) and [`INSTALL.md`](INSTALL.md).
`setup.sh` is idempotent. It provisions the Blueprint, BlueprintPrincipal, Agent Identity, and Agent User; assigns a Teams-capable license; uploads a self-signed certificate to Entra; and writes `.env` plus `.mcp.json` with no secrets on disk. Add `--use-cloud-memory` to enable Azure Blob storage for operational state, or `--enable-sandbox` to provision MXC sandbox for contained local code execution (opt-in, disabled by default; full walkthrough in the [MXC sandbox setup guide](docs/guides/mxc-sandbox.md)). Full walkthrough — including Windows, cloud memory, cross-tenant group chats, and the Work IQ Word setup — is in [`docs/getting-started/quickstart.md`](docs/getting-started/quickstart.md) and [`INSTALL.md`](INSTALL.md).

### Launching the agent

Expand Down Expand Up @@ -146,6 +147,7 @@ The full doc site: **<https://microsoft.github.io/entrabot/>**
Direct pointers:

- [Quickstart](docs/getting-started/quickstart.md) — five minutes from clone to first Teams message
- [MXC sandbox setup](docs/guides/mxc-sandbox.md) — enable contained local code execution (`run_code`): build the binary, set the operator ceiling, verify kernel enforcement
- [MCP tool reference](docs/reference/mcp-tools.md) — every tool, every parameter
- [Setup script reference](docs/reference/setup-script.md) — every `setup.sh` flag
- [Script reference](docs/reference/scripts/operations.md) — status, health, DM, email, setup, teardown, and diagnostic scripts
Expand Down
20 changes: 16 additions & 4 deletions TODOS.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,18 @@ Claude Code v2.1.152 now does MCP OAuth 2.1 discovery and ignores `.mcp.json` `h

## P1

### Cache the Agent User storage token — every blob op re-runs the three-hop flow synchronously on the event loop
`_ConditionalBlobAdapter` (promises path) passes `token_provider=lambda: acquire_agent_user_storage_token(...)` with no caching (`src/entrabot/tools/promises.py:163`), so each blob GET/PUT pays up to three blocking HTTPS token round-trips on the asyncio loop — a `resolve_promise` can cost ~8 sequential requests, each a timeout opportunity, and each blocks the loop (same anti-pattern Learning #69 fixed at boot). A short-TTL storage-token cache would cut the failure surface and the loop stalls.

- **Effort:** S–M
- **Source:** resolve_promise empty-error investigation, 2026-07-06 (sub-agent report; fix for the error *surfacing* shipped separately — this is the amplifier).

### Investigate chronic connectivity degradation of the MCP server process
The rotating server log holds **644** empty-message `ConnectTimeout`/`getaddrinfo` warnings (102 on 2026-07-06 alone, starting ~18:52Z) hitting cursor saves, chat bootstraps, and email polls, while cached-token Teams Graph calls kept working. Suspects: Parallels VM pauses (multi-minute `SystemTimeChange` jumps from `prl_tools.exe`), per-call token acquisition (see above), and/or the open MCP-disconnect dossier (`docs/runbooks/mcp-disconnect-investigation.md`) — read that runbook first, do not restart the investigation from scratch.

- **Effort:** M (instrumentation-first)
- **Source:** 2026-07-06 session — the degradation window is what made `resolve_promise` fail 4/4 while `add_promise` (called earlier) succeeded.

### Follow-up: two-phase sponsor confirmation flow for mutating tools
The active-sponsor-channel binding shipped in PR `fix/msrc-active-sponsor-channel-binding` closes Chain A from the security confused-deputy report (attacker in low-priv chat manipulating action on a chat where sponsor is passive) but does NOT close the residual window where a sponsor IS actively engaged in the target chat. An attacker who gets a sponsor to read an injected SharePoint doc (Chain B) can still trigger a malicious `add_member` / `share_file` because all binding checks pass.

Expand Down Expand Up @@ -128,11 +140,11 @@ Two bugs, both observed at 2026-04-17T17:00:00 PDT (= 00:00:01 UTC 2026-04-18):
### ~~Token auto-refresh in teams_send~~ ✅ DONE
Implemented as `_with_token_retry()` in `mcp_server.py` and `_ensure_valid_token()` (proactive refresh at 55 min). All tools use it.

### AppContainer sandbox production implementation
Tonight's spike proves feasibility. Production version needs: filesystem allowlist, network filtering (Graph API only), process spawn restrictions, MCP server integration. May require Win32 C extension from Python.
- **Effort:** L (CC: ~1-2 days)
- **Depends on:** AppContainer spike results
### ~~AppContainer sandbox production implementation~~ ✅ DONE (MXC sandbox integration)
**Shipped as MXC sandbox integration (Issue #84, ADR-007).** Phase 1 complete: process-level containment via MXC 0.6.0-alpha (macOS Seatbelt). Positive-allowlist filesystem, network blocking, operator ceiling enforcement, binary SHA256 verification, opt-in `run_code` tool. The macOS mock binary was retired on 2026-06-18 and replaced with a real `mxc-exec-mac` built from `microsoft/mxc` v0.6.1 plus the repo-local stdin compatibility patch in `scripts/mxc-mac-stdin-compat.patch`. Phase 2 stub (session-bound Entra identity attribution) ready for future APIs. Windows AppContainer + Linux seccomp-bpf deferred to T4/T10.
- **Status:** Phase 1 shipped (1605 tests passing), Phase 2 stub in place
- **Source:** CEO review, refined premise (sandbox co-equal with identity)
- **See:** `docs/decisions/007-mxc-sandbox-integration.md`, `docs/architecture/DESIGN-mxc-sandbox.md`

## P2

Expand Down
Loading
Loading