Skip to content

Repository files navigation

M365 Toolbox

M365 Toolbox is a web-based console for approved Microsoft 365 PowerShell operations. It combines a React frontend, an Express API, a Redis-backed BullMQ queue, a PostgreSQL-backed run store, a dedicated PowerShell worker, and a toolbox-native script catalog so admins can launch reports and response workflows from the browser, authenticate with Microsoft device code, and review results without leaving the app.

What the project does

  • Presents a categorized script catalog for Microsoft 365 operations
  • Runs allowlisted PowerShell scripts through a controlled backend wrapper
  • Requires sign-in with local Toolbox users or Microsoft Entra ID
  • Enforces role-based authorization for administrators, privileged users, and restricted users
  • Prompts for Microsoft device-code sign-in when a script requires authentication
  • Tracks run status, command details, stdout, stderr, exit code, and artifacts
  • Renders HTML reports inline in the UI and supports direct download
  • Stores favorites in the browser for faster access to common workflows

The current catalog includes 59 toolbox-native scripts across categories such as Identity, Exchange, Security, SharePoint, Teams, Reporting, Licensing, Devices, Operations, Collaboration, and Incident Response.

Project layout

  • backend/ Express API, queue integration, run tracking, artifact endpoints, and worker health reporting
  • frontend/ React/Vite UI with the resizable sidebar, category icons, dark mode, favorites, dashboard shortcuts, run details, and inline report preview
  • scripts/ Toolbox-native PowerShell scripts, the script wrapper, and shared report helpers
  • scripts/catalog/ JSON catalog files that define script metadata, fields, risk, and runner behavior
  • output/ Generated report artifacts written by backend runs
  • docker-compose.yml Single Docker Compose deployment for local and self-hosted use, including PostgreSQL, Redis, a one-shot migration job, the backend, the PowerShell worker, and the frontend
  • .env.example Example environment file for self-hosted deployments

Current capabilities

  • Resizable left sidebar for the script catalog
  • Search and category browsing in the catalog
  • Category icons in the sidebar for faster scanning
  • Read-only versus remediation mode labeling and filtering
  • Favorites toggle and favorites-only filtering
  • Dark mode toggle
  • Better dashboard home screen with quick stats and shortcuts
  • Recent favorites and most-used shortcuts on the dashboard
  • Persistent run history in the UI
  • Queue-aware execution with queued run status
  • Run cancellation from the UI
  • Structured run logs, timestamps, and clearer run-state feedback
  • Artifact browser for HTML, CSV, XLSX, text, and log downloads
  • ZIP bundle download for full run artifact packages
  • Inline HTML report preview after successful runs, with the report brought into focus automatically
  • Device-code modal that surfaces the sign-in code, copy action, and login URL
  • Approval confirmation prompt for remediation workflows
  • Action profiles and high-impact action guidance for the compromised-account workflow
  • Backend status view for Redis, queue, worker heartbeat, script mount, and output path readiness
  • GitHub repository link in the sidebar footer

Current script catalog

