Skip to main content

Safe, auditable MSP workflow automation CLI for Microsoft 365 operations.

Project description

msp-copilot

Audit-grade workflow engine with approvals + traceability | Pilot-ready on a sandbox tenant | Architecture won't collapse when we swap mocks → real Graph

CLI quickstart

Install

pip install msp-copilot

From source checkout:

pip install .

Configure

Create a .env file (or set env vars in your shell):

# Required for real Graph runs (optional for mock/dry-run)
MSP_GRAPH_CLIENT_ID="..."
MSP_GRAPH_TENANT_ID="..."

# Safety: execution is OFF by default
MSP_EXECUTION_ENABLED="false"

# Optional: tenant aliases (tickets can use alias instead of GUID)
MSP_TENANT_ALIAS_cryingman-dev="67aca8ef-69a4-4853-9045-d4c345601d6e"

Introspection commands (no auth / safe)

Explain a workflow:

msp-copilot explain offboarding

Validate a ticket (schema + guardrails only):

msp-copilot validate --ticket data/tickets/offboard_001.json

Preview a plan:

msp-copilot plan --ticket data/tickets/offboard_001.json
msp-copilot plan --ticket data/tickets/offboard_001.json --approve remove_licenses,convert_mailbox

Doctor checks (operator readiness):

msp-copilot doctor --tenant cryingman-dev --test-user john.doe@example.com
msp-copilot doctor --json

Live gauntlet (10-scenario operator check):

make test-live

Notes:

  • Loads .env automatically when present
  • Stores artifacts under data/live_runs/<utc-timestamp>/
  • Scenario output logs: data/live_runs/<utc-timestamp>/scenarios/
  • New run-log snapshot: data/live_runs/<utc-timestamp>/run_logs/
  • Run metadata: data/live_runs/<utc-timestamp>/meta.json (commit/version/python/os/redacted env flags)
  • Set LIVE_GAUNTLET_USE_REAL=1 to keep real Graph credentials instead of forced mock mode

Running workflows

Dry-run (default-safe):

msp-copilot run --ticket data/tickets/offboard_001.json --operator you

Execute (requires kill switch enabled):

MSP_EXECUTION_ENABLED=true \
msp-copilot run --ticket data/tickets/offboard_001.json --execute --operator you

Execute with approvals:

MSP_EXECUTION_ENABLED=true \
msp-copilot run --ticket data/tickets/offboard_001.json --execute \
  --approve remove_licenses,convert_mailbox \
  --operator you

Last run:

msp-copilot last-run

Operator configuration

License removal configuration:

{
  "ticket_id": "offboard_001",
  "type": "offboarding",
  "tenant_id": "cryingman-dev",
  "user_email": "john.doe@contoso.com",
  "remove_sku_ids": [
    "6fd2c87f-b296-42f0-b197-1e91e994b900"
  ]
}

or fallback defaults via env:

MSP_DEFAULT_REMOVE_SKU_IDS="6fd2c87f-b296-42f0-b197-1e91e994b900,another-sku-guid"

Rules:

  • remove_sku_ids must be explicit (ticket or env fallback)
  • Empty remove list fails the remove_licenses step
  • Only targeted SKUs are removed
  • Compensation payload is logged in run evidence

Exchange Online mode:

MSP_EXCHANGE_REAL=true
MSP_EXECUTION_ENABLED=true

Behavior:

  • Uses pwsh subprocess commands for mailbox conversion
  • Skips conversion when mailbox is already SharedMailbox
  • Captures sanitized command output and timing in evidence
  • convert_mailbox still requires explicit approval

Group diff workflow

Config:

# Groups you allow the engine to manage (required for managed_only)
MSP_MANAGED_GROUP_IDS="guid1,guid2,guid3"

# Groups that must NEVER be removed
MSP_PROTECTED_GROUP_IDS="guidX,guidY"

# Safety cap on removals
MSP_GROUP_REMOVE_MAX="10"

Run (safe defaults):

msp-copilot plan --ticket data/tickets/group_diff_001.json
msp-copilot run  --ticket data/tickets/group_diff_001.json --operator you

Approve removals (if needed):

