Sensitive data masking for support access: what read-only doesn't hide

Read-only support access still exposes secrets and personal data. Use sensitive data masking, field minimisation and support views, with a test matrix.

Read-only support access stops an agent from changing a customer’s account. It doesn’t stop them seeing everything in it. Sensitive data masking and field-level minimisation decide what support can see. Read-only scope decides what they can do. A safe support session needs both.

Think about what a read-only session can open without writing anything: an integrations page that shows the customer’s API key, a billing page with a full address and payment details, a message inbox, a CSV export. Each one is a read. The read-only impersonation guide covers blocking writes and dangerous operations. This guide covers the other half: what support sees, and how to limit it.

Why doesn’t read-only access protect sensitive data?

Read-only is about state changes, not disclosure. A read-only rule asks “does this request change anything?” A sensitive-data rule asks “should this person see this value?” Those are different questions, and most systems only answer the first.

OWASP’s API Security Top 10 (opens in a new tab) describes the underlying problem. APIs tend to return every property of an object, and an endpoint is vulnerable when it exposes properties the user shouldn’t read. In an impersonation session there’s a twist: your API is behaving correctly. The customer is allowed to see their own address and settings. The person looking just isn’t the customer.

That’s why support access needs its own minimisation rules. GDPR’s data protection by default (opens in a new tab) expects only the personal data necessary for each purpose to be processed, and says the obligation covers its accessibility. A support ticket about a broken export button rarely needs a customer’s date of birth.

Where does sensitive data leak in a read-only session?

Most leaks come from ordinary reads that nobody thought of as sensitive:

SurfaceWhat can leakWhy read-only misses itBetter control
Settings and integrationsAPI keys, webhook secrets, OAuth tokensViewing settings is a GETShow secrets once, then only a prefix or name
Profile and billingAddresses, phone numbers, payment and government identifiersViewing a profile is a GETMask on the server for support sessions
Search and listsOther users’ records in the tenant, message previewsSearch is a read, sometimes a POSTLimit fields in search results
Exports and downloadsWhole datasets, invoices, attachments, signed file linksExports change nothing in the databaseBlock, or require a separate reviewed path
Messages and documentsPrivate user contentContent is just dataHide by default; reveal per ticket with a reason
Logs, recordings and ticketsAnything shown on screenCopies are made after the responseMask capture; keep values out of tickets

Secrets deserve special handling. Stripe, for example, displays a live secret key (opens in a new tab) you create one time, and you can’t reveal it later. If your settings page can’t return a full secret to anyone, it can’t return one to support either.

Exports are easy to miss because they look harmless. OWASP’s logging guidance (opens in a new tab) lists data import and export, including screen-based reports, among the events you should always log, alongside access to sensitive data.

What is sensitive data masking, and where should it happen?

Sensitive data masking is replacing or removing a value so the viewer can’t recover it. NIST defines masking (opens in a new tab) as removing a field or replacing it in a way that doesn’t keep the value’s analytic utility, such as swapping a phone number for asterisks.

For support access, masking has to happen on the server, before the response leaves your API. A blurred field in the UI still sits unmasked in the network response, the browser’s developer tools and any client-side cache.

ApproachHow it worksChoose it whenWatch out for
Field-level minimisationEach endpoint returns only named propertiesAlways, as the baselineGeneric serializers that dump whole objects
Server-side masking for support sessionsThe serializer masks named fields when the request is impersonatedSupport needs the real UI with fewer valuesMasking keyed on browser-supplied flags
Dedicated support viewSeparate endpoints and screens built for supportMost tickets are about status and configurationIt can drift from what the customer sees
Column-level database grantsAn internal tool’s database role can’t select sensitive columnsInternal tools query the database directlyDoesn’t help inside the customer’s own UI
Frontend-only maskingThe page hides values the API still returnsNever as a controlThe data is still in the response

OWASP’s prevention advice (opens in a new tab) matches the first row: pick the specific properties you return rather than serializing whole objects, and keep returned data to the minimum the endpoint needs. For internal tools, PostgreSQL lets you grant SELECT on specific columns (opens in a new tab) rather than a whole table.

The second row needs a trustworthy signal. Key masking on verified impersonation context from your authentication layer, never on a header or body field the browser sends. In Devora integrations, for example, the backend receives verified context (opens in a new tab) that includes whether the request is impersonated, the actor, the subject and the scope.

Should support use a support view or live account access?

Use a support view for routine questions and live account access when the problem only shows up as the customer sees it. Many teams need both.

Support viewLive account access
What support seesStatus, configuration, recent errors, chosen summariesThe customer’s actual screens
Default data exposureLow, by designEverything the customer can see, unless you mask it
Catches UI and permission bugsRarelyYes
Engineering effortA separate set of screens to maintainSession handling, scope enforcement and masking
Good for”Is my sync running?”, “Which plan am I on?""This button is missing for me”, “This report looks wrong”

Choose a support view when the answer lives in metadata: plan, feature flags, job status, error codes, timestamps. That’s most tickets.

