Ledger Gate

Privacy & Redaction

How @ledgergate/ledgergate-sdk protects your users' data — what is collected, what is redacted, and how to configure privacy controls.

Design Philosophy

The SDK is privacy-by-default. Every privacy protection described on this page is active out of the box — no configuration required to enable them. You only need to configure privacy options if you want to relax a protection (e.g. allowing a specific header through) or strengthen it (e.g. providing a custom IP hash salt).

The SDK is also non-custodial. It never captures request or response bodies, never stores payment credentials, and never handles funds.


What Is Collected

The SDK collects the following metadata per request:

FieldNotes
HTTP methodGET, POST, etc.
Request pathQuery strings stripped
Response status codee.g. 200, 402
Latency (milliseconds)Measured from first byte in to last byte out
Request headersSensitive headers redacted — see below
Client IPHashed with SHA-256, then truncated to 16 hex chars
x402 payment metadataAddress, amount, network, token, status (from headers/body)
SDK name and version

What Is Never Collected

  • Request bodies
  • Response bodies (unless you explicitly attach one for x402 parsing)
  • Raw IP addresses
  • Query string parameters
  • Any cryptographic material (private keys, payment secrets, macaroons)

Header Redaction

All request headers are passed through a redaction filter before being stored on the RequestContext or included in events. The following headers are always replaced with [REDACTED]:

Header
authorization
cookie
set-cookie
x-api-key
x-auth-token
x-access-token
x-csrf-token
x-xsrf-token
proxy-authorization
www-authenticate

Matching is case-insensitive. The redacted value [REDACTED] replaces only the header value — the header name itself is preserved in the event.

Allowing specific headers through

Use redaction.allowedHeaders to permit headers that would otherwise be redacted:

const sdk = createLedgergateSdk({
  apiKey: process.env.LEDGERGATE_API_KEY!,
  redaction: {
    allowedHeaders: ["x-api-key"], // allow this through for correlation
  },
});

Caution: Only allowlist headers whose values are safe to store on the Ledger Gate servers. Never allowlist authorization or cookie.

Header normalisation

All header names are lowercased before storage. Array-valued headers (which HTTP/1.1 permits) are joined into a comma-separated string.


IP Address Hashing

When redaction.hashIp is true (the default), the SDK:

  1. Extracts the client IP from X-Forwarded-ForX-Real-IP → direct socket IP (in that priority order)
  2. Concatenates your ipHashSalt with the raw IP string
  3. Computes SHA-256 over the result
  4. Truncates the hex digest to 16 characters

The resulting clientIpHash (e.g. "3f2a1b9e0c7d4e5f") allows usage correlation without revealing identifiable addresses.

Disabling IP collection

Set redaction.hashIp: false to skip all IP extraction and hashing. No clientIpHash will be present on any event.

const sdk = createLedgergateSdk({
  apiKey: process.env.LEDGERGATE_API_KEY!,
  redaction: {
    hashIp: false,
  },
});

Custom hash salt

The default salt is an internal constant shared across all SDK installations. For stronger privacy guarantees, provide a unique salt per deployment:

const sdk = createLedgergateSdk({
  apiKey: process.env.LEDGERGATE_API_KEY!,
  redaction: {
    ipHashSalt: process.env.IP_HASH_SALT!, // random secret, min 16 chars recommended
  },
});

With a custom salt, hashes from your deployment cannot be correlated with hashes from any other deployment — even if they tracked the same IP.


Sampling

Sampling is a complementary privacy control. With sampleRate: 0.1, only 10% of requests are tracked at all. Sampling is evaluated at the very start of the middleware — unsampled requests produce zero events and zero data collection.

const sdk = createLedgergateSdk({
  apiKey: process.env.LEDGERGATE_API_KEY!,
  sampleRate: 0.5, // track 50% of traffic
});

See Configuration — sampleRate for details.


Low-Level API

The privacy utilities are exported directly if you need them outside the middleware context:

import {
  extractClientIp,
  hashIp,
  isSensitiveHeader,
  redactHeaders,
} from "@ledgergate/ledgergate-sdk";

// Extract the best-guess client IP from headers
const ip = extractClientIp(req.headers, req.socket.remoteAddress);

// Hash it
const hashed = hashIp(ip!, "my-custom-salt");

// Check a single header
const isSensitive = isSensitiveHeader("authorization"); // true

// Redact a headers object
const safe = redactHeaders(req.headers, ["x-tenant-id"]);
ExportSignature
extractClientIp(headers, directIp?) => string | undefined
hashIp(ip, salt?) => string (16-char hex)
isSensitiveHeader(name) => boolean
redactHeaders(headers, allowlist?) => Record<string, string>

On this page