Core workflows and reporting:

  • scripts/M365-CompromisedAccountRemediation.ps1 Contains and investigates compromised accounts with review-only and containment profiles, recent sign-in review, optional delegate cleanup and protocol lock-down, and a richer incident dashboard.
  • scripts/M365-MfaReport.ps1 Builds a tenant-wide MFA coverage report with admin-risk visibility.
  • scripts/M365-UsageReport.ps1 Creates OneDrive, SharePoint, and mailbox usage dashboards.
  • scripts/M365-LicensingReport.ps1 Reviews subscribed SKUs, assigned licenses, and unlicensed users.
  • scripts/M365-GuestAccessReport.ps1 Audits guest accounts, invitation state, stale guests, and external domains.
  • scripts/M365-ConditionalAccessReport.ps1 Summarizes Conditional Access policies, state, scope, and grant controls.
  • scripts/M365-MailForwardingAudit.ps1 Finds mailbox forwarding and inbox rules that redirect mail.
  • scripts/M365-SharedMailboxReport.ps1 Reviews shared mailboxes, forwarding, visibility, and delegate counts.
  • scripts/M365-ImapMigrationPreflight.ps1 Validates mounted IMAP migration CSV readiness, Exchange Online sign-in, and source IMAP endpoint availability.
  • scripts/M365-ImapMigrationBatch.ps1 Creates or reuses an Exchange Online IMAP migration endpoint, creates a migration batch from CSVData, and can optionally start it.
  • scripts/M365-ImapMigrationStatus.ps1 Exports current Exchange Online migration batch summary and per-user migration status.
  • scripts/M365-SignInRiskReport.ps1 Shows risky users and detections when Identity Protection data is licensed and available.
  • scripts/M365-TeamsExternalAccessReport.ps1 Reviews Teams guest exposure, ownership gaps, and external membership.
  • scripts/M365-SharePointSharingReport.ps1 Combines SharePoint tenant sharing settings with site usage inventory.
  • scripts/M365-SecureScoreSnapshot.ps1 Captures the latest Secure Score snapshot and top improvement controls.
  • scripts/M365-AdminRoleAudit.ps1 Audits privileged role assignments and MFA hygiene for admin accounts.

Audit, hygiene, and operations reports:

  • scripts/M365-InactiveUsersReport.ps1 Identifies inactive accounts and likely license-reclaim candidates.
  • scripts/M365-AppConsentAudit.ps1 Reviews enterprise app consent grants and high-privilege delegated scopes.
  • scripts/M365-MailboxPermissionAudit.ps1 Audits Full Access and Send As delegation across mailboxes.
  • scripts/M365-ExternalSharingLinksReport.ps1 Reviews SharePoint external sharing posture and site-level sharing link counts.
  • scripts/M365-DistributionGroupAudit.ps1 Audits distribution group ownership, membership, and external sender exposure.
  • scripts/M365-ServiceHealthSnapshot.ps1 Captures current Microsoft 365 service health and active advisories.
  • scripts/M365-AuthenticationPolicyReport.ps1 Reviews security defaults and authentication methods policy posture.
  • scripts/M365-PrivilegedAppAudit.ps1 Inventories service principal credentials and non-human identity exposure.
  • scripts/M365-DkimDmarcReport.ps1 Reviews accepted domains for DKIM signing and DMARC presence.
  • scripts/M365-GroupLifecycleReport.ps1 Audits Microsoft 365 group ownership, renewal activity, and lifecycle hygiene.

