Back to blog

Client API Blog

How to Expose the Right Customer and Job Data in Your Portal  Without Opening Your Backend

Customer portals need to show up-to-date job and account information without exposing internal systems or sensitive data. This post outlines practical patterns to surface the right data safely and reliably.

Why this matters
Customer portals are a primary touchpoint. Customers expect accurate job status, ETA, invoices, and attachments. But giving the portal direct access to core backends risks exposing internal notes, financial line items, or database identifiers. It also increases operational coupling and backend load.

Guiding principles
- Least privilege: return only the fields customers need.
- Read-only surface: portal APIs should be optimized for reads and not grant write access into core services.
- Separate concerns: dont map portal requests directly to internal tables or microservice interfaces.
- Auditability: log what data was returned and who requested it.

Practical patterns
1) Build portal-specific read models
Create denormalized, read-optimized tables or materialized views with exactly the fields the portal needs. For a field-service portal, a JobSummary read model might include: portal-safe job_id, status, scheduled_window, technician_name, ETA_minutes, customer_facing_notes, and attachments_count. Omit internal_notes, vendor_costs, and raw foreign keys.
Benefits: predictable shape, fast reads, and a clear contract for what can be exposed. Keep these near-real-time using event streams or change-data-capture (CDC).

2) Introduce a Backend-for-Frontend (BFF) or gateway
Place a BFF or gateway between the portal and backend services. The BFF performs joins, applies business rules, and enforces field-level filtering. It prevents clients from composing arbitrary queries against internal services.
Concrete controls: whitelist query parameters, enforce pagination, and return only named response schemas.

3) Use scoped tokens and row-level security
Issue scoped JWTs or OAuth tokens with claims such as tenant_id and allowed scopes (for example, portal:read:job_summary). Enforce row-level security so a portal user cant access another tenants rows. For files, serve presigned URLs that expire in minutes to avoid exposing storage credentials.

4) Shape responses to avoid leaking internal identifiers
Replace internal IDs with portal-specific UUIDs that have no meaning in internal systems. Strip internal URLs, admin flags, debug traces, and SQL-generated fields from responses. Never return internal flags like is_flagged_for_audit.

5) Choose sync vs. async updates thoughtfully
Use websockets or SSE for high-frequency status and ETA updates; use short polling for simpler implementations. For lower-sensitivity data such as history, serve from the read model on demand. Use webhooks or CDC pipelines to refresh read models and notify the portal layer of changes.

6) Handle file access and media safely
Keep files in object storage and generate short-lived presigned URLs for delivery. Strip sensitive metadata before linking objects in the portal. Consider serving scaled previews via CDN and requiring additional auth for full-resolution downloads.

7) Protect PII and financial data explicitly
Inventory PII and financial fields, defaulting them to sensitive. Require an approval process to include sensitive fields in portal APIs. When customers need invoices, prefer streaming a PDF with internal comments redacted rather than returning granular line items.

8) Test with staged, scrubbed data
Exercise portal endpoints against staging that mirrors production data but with PII scrubbed. Include threat modeling and role-based tests to ensure there are no accidental leaks.

Operational considerations
- Caching: cache read-model responses and use ETags to minimize load. Invalidate caches on relevant events, such as status changes.
- Rate limits: enforce per-tenant and per-user limits at the gateway to prevent abusive probing of data shapes.
- Logging and monitoring: log which fields were returned and alert on abnormal access patterns (for example, repeated requests for excluded fields).
- Backwards compatibility: version portal endpoints and avoid breaking schema changes that force front-end rewrites.

Concrete example: a field-service portal API
Endpoint: GET /v1/portal/customers/{customer_portal_id}/jobs
Curated response shape:
- id (portal UUID)
- status (scheduled, en route, on site, completed)
- scheduled_window (start/end ISO timestamps)
- technician_name (first name + last initial)
- eta_minutes (integer)
- customer_facing_notes (string)
- attachments: [{type, preview_url}] (presigned URLs expire in 5 minutes)
- last_updated (ISO timestamp)
Excluded: internal_notes, billing_costs, vendor_id, internal_status_codes.

Typical implementation flow
1) Events from core systems update a JobSummary read table via CDC.
2) The BFF reads JobSummary, applies tenant filters from the JWT, and formats the response.
3) Attachments are provided as presigned URLs requested from object storage when needed.
4) Cache responses for 1030 seconds depending on SLA; use ETags and invalidate on status changes.

How this helps product and ops
- Predictable performance: read models avoid expensive joins at request time.
- Safer compliance: PII and financials are controlled centrally, reducing accidental exposure.
- Faster iteration: product can update the read model and BFF without changing core services.

Where Client API fits
Platforms like Client API can accelerate these patterns. Scoped read endpoints, presigned file delivery, curated projection endpoints, and API-layer access rules make it easier to enforce least-privilege surfaces.

Checklist to get started
- Map every portal field to its source of truth and mark sensitive fields.
- Build a read model containing only allowed fields.
- Implement a BFF or gateway that applies scopes, row-level security, and field filtering.
- Serve attachments via short-lived presigned URLs.
- Test in staging with scrubbed data and enable field-level logging.

Summary
Exposing the right data in a customer portal is about designing explicit, curated surfaces that separate read access from internal operations. Applying read models, a BFF, scoped access, and presigned media reduces risk, improves performance, and makes the portal a reliable product feature rather than a fragile integration point.

More reading

Recent posts