MSP_EXECUTION_ENABLED=true \
msp-copilot run --ticket data/tickets/group_diff_001.json --execute \
  --approve group_diff_apply \
  --operator you

Behavior rules:

  • desired_group_ids must be non-empty
  • In managed_only, only groups in MSP_MANAGED_GROUP_IDS are enforced
  • Removals are blocked unless --approve group_diff_apply is provided
  • Protected groups are never removed
  • Removal cap prevents large accidental group removals

Note:

  • plan does not compute to_add/to_remove counts yet; those are computed at execution precheck time

Notes / behavior guarantees

  • --execute is blocked unless MSP_EXECUTION_ENABLED=true
  • Tenant and user guardrails run before any write steps
  • Approval-required actions block unless explicitly approved
  • Run logs are schema-validated, redacted, and versioned (run_schema_version: 1)

Deployment

One-page deploy guide: DEPLOYMENT.md

Current State

What you can claim right now:

  • Per-step audit trail with unique run_id (UUID v4)
  • Approval gating for risky operations
  • Real-time status tracking (planned → completed/blocked/failed/skipped)
  • Enterprise audit logs: data/runs/run_<timestamp>.json
  • Timestamps with millisecond precision (ISO 8601 UTC)
  • Operator tracking via MSP_OPERATOR_EMAIL environment variable
  • Architecture validated: swapping MockGraphOperations → real Graph API won't break the core engine

Why "pilot-ready":

  • All core workflows tested and working (dry-run, execute, approval gates)
  • Mock Graph API provides realistic 50ms latency per operation
  • Audit logs capture everything needed for compliance review
  • Run logs include: run_id, started_at, completed_at, duration_seconds, all step timings, approval tracking

Why NOT "production-ready":

  • Still using mock Graph API (no real Microsoft 365 connectivity)
  • No real OAuth authentication (we fake the login)
  • No idempotency protection (reruns could conflict)
  • Secrets still in .env (should be in keyring/vault)
  • No cross-tenant isolation checks

Enterprise Gates

See ENTERPRISE_ROADMAP.md for detailed implementation paths. The critical blockers for production:

  1. Real Microsoft 365 Auth + Tenant Isolation ← Next priority (MSAL-based OAuth)
  2. Idempotency + Safe Retries (SQLite store, retry policy)
  3. Secrets Management + Token Redaction (keyring, log scrubbing)

Documentation

  • ENTERPRISE_ROADMAP.md — 6 production-readiness gates with code examples
  • QUICK_WINS.md — 4 improvements just implemented (validation, run_id, timestamps, actor tracking)
  • NEXT_STEPS.md — 30-day sprint plan + decision framework

Architecture

Domain-driven: Ticket → Planner → Plan → Executor → RunResult + Auditor

Connectors: Microsoft Graph (mocked, real auth coming next)

Storage: JSON run logs + future SQLite (idempotency, audit)

CLI: Argparse with --ticket, --execute, --approve flags

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

msp_copilot-0.1.1.tar.gz (46.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

msp_copilot-0.1.1-py3-none-any.whl (36.0 kB view details)

Uploaded Python 3

File details

Details for the file msp_copilot-0.1.1.tar.gz.

File metadata

  • Download URL: msp_copilot-0.1.1.tar.gz
  • Upload date:
  • Size: 46.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for msp_copilot-0.1.1.tar.gz
Algorithm Hash digest
SHA256 6f19c0a64c13d515f04b3e316f94fc1ba64ba6f68cf439b57e089562c244eff5
MD5 70e392dc9e21d0dfb96c476ba5d7f872
BLAKE2b-256 ba6f0c26fd6ddbe7f8ff56bda8c23d2072ae5d36724a45d1b0ff0afcd2156537

See more details on using hashes here.

File details

Details for the file msp_copilot-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: msp_copilot-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 36.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for msp_copilot-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 21d62e801b99954f78d25b2c8ba810b439bf44acd69b4de8ed544480a3b2d953
MD5 d45f214da56d8d44c0cbc73b9f2a7dcf
BLAKE2b-256 823f9f51cce0fbb614138646d1dbc190bb997fdc5e58378f2e8aa38fec67785e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page