Latest additions:

  • scripts/M365-CAPolicyCoverageReport.ps1 Maps Conditional Access inclusion and exclusion coverage across users, groups, guests, and apps.
  • scripts/M365-LegacyAuthExposureReport.ps1 Surfaces recent legacy-authentication sign-ins and affected users.
  • scripts/M365-PIMRoleActivationReport.ps1 Reviews active and eligible privileged role schedule instances from Entra ID.
  • scripts/M365-DeviceComplianceSnapshot.ps1 Summarizes Intune-managed device compliance, ownership, and platform mix.
  • scripts/M365-B2BDirectConnectReport.ps1 Reviews cross-tenant access defaults and B2B direct connect posture.
  • scripts/M365-MailTransportRulesAudit.ps1 Audits Exchange Online mail transport rules and test/audit mode coverage.
  • scripts/M365-DefenderIncidentSnapshot.ps1 Captures current Defender incidents, severity, and status.
  • scripts/M365-PrivilegedGroupAudit.ps1 Reviews sensitive groups for owner gaps and membership exposure.
  • scripts/M365-PasswordResetReadinessReport.ps1 Estimates self-service password reset readiness from registered auth methods.
  • scripts/M365-OneDriveExternalSharingReport.ps1 Reviews OneDrive usage and highlights large or highly active personal sites.
  • scripts/M365-MFARegistrationCampaignReport.ps1 Reviews MFA registration campaign settings and rollout posture.
  • scripts/M365-EnterpriseAppsInventory.ps1 Inventories enterprise applications for ownership, visibility, and risk review.
  • scripts/M365-GuestInvitationFailures.ps1 Surfaces guest invitation issues and onboarding failures for follow-up.
  • scripts/M365-MailboxAutoReplyAudit.ps1 Reviews mailbox automatic replies for external exposure and operational awareness.
  • scripts/M365-CalendarSharingAudit.ps1 Audits mailbox calendar sharing posture and external visibility.
  • scripts/M365-RoleEligibleAssignmentsReport.ps1 Reviews eligible privileged role assignments and standing access exposure.
  • scripts/M365-AnonymousLinkExposureReport.ps1 Highlights anonymous sharing links and externally accessible content exposure.
  • scripts/M365-TeamsOwnershipAudit.ps1 Reviews Microsoft Teams ownership gaps and governance hygiene.
  • scripts/M365-AppCredentialExpiryReport.ps1 Finds expiring or stale application credentials that need rotation.
  • scripts/M365-MailflowConnectorAudit.ps1 Reviews inbound and outbound Exchange Online connectors, relay paths, and TLS posture.
  • scripts/M365-BreakGlassAccountAudit.ps1 Reviews emergency access accounts for privilege, MFA, and recent sign-in visibility.
  • scripts/M365-ImpossibleTravelReview.ps1 Highlights rapid country-to-country sign-in changes for the same user.
  • scripts/M365-MailboxLoginAnomalyReview.ps1 Reviews mailbox-related sign-ins with suspicious client, failure, or access patterns.
  • scripts/M365-ExternalTenantTrustReview.ps1 Summarizes cross-tenant partner trust settings and guest domain concentration.
  • scripts/M365-PrivilegedUserSignInReview.ps1 Reviews recent sign-in visibility for privileged users across directory roles.
  • scripts/M365-InboxRuleThreatHunt.ps1 Hunts for suspicious inbox rules that forward, redirect, hide, or delete messages.
  • scripts/M365-ConditionalAccessGapReview.ps1 Highlights Conditional Access policies with exclusions, missing controls, or weak enforcement.
  • scripts/M365-MFAExclusionAudit.ps1 Audits MFA-enforcing policies that still exclude users, groups, or roles.
  • scripts/M365-DormantAdminAccountReview.ps1 Finds privileged accounts with little or no recent sign-in activity.
  • scripts/M365-SharedMailboxAbuseReview.ps1 Reviews shared mailboxes for forwarding, risky delegates, and inbox rule abuse signals.
  • scripts/M365-TransportRuleThreatHunt.ps1 Flags transport rules with redirect, bypass, delete, or routing threat signals.
  • scripts/M365-BreakGlassAccountHardeningReview.ps1 Reviews likely break-glass accounts for MFA, state, and hardening posture.
  • scripts/M365-OAuthAppRiskReview.ps1 Highlights OAuth-enabled apps with delegated grants, risky scopes, and credential risk.

The catalog loader lives in backend/src/data/scripts.js, the catalog source files live in scripts/catalog, and the PowerShell entry scripts live in scripts.

Runtime model

The backend loads script metadata from the JSON catalog, accepts validated run requests, persists queued run records in PostgreSQL, and hands execution to BullMQ. A separate PowerShell worker container reads queued jobs, launches scripts/Invoke-ToolboxScript.ps1, captures structured events and artifacts, and writes incremental logs, artifacts, approvals, and result metadata back to PostgreSQL while keeping report files in output/.

The backend tracks:

  • selected script id
  • generated command line
  • stdout
  • stderr
  • structured log entries
  • run status
  • queued, running, canceling, completed, failed, canceled, and interrupted lifecycle states
  • exit code
  • timestamps
  • artifact inventory for exported files

Company tenant settings

The Settings page can store reusable company mappings in PostgreSQL. Administrators add a Company Name and a Tenant ID or Domain, then operators type either the company name, tenant id, or domain in a script tenant field to resolve it before launch.

