Getting started
1. Five-minute local demo (docker-compose)
The fastest way to see the product. Auth is disabled in compose, so the UI works without an identity provider - you just can't reach real tenants yet. The published images on ghcr.io are public, so no clone or build is needed:
curl -LO https://raw.githubusercontent.com/Spillers-Technology/PartnerCenterBridge/main/docker-compose.ghcr.yml
docker compose -f docker-compose.ghcr.yml up
# SPA: http://localhost:8082
# API: http://localhost:5080 (Swagger at /swagger)
Or build from source:
git clone https://github.com/Spillers-Technology/PartnerCenterBridge.git
cd PartnerCenterBridge
docker compose up --build
To point the same stack at real tenants later, create a .env file next to
the compose file (see .env.example in the repo) and fill in the
PARTNER_* (and optionally EXCHANGE_*) values - compose picks
them up automatically.
Or run the pieces directly:
# API (needs a Postgres; connection string in appsettings.json)
dotnet run --project src/PartnerCenterBridge.Api
# SPA (proxies /api to http://localhost:5080)
cd web && npm install && npm run dev
Tests need no tenant at all - orchestration is covered against WireMock:
dotnet test
2. Connect real tenants
To act in customer tenants the bridge needs the standard CSP plumbing you likely already have as an MSP:
| Requirement | Why |
|---|---|
A multi-tenant Entra app registration in your partner tenant
(client id + secret in the Partner config section) |
This is the Secure Application Model app that acts on your behalf. |
| GDAP relationship per customer, with roles covering what you use (Intune administration, user management, Exchange recipient management) | Scopes what the bridge can touch in each tenant. No GDAP, no access - the tenant shows as NoDelegation. |
| Per-customer admin consent for the app | Standard multi-tenant app consent in each customer tenant. |
| A one-time SAM bootstrap by an MFA'd admin agent | Seeds the encrypted, auto-rotating refresh token the bridge exchanges for per-tenant Graph tokens. |
(Exchange workflows only) an app-only certificate for Exchange
Online PowerShell (Exchange config section) |
Mailbox configuration is not fully exposed by Graph; the bridge shells out to the EXO V3 module with certificate auth. |
App registration permissions
The Secure Application Model uses delegated (App+User) permissions: the bridge acts as the admin agent whose refresh token you seed at bootstrap. Grant these delegated permissions on the multi-tenant app registration and admin-consent them in your partner tenant. Effective access in each customer tenant is the intersection of this list with the roles on that customer's GDAP relationship.
| API | Delegated permission | Used for |
|---|---|---|
Partner Center (https://api.partnercenter.microsoft.com) |
user_impersonation |
Customer list sync; the SAM token exchange itself. |
| Microsoft Graph | DeviceManagementApps.ReadWrite.All |
Win32 app templates: create, upload and assign Intune apps. |
| Microsoft Graph | User.ReadWrite.All |
New hire, offboard (block sign-in, revoke sessions), license assignment, user lookups. |
| Microsoft Graph | Group.ReadWrite.All |
Adding/removing group membership during provisioning and offboarding. |
| Microsoft Graph | UserAuthenticationMethod.ReadWrite.All |
MFA reset and compromised-account lockdown (enumerating and deleting auth methods). |
| Microsoft Graph | User-PasswordProfile.ReadWrite.All |
Password reset workflow. |
| Microsoft Graph | Organization.Read.All |
Reading subscribed SKUs for the license pickers and license repair. |
| Microsoft Graph | Policy.Read.All |
Config Snapshots: reading Conditional Access Policies and Named Locations. |
| Microsoft Graph | DeviceManagementConfiguration.Read.All |
Config Snapshots: reading Device Compliance Policies. |
/.default, the bridge can only ever use what is consented on the app - adding a
permission later means re-consenting in the partner tenant (customer tenants inherit via
GDAP + the multi-tenant consent).3. First session
- Sync tenants: the Tenants tab pulls your customer list from Partner Center.
- Create a contract: a named group of tenants sharing a desired state.
- Assign tenants to the contract.
- Add an app template (upload an
.intunewinproduced by the Microsoft Win32 Content Prep Tool) or a provisioning template (licenses, groups, UPN domain). - Deploy / provision / run workflows. Everything shows its plan or its diagnosis before it acts, and its steps after.
- Take a config snapshot (optional): the Config Snapshots tab backs up Conditional Access, Named Locations, and Device Compliance Policies for a tenant and diffs any two runs. See Config Snapshots.
Auth section
(authority, audience) and matching VITE_OIDC_* SPA variables -- or set
Auth:Mode=Local for self-registered accounts (passkeys, TOTP, per-tenant sharing)
with no external IdP at all. Full detail: Authentication.
Auth:Mode=Dev (Auth:Enabled=false) is for local development only --
never on a deployed instance.