Choose live account access when you need to reproduce a problem as the customer, such as a layout, a permission or data-dependent behaviour. Combine it with server-side masking so the session shows the shape of the data without every value.

How do you decide which fields to mask?

Classify your data once, then set a default for support sessions per class. Here’s a reasonable starting point:

Data classExamplesDefault in a support session
SecretsAPI keys, webhook secrets, tokens, recovery codesNever returned
Regulated identifiersGovernment IDs, full payment card or bank numbers, health dataMasked; never revealed in support
Contact detailsEmail, phone, addressPartially masked
Customer contentMessages, documents, notes, uploadsHidden; revealed per ticket with a reason
Operational metadataPlan, status, flags, job results, error codesShown

The “reveal with a reason” pattern works well for content. The agent asks to see a specific field or document, gives a reason, and your application records an audit event with the actor, the customer, the field name and the reason, never the value itself.

What about logs, recordings and screenshots?

Anything support sees can be copied somewhere less protected. Three places matter most.

Application logs. OWASP recommends (opens in a new tab) that access tokens, passwords, sensitive personal data and payment data are removed, masked, hashed or encrypted rather than logged directly. Don’t log full response bodies from support sessions “for debugging”.

Session recordings. Masking in a recording protects the replay, not the live view. In Devora, recording is off by default (opens in a new tab). When it’s on, the default profile is fully masked, sensitive inputs such as passwords, emails, phone numbers and card fields stay masked in every profile, and masking runs in the agent’s browser. The agent still sees the live page exactly as your app renders it. Whether to record at all is a separate decision, so make it deliberately rather than leaving recording on for every session.

Tickets and chat. Screenshots pasted into a help desk outlive the session. Set a team rule: describe the state, don’t paste the data.

How does Devora fit, and what stays your job?

Devora’s scope controls actions (opens in a new tab), not field visibility. Endpoint rules match a method and a path. Read scope allows GET, HEAD and OPTIONS by default, and always-blocked rules apply in both read and write sessions. A rule can cover every method on a route, as in Devora’s recommended * /api/api-keys/**, so you can block key and export routes even for reads.

Devora doesn’t rewrite or redact your API responses. Masking fields inside a live session is your application’s job, keyed on the verified context your backend receives.

The access workflow itself is minimised. When an agent searches for a customer, Devora drops attribute keys (opens in a new tab) that look like secrets or sensitive identifiers, such as ones containing ssn, card, iban or dob. A request keeps a snapshot of only the attributes the template showed. Your search handler should still return only what your team needs to pick the right user.

How do you test what support can see?

Test the network responses, not the screen. Use a synthetic customer with fake secrets and personal data, open a read-only support session, and inspect every response body. These are pass conditions to check, not results we’ve run.

CheckPass condition
Open settings and integrations in a support sessionNo full API key, webhook secret or token in any response body
Open the profile and billing pagesIdentifiers and payment details arrive masked from the server
Make the same requests as the customer, outside a support sessionThe customer still sees their normal data
Send a fake “impersonated: false” header during a support sessionMasking still applies, because it uses verified context
Run global searchResults contain only the fields on your support allowlist
Call the export or bulk download endpointRejected; no file, job or signed link is created
Open an attachment link captured before the sessionLink expired or rejected
Reveal a hidden document with a reasonAudit event has actor, customer, field and reason, not the content
Replay a recorded session that opened the billing pageSensitive inputs and listed regions are masked
Search application logs for the sessionNo tokens, secrets or full payloads

Start with the data classification table, because every other control depends on it. Then decide which tickets a support view can answer, and mask the rest of the live session on the server. When you’re ready to try the access side, create a Devora account and try one staging session against this matrix.

Sources

Quick answers

Common questions, answered clearly.

Direct answers to the questions teams usually ask when evaluating this approach.

Does read-only support access hide sensitive data?

No. Read-only access stops an agent from changing a customer's account, but every page, search result and download still returns whatever your API sends. Hiding sensitive fields needs separate controls: minimised responses, server-side masking or a dedicated support view.

What is sensitive data masking?

Sensitive data masking replaces or removes a value so the person viewing it can't recover the original, for example showing only the last four digits of an account number or asterisks instead of a phone number. For support access it has to happen on the server, before the response reaches the agent's browser.

Is masking sensitive fields in the frontend enough?

No. If the API returns the full value and the page blurs or hides it, the value is still in the network response, the browser's developer tools and any cached data. Treat frontend masking as presentation and do the real masking in the API response.

Does Devora mask sensitive data during a support session?

Not in the live session. Devora's scope and endpoint rules decide which requests can run, not which fields come back, so field masking belongs in your application. Devora's masking profiles apply to optional session recordings, which are off by default.

Should support agents ever see API keys or full payment details?

Almost never. Secrets such as API keys and webhook signing secrets are best shown once at creation and never returned again, even to the customer. Payment and government identifiers should be masked in any support view, with a recorded reason for the rare case that needs more.

Put it into practice

Give your team context.Keep control of access.

Bring approvals, scoped sessions, and access history into your support workflow.