Company mappings can be imported or exported as CSV. Use two columns:

Company Name,Tenant ID or Domain
Contoso,contoso.onmicrosoft.com
Fabrikam,fabrikam.com
Northwind,00000000-0000-0000-0000-000000000000

The header row is optional but recommended. If a company name contains a comma, wrap it in quotes, for example "Contoso, Ltd.",contoso.onmicrosoft.com.

Authentication and roles

M365 Toolbox shows a login page before the app shell. The backend creates a local administrator on startup if it does not already exist:

  • username: admin
  • password: admin
  • role: administrator

The password is stored as a bcrypt hash, and the default account is marked for password change. After first login, open Settings and change the password before using the toolbox for production work. Existing admin accounts are never overwritten or reset by startup.

Roles are enforced by the backend:

  • administrator: can run every script, edit company mappings, edit authentication settings, manage local users, assign user roles, and manage Microsoft group role mappings.
  • privileged_user: can run every script, but cannot edit administrator-only settings.
  • restricted_user: can run only non-remediation scripts. Remediation and high-impact workflows are blocked with 403 even if called directly through the API.

Local users authenticate with the username and password stored in PostgreSQL. Administrators can manage local users from Settings → Users, including creating users, editing profile details, assigning roles, resetting local passwords, and removing users. The app prevents administrators from removing their own signed-in account or leaving the toolbox without another administrator. Microsoft users authenticate in the SPA through MSAL, then the backend validates the Microsoft access token against Entra OpenID/JWKS metadata and creates a Toolbox session cookie. Microsoft user roles are assigned from Entra group role mappings when the user signs in.

Microsoft Entra login setup

Administrators configure Microsoft login in the Toolbox UI under Settings → Microsoft App Registration Configuration. Use the local admin account for the initial setup, then switch to Microsoft sign-in after the configuration and group mappings are saved.

This integration uses a browser SPA sign-in flow with MSAL. Do not create or paste a client secret into Toolbox; the app only stores tenant/app IDs and validates Microsoft access tokens on the backend.

Prerequisites

  • A Microsoft Entra tenant ID.
  • Permission to create or update Entra app registrations.
  • At least one Entra security group for Toolbox access. Use group object IDs whenever possible.
  • The public Toolbox frontend origin:
    • local development: http://localhost:5173
    • default production compose: http://localhost:8080
    • hosted production example: https://toolbox.example.com

The redirect URI must exactly match the origin shown in the Toolbox Settings page under Redirect URI.

1. Create the backend API app registration

  1. In Microsoft Entra admin center, open App registrations → New registration.
  2. Name it, for example M365 Toolbox API.
  3. Use Accounts in this organizational directory only unless you intentionally support another tenant model.
  4. After creation, copy the Application (client) ID. This is the Toolbox Backend API Audience value.
  5. Open Expose an API.
  6. Set the Application ID URI to api://<backend-api-client-id> if Entra has not already generated one.
  7. Add a delegated scope:
    • Scope name: access_as_user
    • Who can consent: Admins and users or Admins only, depending on tenant policy
    • Admin consent display name: Access M365 Toolbox
    • Admin consent description: Allows the Toolbox frontend to call the Toolbox API as the signed-in user
    • State: enabled
  8. Open Token configuration and add a groups claim to access tokens. Prefer group object IDs. If your tenant emits group overage claims because the user belongs to many groups, Microsoft login will be rejected until the token contains usable group claims for this API.

2. Create the frontend SPA app registration

  1. In App registrations → New registration, create another app, for example M365 Toolbox Frontend.
  2. In Authentication, add a platform of type Single-page application.
  3. Add the Toolbox frontend origin as the redirect URI, for example https://toolbox.example.com or http://localhost:5173 for local development.
  4. Keep implicit grant unchecked unless you have a separate reason to enable it. MSAL uses the authorization-code-with-PKCE flow for SPAs.
  5. Copy the Application (client) ID. This is the Toolbox Frontend Client ID value.
  6. In API permissions, add a permission → My APIs → select the backend API app → delegated permissions → access_as_user.
  7. Grant admin consent if your tenant requires it.

