Every MSP eventually gets the same request: "Can our client just log in and see their own stuff?" Their open tickets, their backup status, their renewals, an invoice or two. It's a reasonable ask. The problem is that the place where all of that data lives — your console — is also where you reboot servers, push patches, void payments, and read every other client's numbers.
So the usual answer is to stand up a second thing. A separate client-portal product, a forms front-end bolted onto the PSA, a shared inbox dressed up as a "portal." Now you're maintaining two apps, syncing data between them, and explaining to a client why their ticket shows one status in your tool and another in theirs.
When we built the customer portal in Morton Command Center, the goal was to skip all of that. The portal isn't a second application. It's a scoped, white-labeled view of the same data your team already works in — with every agent-only control removed and every other client's data fenced off at the server.
The portal is a subset, not a sibling
The portal runs as its own bundle on its own subdomain (portal.<your-domain>), but it reads from the exact same sources your dashboard does. There's no separate database of client-facing copies to keep in sync, because there are no copies. When a ticket changes status in your console, the client sees the new status the next time their portal refreshes — same record, same source.
That matters for two reasons. First, you never get the "it says something different in their portal" support escalation, because there's only one version of the truth. Second, you're not paying for, or babysitting, a second product. The portal is a curated subset of the surfaces your techs already use, not a parallel app that happens to show similar data.
The flip side of "subset" is the part that makes it safe: the portal deliberately does not carry your operational tooling. There's no Devices console for rebooting machines or running scripts, no Invoicing surface for creating or voiding invoices, no cross-company revenue analytics, no Settings, no other client's anything. Those live in the admin app behind your team's authentication, and they simply aren't part of the portal bundle.
What a client actually sees
The portal opens on an overview — a KPI strip, their plan and rates, and their recent tickets — and from there you decide which sections are available. Each one is individually toggleable, so the portal you give a 12-person law firm can look nothing like the one you give a hospital network. The sections we ship:
- Overview — KPI strip, plans & rates, recent tickets.
- Work — included work versus billable work, so clients can see what's covered and what isn't.
- Maintenance — the history of maintenance performed on their environment.
- Security — EDR/MDR, identity/ITDR, and pen-testing cards, drawn from whichever security vendors you've enabled.
- Backup — on-prem and cloud backup status.
- Invoices — their invoice history, pulled from your accounting system. The platform is API-driven, so any accounting system with an API — QuickBooks, Xero, Sage, or otherwise — is built custom to your stack as part of your engagement.
- Contacts — their contact roster with roles like primary, backup, and purchase approver.
- Licenses & Renewals — Microsoft 365 license counts and upcoming renewal dates.
- Email Preferences — so the client controls what automated reports they receive.
If a section depends on something you haven't connected, you just leave it off. No security tool wired up yet — Huntress, SentinelOne, or whatever you run? Don't enable the Security card. Not pushing invoices from your accounting system yet? Skip the Invoices tab. Every integration is built custom to your stack as part of your engagement — if your tool has an API, we build that integration for you, and proven patterns stand up faster. The toggles live in Settings → Customer Portal, and changing them takes effect for that tenant without a redeploy.
How "only their own data" is actually enforced
This is the part that earns trust, and it's the part most homegrown portals get wrong. It is not enough to hide a button or filter a list in the browser — anyone with the dev tools open can ask for more. Scoping has to happen on the server, before the data ever leaves the building.
In Morton Command Center, a portal user authenticates as a Customer role and is bound to a single company. Every request that user makes is checked server-side against that scope. Tickets, security findings, backups, invoices, contacts — each path enforces "this caller may only see this company's records" in the function that serves it, not in the UI that renders it. The same scope-enforcement machinery we use for your own techs (a Sales rep who's assigned three accounts can't load a fourth) is what keeps a customer fenced to exactly one.
So the worst case for a curious client poking at network requests is that they see their own data, slightly faster. There's no endpoint that quietly returns the full list if you ask it nicely.
White-label means it's your brand, not ours
A client portal that says Morton Command Center across the top would be a strange thing to hand a customer. So it doesn't. The portal pulls your company name, your logo, and your primary and secondary colors from your branding settings and applies them to the portal chrome — and to the automated emails that go out to those clients. To the customer, it's your portal. The only Morton you'll find is in the fine print.
This is the same branding configuration that drives your admin app and your outbound email, so you set it once. If you've already themed the console for your shop, the portal inherits it. We go deeper on the brand-control side in our white-label client portal overview if you want the full picture.
Why this matters more in regulated verticals
If you run healthcare, finance, or any vertical where "who can see what" is a compliance question and not just a preference, the server-side scoping stops being a nice-to-have. A portal that leaks one clinic's data into another clinic's view isn't an embarrassing bug — it's a reportable incident.
That's a big reason we built scoping the way we did, and it's why the same model carries through the whole app: a technician assigned to a subset of companies sees only those companies' devices, tickets, and security data; financials are stripped entirely for roles without a billing entitlement. The portal is just the strictest case of a rule that's enforced everywhere. If your client base lives in a regulated space, our notes on healthcare MSP software walk through how the scoping and reporting fit those requirements.
What it doesn't do (on purpose)
It's worth being clear about the boundaries, because an honest portal is a more useful one. The portal is a near-real-time read surface for the client, warmed on the same cron cycles as the rest of the app, plus a manual refresh — so "within minutes," not a live ticker. Clients can view their tickets and recent activity, but the portal is not a replacement for your ticketing intake; the heavy ticket workflow lives in the admin console where your team works. And the portal never exposes a control that acts on infrastructure — no reboots, no scripts, no payment actions. Those are agent powers, and they stay in the agent app.
The point isn't to give clients a watered-down copy of your console. It's to give them a clean, branded window into the parts of their account that are theirs to see — and to make absolutely sure the window doesn't open onto anyone else's house, or onto the tools you use to run the building.
Set it up once, scope it per client
The pattern we landed on is: brand it once, then decide per client which sections are on. A managed-services client on a full plan might get every section; a break-fix client might get Overview and Invoices and nothing else. Because it's all toggles over one shared data layer, dialing a portal up or down for a specific account is a settings change, not a project.
If you've been putting off giving clients self-service because the only options were "expose too much" or "build a second app," this is the third option. Same data, your brand, their data only — and the admin tools stay where they belong. It pairs naturally with flattening your stack overall, which we made the case for in why MSPs end up paying 4× their headcount in platform fees.