2025-08-08
Build Customer Portals with Power Pages and Dataverse

What you’ll build (at a glance)
-
Auth: External identities (Azure AD B2C or local) + MFA
-
Access: Web roles (Customer / Partner / Manager) mapped to Dataverse table permissions with Contact/Account scope
-
Data: Read/write only to the user’s own records; sensitive columns masked
-
Branding: Your domain, colors, logos, emails, and error pages
-
Audit: Sign-in logs, data access logs, and change history wired up
Step-by-step (secure by default)
-
Plan data boundaries (15 min)
-
List the Dataverse tables you’ll expose and the minimum actions:
Read | Create | Update | Append. -
Decide row scope per table: Contact (only my records), Account (my company’s records), Global (public/KB only).
-
-
Create a Dev environment + Power Pages site
-
Separate Dev/Test/Prod. Disable indexing while in Dev.
-
-
Choose authentication (customers)
-
Recommended: Azure AD B2C (supports social logins + MFA + self-service).
-
Small/temporary: Local auth with strong password/MFA + email verification.
-
Turn OFF anonymous access unless it’s a public KB.
-
-
Wire identities
-
Map portal users to Dataverse Contacts.
-
Enable email verification and password reset flows; add custom sender domain.
-
-
Define web roles (least privilege)
-
CustomerUser– sees own records (Contact scope). -
AccountManager– sees own account’s records (Account scope). -
SupportAgentExternal(optional) – specific tables with broader read. -
Avoid using the default “Authenticated Users” for production.
-
-
Add tables (carefully)
-
In Power Pages Studio → Data → Add table.
-
Immediately set Table Permissions: scope + CRUD per role.
-
Never set Global unless data is truly public.
-
-
Harden field-level visibility
-
Hide PII fields from forms/lists.
-
Use column-level security or separate a “PublicView” with safe columns only.
-
-
Build pages, lists, and forms
-
Use filtered lists (e.g.,
Created By (Contact) = Current User). -
Validate server-side with Dataverse rules; add client checks for UX only.
-
-
Branding & trust
-
Custom domain + SSL, logo, colors, typography.
-
Branded sign-in/reset pages + branded emails (DKIM/SPF set).
-
Accessibility (WCAG AA): contrast, focus states, alt text, keyboard nav.
-
-
Instrumentation & audit
-
Turn on portal diagnostics, Application Insights, and sign-in logs.
-
Add correlation IDs to error pages; set up alert rules for 4xx/5xx spikes.
-
-
Pen-test your permissions
-
Test as each web role: confirm you can’t see other Contacts/Accounts.
-
Try direct URL/ID tampering on list/detail pages.
-
Review audit logs after tests.
-
-
Promote to Test → Prod
-
Export as managed solution.
-
Rebind environment variables, site settings, and identity providers per env.
-
Smoke test, then schedule a soft launch.
-
Baseline permission model (starter)
| Web Role | Tables (example) | Scope | Perms |
|---|---|---|---|
| CustomerUser | Case, Order, Invoice | Contact | Read, Create (Case) |
| AccountManager | Case, Order, Invoice | Account | Read, Update (Case) |
| KnowledgeBaseViewer | Article | Global | Read |
| VendorUser (opt.) | Delivery, ASN | Account | Read, Update (Delivery) |
Add separate Admin (internal) only if truly needed; keep it out of external roles.
Auth choice quick matrix
-
Azure AD B2C (best general choice)
-
✅ MFA, social logins, self-service, scale
-
🔧 Initial setup + custom policies/branding
-
-
Local Accounts
-
✅ Quick start, small audiences
-
⚠ You own password resets, MFA, deliverability, breach notifications
-
-
External IdPs (Google/Apple)
-
✅ Frictionless sign-in
-
⚠ Compliance/data residency checks; align privacy disclosures
-
Go-live checklist (copy/paste)
-
Anonymous access OFF (unless public KB)
-
Custom domain + SSL bound
-
Branded sign-in/reset pages + verified sender domain
-
Web roles documented; defaults removed from users
-
Table permissions set with Contact/Account scopes
-
Sensitive columns excluded or masked
-
URL tampering tests (GUID swaps) blocked by server filters
-
App Insights + alerts; sign-in logs reviewed
-
Content Security Policy tightened (no
*) -
Managed solution deployed; env variables set; secrets in Key Vault
-
Accessibility pass (WCAG AA)
Useful snippets & settings
Table Permission examples
-
Case (CustomerUser): Scope=Contact, Perms=Read, Create (limit fields), Append To: Contact
-
Case (AccountManager): Scope=Account, Perms=Read/Update, Append To: Account
-
Invoice: Scope=Account, Perms=Read (no Create/Update)
Site settings to review
-
Authentication/OpenRegistrationEnabled= false (if invite-only) -
Authentication/Registration/Email= true -
Webapi/EnableReadOnly= true (tighten further per need) -
Site/EnableCustomErrors= true (no stack traces to users)
Content Security Policy (tight start)
default-src 'self';
img-src 'self' data:;
script-src 'self' 'sha256-…';
style-src 'self' 'unsafe-inline';
connect-src 'self' https://*.yourtenant.crm*.dynamics.com;
frame-ancestors 'self' https://yourdomain.com;
Ops runbook KPIs
-
Auth health: Success rate, MFA drop-offs, password reset failures
-
Data access: 4xx (forbidden) spikes, RBAC drift (unexpected role mix)
-
Performance: P95 page load, list query duration, form save latency
-
Security: CSP violations, WAF hits, unusual geo sign-ins
-
Adoption: DAU/MAU, case creation rate, time-to-resolution
1-week rollout plan
Day 1: Scope tables & actions; draft web roles
Day 2: Stand up Dev site; configure B2C/local auth; disable anonymous
Day 3: Add tables + table permissions; hide sensitive fields
Day 4: Build lists/forms with filtered views; brand sign-in/reset
Day 5: Instrumentation (App Insights); pen-test row/field access
Day 6: Move to Test (managed); rebind settings; UAT with 5 pilot users
Day 7: Cutover to Prod; enable alerts; soft launch + feedback loop
Avoid these gotchas
-
Leaving “Authenticated Users” with broad access—create specific roles.
-
Using Global scope where Account/Contact is intended.
-
Exposing sensitive columns in list views (even if hidden on forms).
-
Relying on client-side filtering only—enforce on server via permissions.
-
Launching without branded comms (welcome/reset emails land in spam).
If you want, I can tailor a role & permission matrix to your exact tables and sketch the managed solution structure (Dev → Test → Prod), plus an invite email template your brand team can drop in.
Apple Podcasts · Spotify · YouTube
Host: Mirko Peters