Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
7e24470
feat(sandbox): implement base protocol and dataclasses (T1)
brandwe Jun 18, 2026
f31ad4e
feat(sandbox): implement policy building and clamping (T2)
brandwe Jun 18, 2026
2d89020
feat(sandbox): implement binary resolution and SHA256 verification (T3)
brandwe Jun 18, 2026
9474e7f
feat(sandbox): implement macOS Seatbelt runner and factory (T4)
brandwe Jun 18, 2026
3eba4c0
feat(sandbox): T5 - Add run_code MCP tool
brandwe Jun 18, 2026
4d7650c
feat(sandbox): T6 - Add setup_sandbox.sh script
brandwe Jun 18, 2026
5b9826e
fix(sandbox): Fix platform naming conflict and binary resolution
brandwe Jun 18, 2026
f7f7bf1
docs: Add Claude Code sandbox testing guide
brandwe Jun 18, 2026
d725627
feat(sandbox): T6.5 - Add write_local_file demonstration tool
brandwe Jun 18, 2026
5714657
docs: Add MXC sandbox security demonstration guide
brandwe Jun 18, 2026
10d265e
feat(sandbox): T7 - Add Phase 2 session isolation stub
brandwe Jun 18, 2026
9e14810
docs: T8 - Complete MXC sandbox documentation
brandwe Jun 18, 2026
ccd6089
test(sandbox): T9 - Add adversarial integration tests
brandwe Jun 18, 2026
5e1fa96
test: Add MXC sandbox demonstration scripts
brandwe Jun 18, 2026
fb1f7d2
feat(sandbox): Build real MXC binary from source
brandwe Jun 18, 2026
f89183e
fix(sandbox): harden clamp_to_ceiling with canonicalize-then-containment
brandwe Jun 20, 2026
4873d31
docs: Add upstream feedback note for microsoft/mxc (macOS symlink can…
brandwe Jun 20, 2026
65a5a56
feat(setup): support side-by-side test Agent Identity chains
brandwe Jun 20, 2026
46a6368
demo(sandbox): Add presentation demo script for MXC least-privilege
brandwe Jun 22, 2026
c7c3775
feat(config): honor ENTRABOT_ENV_FILE override in _load_dotenv
brandwe Jun 22, 2026
fd4053d
demo(sandbox): add --config-only mode + fix lint
brandwe Jun 22, 2026
782bda4
fix(demo): re-exec demo_sandbox.py under repo venv
brandwe Jun 22, 2026
1d41701
docs: add MXC sandbox setup HOWTO + README title
brandwe Jun 22, 2026
00eff45
chore: gitignore test/backup MCP configs (.mcp.*.json, .mcp.json.bak.*)
brandwe Jun 22, 2026
3a9ec50
fix(sandbox): gate write_local_file behind ENTRABOT_ENABLE_UNSAFE_WRITE
brandwe Jun 22, 2026
91b60fb
docs(sandbox): document host tool containment (the honesty fix)
brandwe Jun 23, 2026
70f8f70
fix(sandbox): teach the agent run_code is its LOCAL filesystem path
brandwe Jun 23, 2026
b3c6cb6
feat(sandbox): purpose-named read_local_file / write_local_file tools
brandwe Jun 23, 2026
8d24991
docs: point agent + guide at read_local_file/write_local_file
brandwe Jun 23, 2026
0554257
Merge branch 'main' into feat/mxc-sandbox-integration
brandwe Jun 25, 2026
d4ba1fa
fix(cursor): judge cursor staleness by write-time, not message-time
brandwe Jun 27, 2026
1c86554
feat(sandbox): Windows MXC processcontainer integration + local-file fix
brandwe Jun 27, 2026
6dc3a16
fix(mcp): run boot auth off the event loop so MCP handshake stays res…
brandwe Jun 29, 2026
b58dce1
chore(tests): fix pre-existing ruff errors and a flaky scratch-dir test
brandwe Jun 29, 2026
6c07122
fix(sandbox): grant interpreter dirs so Windows write_local_file can …
brandwe Jul 2, 2026
60c8aad
docs(sandbox): add MXC Windows processcontainer upstream-feedback note
brandwe Jul 2, 2026
9b56b6d
chore(demo): add Windows demo launcher, rename fixture to entrabot-in…
brandwe Jul 2, 2026
7bbd463
fix(sandbox): grant parent dir for Windows local reads + one-time DAC…
brandwe Jul 2, 2026
165902a
docs(mxc-feedback): file- vs dir-level read grant + prepare-system-dr…
brandwe Jul 2, 2026
200faf9
fix(hooks): don't report a failed Teams send as "sent"
brandwe Jul 2, 2026
31dc30e
fix(sandbox): tree-kill wxc-exec on timeout so a 30s cap cannot hang …
brandwe Jul 6, 2026
5fbe767
docs(mxc-feedback): Issue 5 - pre-containment wedge with zero ETW eve…
brandwe Jul 6, 2026
3861ace
Merge origin/main: fleet-safe Teams cursor fix (#97) forward-ported
brandwe Jul 6, 2026
ce509d4
docs(mxc-feedback): Issue 5 hardened - wedge is reproducible from lon…
brandwe Jul 6, 2026
ba06200
fix(promises): surface httpx errors with a named type instead of an e…
brandwe Jul 6, 2026
b244138
docs(status): 2026-07-06 handoff - sandbox wedge dossier, cursor fix …
brandwe Jul 6, 2026
1260586
docs(mxc-feedback): Issue 6 - zero ProcessModel ETW for ANY processco…
brandwe Jul 6, 2026
d20c2b4
docs(status): record MXC blocker escalation email sent 2026-07-06
brandwe Jul 6, 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
11 changes: 9 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,8 @@ 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/
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 @@ -17,6 +17,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 @@ -111,11 +123,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