> ## Documentation Index
> Fetch the complete documentation index at: https://platform.atlan.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Privacy controls

> Suppress payload content, mask sensitive values, and control trace volume.

The SDK sends span payloads — prompts, completions, tool arguments — to Agent
Registry by default. Three controls change that, and all of them fail closed:
when a control breaks, data is withheld rather than leaked.

## Suppress content entirely

`trace_content: false` stops input, output, metadata, and tool payloads from
being recorded, while keeping the structural telemetry: span names, observation
types, model, provider, usage, cost, and scores.

<CodeGroup>
  ```python Python theme={null}
  client = atlan_ai.init(service_name="support-rover", trace_content=False)
  ```

  ```typescript TypeScript theme={null}
  const client = atlan.init({ serviceName: "support-rover", traceContent: false });
  ```
</CodeGroup>

`ATLAN_TRACE_CONTENT=false` does the same without a code change.

This also stamps `atlan.consent.store_content=false` on the resource, so the
Gateway's consent gate enforces the same decision server-side. The suppression
does not depend on the client alone.

Use this when you need cost, latency, and quality metrics but the payloads
themselves must not leave your environment.

## Mask specific values

When you need most content but must redact parts of it, use a mask hook
instead of suppressing everything.

### Data-level masking

`mask` runs when your own spans' `input`, `output`, and `metadata` are
recorded. It receives the value and returns the redacted replacement.

<CodeGroup>
  ```python Python theme={null}
  def mask(*, data, **_):
      return redact_pii(data)


  client = atlan_ai.init(service_name="support-rover", mask=mask)
  ```

  ```typescript TypeScript theme={null}
  const client = atlan.init({
    serviceName: "support-rover",
    mask: ({ data }) => redactPii(data),
  });
  ```
</CodeGroup>

Accept extra keyword arguments in Python (`**_`) so the hook keeps working if
the SDK passes additional context in a later version.

If your mask raises, the value is replaced with
`[atlan: value withheld - mask hook failed]` rather than sent unmasked.

### Export-stage masking

`mask` only sees spans the SDK created. Spans from third-party instrumentation
— OpenLLMetry, OpenInference, a framework's native OTel — bypass it. To reach
those, use `mask_otel_spans` / `maskOtelSpans`, which runs over the whole
export batch and returns a patch per span.

<CodeGroup>
  ```python Python theme={null}
  def mask_otel_spans(params):
      return {
          ident: atlan_ai.OtelSpanPatch(delete_attributes=["gen_ai.input.messages"])
          for ident, span in params.items()
          if "gen_ai.input.messages" in span.attributes
      }


  client = atlan_ai.init(service_name="support-rover", mask_otel_spans=mask_otel_spans)
  ```

  ```typescript TypeScript theme={null}
  const client = atlan.init({
    serviceName: "support-rover",
    maskOtelSpans: (spans) => {
      const patches = new Map();
      for (const [key, span] of spans) {
        if ("gen_ai.input.messages" in span.attributes) {
          patches.set(key, { deleteAttributes: ["gen_ai.input.messages"] });
        }
      }
      return patches;
    },
  });
  ```
</CodeGroup>

A patch can delete attributes or set replacement values. Return no patch for a
span to leave it unchanged.

Failure handling is deliberately blunt here, because a partial result cannot be
trusted:

| What went wrong                   | What happens                |
| --------------------------------- | --------------------------- |
| the hook raises                   | the whole batch is dropped  |
| the hook returns an invalid shape | the whole batch is dropped  |
| one patch is invalid              | that single span is dropped |

Dropping a batch means losing those traces. Test a masking hook against
representative spans before enabling it in production, and watch for
`dropping batch` warnings after you deploy it.

## Control volume

Two independent controls reduce how much is exported.

**The export allowlist** decides which spans are eligible at all. By default
the SDK exports its own spans plus spans from recognized GenAI instrumentors,
and drops unrelated application spans. Replace the decision entirely with
`should_export_span` / `shouldExportSpan` if you need different rules.

**Sampling** drops a fraction of traces. Set `sample_rate` between `0.0` and
`1.0`, or `ATLAN_SAMPLE_RATE`. A value outside that range is ignored with a
warning and treated as `1.0`.

<Note>
  Sampling applies only when the SDK creates the TracerProvider. If your
  application owns the provider, the standard `OTEL_TRACES_SAMPLER` and
  `OTEL_TRACES_SAMPLER_ARG` variables govern sampling and the SDK does not
  override them.
</Note>

## Running alongside another tracing vendor

If you already export to Langfuse, Braintrust, or another OTel backend,
`isolated: true` (TypeScript) keeps the SDK off the global TracerProvider and
runs a private pipeline, so neither vendor receives the other's spans.

```typescript theme={null}
const client = atlan.init({ serviceName: "support-rover", isolated: true });
```

If your application owns the provider and you want Atlan spans in it, pass
`client.spanProcessor` into your provider's constructor instead of letting the
SDK register globally.

## Next steps

<CardGroup cols={2}>
  <Card title="Configuration" icon="gear" href="/sdk/configuration">
    Every option, environment variable, and default.
  </Card>

  <Card title="Serverless" icon="bolt" href="/sdk/serverless">
    Flush reliably when the process is short-lived.
  </Card>
</CardGroup>