3. Configure Toolbox

  1. Sign in with the local administrator account.
  2. Open Settings → Microsoft App Registration Configuration.
  3. Fill in:
    • Tenant ID: your Entra tenant ID.
    • Frontend Client ID: the application/client ID of the frontend SPA app.
    • Backend API Audience: the application/client ID of the backend API app. Toolbox derives the login scope as api://<backend-api-client-id>/access_as_user.
    • Authority URL: optional. Leave blank to use https://login.microsoftonline.com/<tenant-id>, or set that exact tenant authority if needed.
  4. Check Enable Microsoft login.
  5. Save the Microsoft configuration.

4. Add Entra group role mappings

Under Entra Group Role Mappings, add one or more mappings:

  • Entra Group Name: a human-readable group name for operators.
  • Group Object ID: the Entra group object ID. This is strongly recommended because token group names are not always emitted.
  • Assigned Role: one of:
    • administrator: can run every script and manage settings.
    • privileged_user: can run every script but cannot manage administrator-only settings.
    • restricted_user: can run non-remediation scripts only.

Role resolution prefers group object IDs. Group-name matching is only used when a mapping has no object ID and the token contains safe group-name claims. If no mapping matches, or if Microsoft sends group overage claims instead of actual groups, login fails with an authorization error.

5. Test Microsoft sign-in

  1. Sign out of Toolbox or open a private browser window.
  2. Select Sign in with Microsoft on the login page.
  3. Complete the Microsoft prompt.
  4. Confirm the Toolbox user menu shows your Microsoft identity and expected role.

If sign-in fails, verify the redirect URI, tenant ID, frontend client ID, backend API audience, API permission, admin consent, group claims, and group object ID mapping.

High-level flow:

Frontend
  -> API backend
  -> BullMQ / Redis
  -> PowerShell worker
  -> Artifacts + PostgreSQL run store

Runtime controls available through environment variables:

  • MAX_CONCURRENT_RUNS Limits how many worker jobs can execute at the same time. Extra runs stay queued until a slot opens.
  • DATABASE_URL Controls how the API and worker connect to PostgreSQL for run history, logs, artifacts, approvals, and result metadata.
  • RUN_STATE_DIR Controls the directory used for worker heartbeat files and optional legacy file-run imports.
  • OUTPUT_DIR Controls where generated artifacts and worker heartbeat files are written.
  • TOOLBOX_SCRIPT_MOUNT_ROOT Controls where the worker resolves toolbox PowerShell scripts.
  • REDIS_URL Controls how the API and worker connect to Redis for BullMQ.
  • ARTIFACT_TOKEN_SECRET Signs short-lived artifact, HTML preview, and ZIP bundle URLs.
  • AUTH_SESSION_SECRET Signs Toolbox HTTP-only session cookies. Use a long random value in production.
  • AUTH_SESSION_TTL_SECONDS Optional session lifetime override. Defaults to 8 hours.

By default, Docker mounts:

  • ./scripts to /toolbox-scripts
  • ./output to /app/output

Local and container startup both run Prisma migrations before the API or worker starts. You can also run them manually:

npm run db:migrate

To import legacy JSON run files from older builds into PostgreSQL:

npm run migrate:file-runs

The importer skips duplicate run ids, preserves artifacts on disk, and does not delete the old JSON files automatically.

IMAP migration workflows

The IMAP migration workflows orchestrate Exchange Online migration cmdlets. They do not connect to source IMAP mailboxes from Node, React, or local script code, and they do not implement a custom mailbox copy engine. Microsoft 365 migration services perform the mailbox sync after Exchange Online PowerShell creates the endpoint and batch.

