Agent Wranglers

APP-75Recommended

Mask sensitive values until people ask to see them

Show bank account numbers, government ID numbers and stored secrets masked, such as the last 4 characters. Send the full value only when a person with the permission presses Show, and log each request.

How to do it

The server sends only the masked form in lists and detail views, so the full value never sits in the page or its cached data. A Show button calls a separate endpoint that checks the permission, writes who asked and when to the audit log, and returns the value. Hide it again when the person leaves the screen. Replies carry nothing else the screen does not show, as return only the fields needed says. Card numbers never reach your servers at all under keep card numbers off your servers.

Examples

Python example

def masked(value: str) -> str:
    return "•••• " + value[-4:]

@app.get("/customers/<customer_id>")
def customer_detail(customer_id):
    customer = customers.get(current_user().account_id, customer_id)
    return {"name": customer.name, "bank_account": masked(customer.bank_account)}

@app.post("/customers/<customer_id>/bank-account/reveal")
def reveal_bank_account(customer_id):
    require_permission(current_user(), "customers.reveal_bank_account")
    customer = customers.get(current_user().account_id, customer_id)
    audit.write(actor=current_user().id, action="reveal_bank_account", target=customer.id)
    return {"bank_account": customer.bank_account}

TypeScript example

export async function revealBankAccount(customerId: string, field: HTMLElement) {
  const response = await fetch(`/customers/${customerId}/bank-account/reveal`, { method: 'POST' });
  if (!response.ok) return showStatus('You do not have access to the full number.');
  const { bank_account } = await response.json();
  field.textContent = bank_account;
  addEventListener('pagehide', () => { field.textContent = ''; }, { once: true });
}

How to check

Load a customer list and a detail page as a support user. The responses hold only the last 4 characters of each masked field. Pressing Show returns the full value and adds 1 audit entry. A user without the permission gets a 403.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/app-ui/data-views/mask-sensitive-values">Agent Wranglers web app interface playbook</a>. In code you write, add a comment next to it with the same link.