PII Redaction

Automatically redact personally identifiable information from traces before storage.

Neatlogs has two independent controls:

ControlWhere it runsWhat it protectsFailure behavior
SDK mask callbackIn your process, after Neatlogs canonicalizes telemetry and before batching/exportTelemetry sent by that SDK client: span attributes and typed I/O, events/exceptions, logs, and sanctioned resource fieldsFail closed. A callback exception, timeout, cancellation, or invalid result drops the affected telemetry item instead of exporting the unmasked original.
Server-side PII redactionIn Neatlogs ingestion before user-visible span storageConfigured fields and span kinds for the projectIf redaction cannot finish, normal asynchronous trace ingestion must fail closed and retry the event. It does not forward the original content to user-visible span storage.

These controls are not aliases. Server PII options do not run local hashing/redaction, and a local mask does not change the project's server-side policy.

This server behavior applies to normal asynchronous trace ingestion. Other product endpoints and helpers have their own documented contracts. Do not infer their failure behavior from this trace-ingestion guarantee. If data must not leave your infrastructure, use the SDK mask callback as the first control.

SDK Doctor local mode is network-free, so it cannot exercise server-side redaction. Probe mode uses the normal authenticated trace pipeline and verifies its exact persisted result without reproducing or exposing private classification rules.

Client-side masking

def redact(item, *, context=None):
    attrs = item.get("attributes", {})
    for key in list(attrs):
        if "email" in key.lower() or "phone" in key.lower():
            attrs[key] = "***"
    return item

neatlogs.init(mask=redact)

Python accepts synchronous and awaitable callbacks. TypeScript accepts values or promises. Go supplies a cancellable context.Context. Masking runs on a bounded export worker rather than the application span-end path.

Python preserves the legacy mutate-in-place convention: returning None exports the mutated clone. TypeScript and Go use a null/nil result to intentionally drop the item. In every language, callback failure or timeout drops data rather than sending the original secret.

Per-span masking

Python and TypeScript also accept mask on span()/trace(). A per-span callback applies only to that span and takes precedence over the client's global callback; it does not automatically apply to sibling or child spans.

@neatlogs.span(kind="TOOL", mask=redact)
def lookup_customer(email: str):
    ...

Server-side PII redaction

Configure the project policy in Settings → PII Redaction: enabled state, detected entity types, replacement operator, and included span kinds. It can cover core I/O, LLM messages and completions, prompt-template telemetry, tool arguments/results, retrieval and reranker documents, and MCP request/response values.

Python can persist project-level overrides during init():

neatlogs.init(
    pii_enabled=True,
    pii_entities=["PERSON", "EMAIL_ADDRESS"],
    pii_span_types=["LLM", "TOOL"],
)
Warning

These are project settings, not per-process filters. Supplying them changes the saved project policy seen by other applications and in the dashboard. Omit an option to preserve the existing setting. TypeScript's legacy pii and piiSpanTypes options likewise describe server processing; a value such as hash does not hash content inside the TypeScript process. Go currently has no SDK-side project-policy override.

Managed prompts are a separate data path

Telemetry masking applies to trace/log export only. It does not rewrite prompt content sent through getPrompt/createPrompt or Python's managed-prompt methods. Prompt CRUD is an intentional authenticated product-data request; see Managed prompt privacy, ownership, and retention.

If prompt content must be transformed before storage, transform it explicitly in application code before calling the prompt API. Neatlogs does not currently expose a prompt transform option, and enabling telemetry masking must not be treated as proof that managed-prompt content was masked.

On this page

Ask Neatlogs AI

Answers from the docs

How can I help?

Ask anything about instrumenting, tracing, or the Neatlogs dashboard.