Available workflows:

  • M365 IMAP Migration Preflight Validates the CSV path and schema, connects to Exchange Online, tests IMAP endpoint availability, and writes a readiness report.
  • M365 IMAP Migration Batch Creates or reuses the IMAP migration endpoint, creates the migration batch from CSVData, optionally starts it, and exports batch/per-user artifacts.
  • M365 IMAP Migration Status Reads an existing migration batch and exports the current summary and per-user statistics.

Prerequisites:

  • The signed-in admin needs sufficient Exchange Online permissions to manage migration endpoints and batches.
  • Target Microsoft 365 mailboxes must already exist and be licensed before migration.
  • The source IMAP server must be reachable by Microsoft 365 migration services on the selected host, port, and security mode.
  • IMAP migration moves mail only. It does not migrate contacts, calendars, tasks, mailbox rules, permissions, or client profiles.
  • Mailbox size, item, and message size behavior still follows Exchange Online migration service limits.

CSV security and format:

Mailbox passwords must not be entered into the browser. Store the migration CSV in a local folder that is mounted into the backend container, then provide the container path in the toolbox form or set M365_TOOLBOX_IMAP_MIGRATION_CSV_PATH. The scripts validate the CSV and redact sensitive values from logs, reports, diagnostics, and artifact names.

Expected CSV headers:

EmailAddress,UserName,Password,UserRoot
target.user@contoso.com,<source-user>,<source-password>,

Required headers are EmailAddress, UserName, and Password. UserRoot is optional for IMAP servers that require a virtual shared folder root.

Example compose mount:

services:
  backend:
    volumes:
      - ./scripts:/toolbox-scripts:ro
      - ./output:/app/output
      - ./migration-input:/migration-input:ro
    environment:
      M365_TOOLBOX_IMAP_MIGRATION_CSV_PATH: /migration-input/imap-mailboxes.csv

Recommended operating sequence:

  1. Run M365 IMAP Migration Preflight with the endpoint name, IMAP server, port, security mode, and CSV path or environment-backed path.
  2. If preflight is ready, run M365 IMAP Migration Batch with the same endpoint settings and a unique batch name. Select auto-start only when you are ready for Microsoft 365 to begin syncing.
  3. Run M365 IMAP Migration Status with the batch name to review batch summary and per-user migration progress.

UI flow

  1. The frontend loads the script catalog from the backend API.
  2. You select a script from the sidebar and fill in its approved input fields.
  3. The backend transforms those values into a controlled pwsh invocation.
  4. The script runs and the UI polls for status updates.
  5. If the backend concurrency limit is busy, the run stays queued until a slot opens.
  6. If a remediation workflow is selected, the UI requires explicit approval confirmation before launch.
  7. If a Microsoft device-code prompt appears in stdout or stderr, the UI opens a sign-in modal with the code, a copy button, and a direct login link.
  8. If the script generates artifacts, the backend serves them back for browsing, preview, and download.
  9. If an HTML report is generated, the UI collapses the other run cards and scrolls the report preview into view.

Deploy with Docker Compose

Docker Compose is the easiest way to deploy the project because it builds both services, wires the frontend to the backend, and mounts the folders used for scripts and generated output.

What Compose starts:

  • postgres Internal PostgreSQL service for persistent run history, logs, artifacts, approvals, and result metadata
  • backend Node/Express API, run persistence, queue endpoints, and artifact serving
  • worker Dedicated PowerShell execution container that consumes BullMQ jobs
  • redis Internal Redis service for BullMQ queues, retries, and dead-letter handling
  • frontend Nginx container serving the built React app

Named containers in the default and production compose files:

  • m365-toolbox-postgres
  • m365-toolbox-redis
  • m365-toolbox-backend
  • m365-toolbox-worker
  • m365-toolbox-frontend

What Compose mounts:

  • ./scripts into the backend container at /toolbox-scripts as read-only
  • ./scripts into the worker container at /toolbox-scripts as read-only
  • ./output into the backend container at /app/output for generated artifacts
  • ./output into the worker container at /app/output for generated artifacts

What Compose exposes:

  • http://localhost:5173 for the frontend
  • http://localhost:3001 for the backend API

Compose setup:

  • docker-compose.yml Single Compose file for both local and self-hosted deployments
  • .env.example Copy this to .env and set production values before deploying on a server

Environment file setup

For server deployments, provide a .env file for Docker Compose. Docker Compose uses it for substitutions such as ${ARTIFACT_TOKEN_SECRET}, ${AUTH_SESSION_SECRET}, ${FRONTEND_ORIGIN}, and ${FRONTEND_PORT}.

The .env file is not created automatically. Create it once per deployment environment and include the values below.

Copy .env.example to .env and replace the example values:

FRONTEND_ORIGIN=https://toolbox.example.com
FRONTEND_PORT=5173
ARTIFACT_TOKEN_SECRET=replace-with-a-long-random-secret
AUTH_SESSION_SECRET=replace-with-another-long-random-secret
# CORS_ALLOW_PRIVATE_NETWORK=true
# DATABASE_URL=postgresql://m365:m365password@postgres:5432/m365_toolbox

Minimum recommended production values:

  • FRONTEND_ORIGIN
  • ARTIFACT_TOKEN_SECRET
  • AUTH_SESSION_SECRET

Optional values:

  • FRONTEND_PORT
  • DATABASE_URL
  • POSTGRES_DB
  • POSTGRES_USER
  • POSTGRES_PASSWORD
  • REDIS_URL
  • CORS_ALLOW_PRIVATE_NETWORK

Leave DATABASE_URL commented unless you are using an external PostgreSQL database. The bundled PostgreSQL service works with the default connection string already defined in docker-compose.yml.

Generate strong secrets with OpenSSL. Run this command twice and use a different value for each secret:

openssl rand -base64 48

Example production .env after replacing placeholders:

FRONTEND_ORIGIN=https://m365toolbox.example.com
FRONTEND_PORT=5173
ARTIFACT_TOKEN_SECRET=generated-artifact-secret-goes-here
AUTH_SESSION_SECRET=generated-session-secret-goes-here
# CORS_ALLOW_PRIVATE_NETWORK=true

Variable notes:

  • FRONTEND_ORIGIN Public URL used by backend CORS validation. Set this to the exact browser-facing origin, for example https://toolbox.example.com. Do not include a path.
  • FRONTEND_PORT Host port mapped to the frontend container. Defaults to 5173 when omitted.
  • ARTIFACT_TOKEN_SECRET Required in production. Use a long random value. It signs artifact, HTML preview, and ZIP bundle links.
  • AUTH_SESSION_SECRET Required in production. Use a different long random value for HTTP-only login sessions. M365 Toolbox now fails fast at startup in production if this variable is missing.
  • CORS_ALLOW_PRIVATE_NETWORK Optional. Defaults to disabled. Set true only when you intentionally want to allow browser origins on private IPv4 networks like 10.x, 192.168.x, or 172.16-31.x in addition to FRONTEND_ORIGIN and localhost.
  • DATABASE_URL Optional. Leave commented when using the bundled PostgreSQL service. Set it only when using an external or platform-managed database.

Verify Docker Compose can read the file:

docker compose config

If the command prints the fully rendered Compose configuration, the .env file is being loaded correctly.

Keep .env private. Do not commit it, paste it into tickets, or share it in logs.

Default deployment steps:

From the repository root:

docker compose up -d --build

The stack runs in this order:

  1. postgres and redis start
  2. migrate runs Prisma migrations once
  3. backend starts and becomes healthy
  4. worker starts
  5. frontend starts after the backend health check passes

After deployment:

  • Frontend: http://localhost:5173 unless overridden by FRONTEND_PORT
  • Backend health from inside Docker: http://backend:3001/api/health

Useful Docker Compose commands:

docker compose ps
docker compose logs -f
docker compose logs -f backend
docker compose logs -f worker
docker compose logs -f redis
docker compose logs -f frontend
docker compose down

Self-hosted deployment:

From the repository root:

docker compose up -d --build

Recommended production overrides:

  • FRONTEND_ORIGIN Public frontend URL used by backend CORS validation, for example https://m365toolbox.domain.com
  • FRONTEND_PORT Host port mapped to the frontend container when you do not want the default 5173
  • DATABASE_URL Optional PostgreSQL connection string override if you are not using the bundled postgres service defaults
  • ARTIFACT_TOKEN_SECRET Strong secret used for signed artifact and report preview links
  • AUTH_SESSION_SECRET Strong secret used for HTTP-only login sessions

Example:

$env:FRONTEND_ORIGIN="https://toolbox.example.com"
$env:FRONTEND_PORT="80"
$env:ARTIFACT_TOKEN_SECRET="replace-with-a-long-random-secret"
$env:AUTH_SESSION_SECRET="replace-with-another-long-random-secret"
docker compose up -d --build
  • runtime values are expected to be supplied by the platform UI

Recommended variables for Coolify or Portainer:

  • FRONTEND_ORIGIN Set this to the public URL of the deployed frontend, for example https://toolbox.example.com. The backend normalizes the value to its origin, so an optional trailing slash or pasted path is tolerated.
  • FRONTEND_PORT Optional host port override if you are not using a platform-managed proxy
  • DATABASE_URL Optional PostgreSQL connection string override if your platform manages the database separately
  • ARTIFACT_TOKEN_SECRET Required HMAC secret used for signed artifact, HTML preview, and ZIP bundle links
  • AUTH_SESSION_SECRET Required secret used for HTTP-only login sessions

When to rebuild:

  • Rebuild backend and worker if you change backend code or PowerShell module installation
  • Rebuild frontend if you change the React UI and want the containerized build updated
  • Rebuild everything if you change shared package metadata or Dockerfiles
  • You do not need an image rebuild for normal edits inside scripts/ or scripts/catalog/ when those folders are mounted from the host

Examples:

docker compose build backend
docker compose up -d backend worker redis
docker compose build frontend
docker compose up -d frontend

Notes for deployment:

  • The backend persists run history in PostgreSQL, so completed runs remain visible after backend and worker restarts.
  • Generated artifacts remain in the host output/ folder because it is mounted into the container.
  • Scripts are loaded from the host scripts/ folder, so keep that directory in place on the machine running Docker Compose.
  • The Coolify or Portainer-friendly compose file stores artifacts in a Docker-managed volume instead of the host output/ folder.

Run locally for development

Install workspace dependencies from the repository root:

npm install

The repo includes a committed package-lock.json, so CI uses npm ci for repeatable installs.

Start both apps together:

npm run dev

That starts:

  • API backend on http://localhost:3001
  • PowerShell worker in watch mode
  • frontend dev server on http://localhost:5173

Before local development, make sure Redis is available on redis://127.0.0.1:6379 or set REDIS_URL to your local Redis endpoint. The frontend Vite config proxies /api requests to the backend during local development.

Implementation notes

  • Run history is persisted in PostgreSQL so completed runs survive backend and worker restarts.
  • Running or queued jobs are marked as interrupted if the backend restarts before they finish.
  • Toolbox-native scripts are served only from scripts/; there is no external PowerShell repository mount.
  • Shared helpers such as Shared-ToolboxReport.ps1 support common HTML dashboard rendering and output handling.
  • The backend API exposes script listing, run creation, run status, cancellation, artifact listing, artifact download, HTML preview, queue status, and backend status endpoints.
  • Input values are validated on the backend before PowerShell execution starts.
  • Run retention is controlled by backend retention settings so old run records do not accumulate forever.
  • CORS is restricted to configured origins, localhost, and private IPv4 ranges.

Product direction

The current implementation focuses on safe execution, persistent run visibility, and better operator feedback. The next natural product steps are:

  • richer approval workflows with requester and approver identities
  • stronger artifact management and retention controls
  • localization when multilingual support becomes a priority
  • alternative auth flows such as certificate-based or app-based execution where appropriate

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages