Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

DataFog Core

Fast structured PII detection, implemented in Rust and exposed for Rust, Python, Node.js, and browsers.

It detects EMAIL, PHONE, SSN, CREDIT_CARD, IP_ADDRESS, DATE, and ZIP_CODE. Version 0.4.0 also detects JWT tokens by default; see the JWT reference. With an explicit German locale, it also detects DE_IBAN, DE_VAT_ID, DE_TAX_ID, DE_SOCIAL_SECURITY_NUMBER, DE_POSTAL_CODE, DE_PASSPORT_NUMBER, and DE_RESIDENCE_PERMIT_NUMBER. Complete PEM private-key blocks are also detected as PRIVATE_KEY by default; see the private-key reference. Context-labeled US_ROUTING_NUMBER detection is also available; see the detector rules. Context-labeled NPI detection is also available; see the detector rules. Every binding returns the same finding information:

entity type, matched text, byte range, code-point range,
optional confidence, detector name, optional detector version

Structured JSON scanning additionally discovers PERSON from documented name-field aliases or explicit JSON Pointer mappings. It scans every string value with the existing detectors and returns field paths plus string-local findings. No model or dictionary download is needed. See person-field discovery for scan_structured / scanStructured and structured transformation APIs.

Phone candidates without + are interpreted as North American numbers: ten digits, optionally preceded by 1, with area and exchange codes starting with 2 through 9. Candidates starting with + retain the existing permissive 7–15 digit check, including shortened synthetic examples such as +1-555-1002. These checks do not validate country calling codes or assigned phone numbers, and numeric identifiers that fit the accepted patterns can still match PHONE.

Both ranges use zero-based, end-exclusive offsets. The byte range addresses the UTF-8 input; the code-point range addresses Unicode scalar values. Rule-based detectors currently report no confidence score. Node.js and browser WASM also return an explicitly named UTF-16 code-unit range that can be passed directly to JavaScript String.prototype.slice.

The transformation strategies are redact, mask, remove, pseudonymize, and tokenize in Rust, Python, and Node.js. Redaction uses an unnumbered [ENTITY_TYPE] placeholder, masking supports full or leading/trailing reveal modes, and removal deletes only the exact finding span. Pseudonymization uses provider-resolved 256-bit keys and deterministic HMAC-SHA-256 tokens. Tokenization uses an application-supplied asynchronous provider to issue opaque DFTOKENv1(...) envelopes and restore them under an exact request-level scope. Both provider-backed strategies are deliberately unsupported in browser WASM. transform requires explicit findings; scan_and_transform (or scanAndTransform in JavaScript) is the explicit scan-then-transform convenience. Results include the transformed text and an ordered record for every applied replacement, including its source metadata and output byte and code-point ranges. Node.js and browser WASM additionally return source and output UTF-16 ranges. Transformation records never include the original matched text.

Transformation calls require an envelope with a default strategy. It can also select entity types, override the strategy per entity, and exempt exact or full-match regex values:

{
  default: { strategy: "redact" },
  entities: ["EMAIL", "PHONE"],
  overrides: {
    PHONE: { strategy: "mask", reveal: { direction: "last", count: 4 } },
  },
  allow: {
    exact: { EMAIL: ["support@example.com"] },
    regex: { EMAIL: [{ pattern: ".+@example\\.org" }] },
  },
}

scan_and_transform uses { scan?: { locale?: string, detect_uuid?: boolean, format?: "text" | "env" | "sql", entities?: string[] }, transform: ... } so detection settings remain separate from transformation policy. For .env assignments or standard SQL quoted strings, select format: "env" or format: "sql" to preserve email boundaries. See the email source-context policy for supported syntax, raw escaped spans, and limitations. Default text scanning is unchanged.

Credit-card detection and decimal numbers

To reduce decimal false positives, CREDIT_CARD detection suppresses contiguous digit candidates immediately after a digit followed by . or ,, such as 3.4111111111111111 and 3,4111111111111111. Cards containing spaces or hyphens, such as 3.4111-1111-1111-1111, still undergo the normal card checks.

In plain text, 3,4111111111111111 could also be two CSV fields: 3 and a card number. The detector cannot distinguish that structure from a comma-decimal number, so it suppresses the card candidate. For CSV input, parse the CSV and scan each field separately so a card value is checked without the preceding field and delimiter.

Packages

Runtime Distribution Import Status
Rust datafog-core datafog_core Published
Python datafog-core datafog_core Published
Node.js @datafog/node @datafog/node Published
Browser/WASM @datafog/wasm @datafog/wasm Published

Migrating from DataFog Python

DataFog Core is a separate distribution and canonical API, not a drop-in replacement for the established datafog Python package.

DataFog Python 4.8.x DataFog Core 0.3.x
pip install datafog pip install datafog-core
from datafog.engine import ... from datafog_core import ...
scan(...).entities scan(...) returns list[Finding]
scan_and_redact(...) scan_and_transform(...)
result.redacted_text result.text
Entity.type, .text, .start, .end Finding.entity_type, .matched_text, .byte_range, .codepoint_range

Do not mechanically rename legacy token to Core tokenize: Core tokenization is provider-backed and reversible. For non-reversible output, use redact, mask, or remove; use keyed pseudonymize when stable linkage is required.

See the dedicated DataFog Python migration guide for the API mapping, strategy differences, entity names, range semantics, and migration checklist.

Quick start

Rust

cargo add datafog-core
use datafog_core::{
    scan, scan_and_transform, ScanAndTransformConfig, TransformationConfig,
    TransformationStrategy,
};

let findings = scan("Email jane@example.com");
assert_eq!(findings[0].entity_type, "EMAIL");
assert_eq!(findings[0].matched_text, "jane@example.com");
assert_eq!(findings[0].byte_range.start, 6);

let result = scan_and_transform(
    "Email jane@example.com",
    &ScanAndTransformConfig::new(TransformationConfig::new(
        TransformationStrategy::Redact,
    )),
).unwrap();
assert_eq!(result.text, "Email [EMAIL]");

Python

python -m pip install datafog-core
import asyncio

from datafog_core import PrivacyManager, scan, scan_and_transform

findings = scan("Email jane@example.com")
print(findings[0].entity_type)       # EMAIL
print(findings[0].matched_text)      # jane@example.com
print(findings[0].byte_range.start)  # 6

result = scan_and_transform(
    "Email jane@example.com",
    {"transform": {"default": {"strategy": "redact"}}},
)
assert result.text == "Email [EMAIL]"

masked = scan_and_transform(
    "Email jane@example.com",
    {
        "transform": {
            "default": {
                "strategy": "mask",
                "reveal": {"direction": "last", "count": 4},
            }
        }
    },
)
assert masked.text == "Email ************.com"

class KeyProvider:
    async def resolve_key(self, key_ref, key_version):
        return {"key": load_32_byte_key(key_ref, key_version), "resolved_version": "7"}

async def pseudonymize():
    return await PrivacyManager(KeyProvider()).scan_and_transform(
        "Email jane@example.com",
        {
            "transform": {
                "default": {"strategy": "pseudonymize", "key_ref": "customers/email"}
            }
        },
    )

pseudonymized = asyncio.run(pseudonymize())

# A token provider implements tokenize_batch(scope, items) and
# restore_batch(scope, items). It owns storage or reversible cryptography,
# authorization, lifecycle, and audit.
token_manager = PrivacyManager(None, token_provider=TokenProvider())
tokenized = asyncio.run(token_manager.scan_and_transform(
    "Email jane@example.com",
    {"transform": {"default": {"strategy": "tokenize", "token_ref": "customers/default"}}},
    {"scope": "tenant-a"},
))
restored = asyncio.run(token_manager.restore(tokenized.text, {"scope": "tenant-a"}))

Node.js

Install the native Node.js package:

npm install @datafog/node
import { PrivacyManager, scan, scanAndTransform } from "@datafog/node";

console.log(scan("Email jane@example.com"));
console.log(
  scanAndTransform("Email jane@example.com", {
    transform: { default: { strategy: "redact" } },
  }).text,
);

const manager = new PrivacyManager({
  async resolveKey({ keyRef, keyVersion }) {
    return { key: await load32ByteKey(keyRef, keyVersion), resolvedVersion: "7" };
  },
});
const pseudonymized = await manager.scanAndTransform("Email jane@example.com", {
  transform: {
    default: { strategy: "pseudonymize", key_ref: "customers/email" },
  },
});

const tokenManager = new PrivacyManager({ tokenProvider });
const tokenized = await tokenManager.scanAndTransform(
  "Email jane@example.com",
  { transform: { default: { strategy: "tokenize", token_ref: "customers/default" } } },
  { scope: "tenant-a" },
);
const restored = await tokenManager.restore(tokenized.text, { scope: "tenant-a" });

The release includes prebuilt binaries for macOS (Intel and Apple Silicon), Linux (x64 and ARM64), and Windows x64.

Browser / WASM

Install the browser/WASM package:

npm install @datafog/wasm
import { init, scan, scanAndTransform } from "@datafog/wasm";

await init();
console.log(scan("Email jane@example.com"));
console.log(
  scanAndTransform("Email jane@example.com", {
    transform: { default: { strategy: "redact" } },
  }).text,
);

Development

cargo test --workspace

To exercise an installed binding package locally:

npm ci --prefix bindings/node
npm run test:package --prefix bindings/node

rustup target add wasm32-unknown-unknown
cargo install wasm-bindgen-cli --version 0.2.127 --locked
npm ci --prefix bindings/wasm
npx --prefix bindings/wasm playwright install chromium
npm run test:package --prefix bindings/wasm

Repository layout

crates/core/        Rust scanning library
bindings/python/    Python extension
bindings/node/      Node.js native binding
bindings/wasm/      Browser/WASM binding
fixtures/           Shared conformance fixtures

License

MIT

German structured identifiers

Pass {"locale":"de"} to text or structured scans. Trimmed, ASCII case-insensitive de, de-DE, and de_DE activate all seven German detectors; omitted locale and recognized en-US/fr aliases keep base detection only. Version 0.4.0 rejects unsupported explicit locales.

from datafog_core import scan_and_transform

result = scan_and_transform("IBAN DE44 5001 0517 5407 3249 31", {
    "scan": {"locale": "de"},
    "transform": {"default": {"strategy": "redact"}, "entities": ["DE_IBAN"]},
})
assert result.text == "IBAN [DE_IBAN]"

These are format/context detectors, not official identifier validators. IBAN checksums and account existence are not checked. Digits are ASCII; permitted internal separators are space, tab, NBSP and narrow NBSP at specified group boundaries, never newlines. Returned text and offsets preserve the source. Passport and residence-permit patterns are legacy heuristics with limited coverage. See the German entity reference and migration differences. The higher-level Python adapter and its dependency update were merged in PR #179. Its package release is separate from Core.

Text detector selection

Pass {"entities":["EMAIL","SSN"]} to a text scan to run only those selected detectors, rather than detecting every type and filtering findings later. In Rust, use ScanConfig::new().with_entities(vec!["EMAIL".into(), "SSN".into()])?. The same selection works inside scan_and_transform's scan configuration; transformation selection remains independent.

Omitting entities preserves existing detection. An explicit selection must be a nonempty array of unique, exact canonical text entity names. Unknown names, lowercase names, duplicates, and structured-only PERSON are rejected using configuration errors with /entities or /entities/<index> paths. Consult capabilities().entities for types with the text scope.

Selection narrows enabled detectors: selecting UUID still requires detect_uuid=true, and German types still require a German locale. Text format handling, finding order, and byte/codepoint ranges are unchanged. Structured scans do not accept this option. It avoids unselected detector work and findings, but does not cap the selected findings or bound the size of a scan response.

UUID identifiers

Canonical UUID detection is opt-in: pass {"detect_uuid":true} to text or structured scans, independently of locale. It emits UUID findings for versions 1–8 with the IETF variant and original casing/ranges. UUID syntax does not imply sensitivity. See the UUID reference for boundaries, excluded sentinel forms and transformation examples.

0.4.1 is published for Rust, Python, Node.js, and WASM. The higher-level Python adapter is integrated in merged PR #179; its package release is separate. See the release notes, runtime capabilities, and 0.4.x compatibility policy.

Core 0.4.1 adds three default detectors: provider-prefixed API_KEY, context-required BEARER_TOKEN, and whole PostgreSQL CREDENTIAL_URI. The registry reports 23 supported entities and 14 defaults with capability contract 1. See the release notes for exact scopes, preserved legacy Python overlap behavior, and the passed local exact-wheel Python 4.9 integration gate. Python's default backend is unchanged.

Metadata

Release files for datafog-core 0.4.5b1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for datafog-core 0.4.5b1
File Size Uploaded Provenance
datafog_core-0.4.5b1.tar.gz 138.2 kB With provenance Details

Built distributions (wheels)

Table of built distributions (wheels) for datafog-core 0.4.5b1
File
datafog_core-0.4.5b1-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details
datafog_core-0.4.5b1-cp310-abi3-manylinux_2_28_x86_64.whl CPython 3.10 abi3 Linux glibc 2.28+ x86-64 Details
datafog_core-0.4.5b1-cp310-abi3-manylinux_2_28_aarch64.whl CPython 3.10 abi3 Linux glibc 2.28+ ARM64 Details
datafog_core-0.4.5b1-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details
datafog_core-0.4.5b1-cp310-abi3-macosx_10_12_x86_64.whl CPython 3.10 abi3 macOS 10.12+ x86-64 Details

Total release size: 9.4 MB

Release files / datafog_core-0.4.5b1.tar.gz

Download URL datafog_core-0.4.5b1.tar.gz
Size 138.2 kB
Tags Source
SHA-256 checksum
How to use checksums
2e84549b0f58a10d974c93b10d69c040212c8baff38ed86e54ea48a5292e7bf5
BLAKE2b-256 checksum
How to use checksums
db344b8cc344bb38f5e6cac54dcb65ba61c967b989b08a7099320858aefd209c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.

Transparency log

Release files / datafog_core-0.4.5b1-cp310-abi3-win_amd64.whl

Download URL datafog_core-0.4.5b1-cp310-abi3-win_amd64.whl
Size 1.6 MB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
7dc4deff6f71e71ee886243d64501eaa65fd1c36bd70a3c5a6a0e58e3a09b5a1
BLAKE2b-256 checksum
How to use checksums
2edbd499eb35116fc5c093fe85145a9704d01c98810f9fcf0d82d0cf3582e6a2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.

Transparency log

Release files / datafog_core-0.4.5b1-cp310-abi3-manylinux_2_28_x86_64.whl

Download URL datafog_core-0.4.5b1-cp310-abi3-manylinux_2_28_x86_64.whl
Size 2.0 MB
Tags CPython 3.10 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
68b15868ff8f21ed7a01eac810cabdb236647269cd0a56b3821fb5bfe2665e3f
BLAKE2b-256 checksum
How to use checksums
760dc50a9c2f91b07847674e00e88d7a71f991e3dcb828b36fa636d450b5a342
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.

Transparency log

Release files / datafog_core-0.4.5b1-cp310-abi3-manylinux_2_28_aarch64.whl

Download URL datafog_core-0.4.5b1-cp310-abi3-manylinux_2_28_aarch64.whl
Size 2.0 MB
Tags CPython 3.10 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
f138fd109519de408eb92bd43c6cd0dc842807e163794ffad234a36a7f2e882d
BLAKE2b-256 checksum
How to use checksums
248789283a46431610f6392386c3b85e8772afc3ce806d8f8ac7db8ead829f11
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.

Transparency log

Release files / datafog_core-0.4.5b1-cp310-abi3-macosx_11_0_arm64.whl

Download URL datafog_core-0.4.5b1-cp310-abi3-macosx_11_0_arm64.whl
Size 1.8 MB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
4b5ce74a21a0194e0f88bb54ed73884a26846e123887d96c756d4413d3d2049a
BLAKE2b-256 checksum
How to use checksums
b10ba1f0147b6ca78821b01e4ea46b6111f5085b12657d05c9175463b385aa40
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.

Transparency log

Release files / datafog_core-0.4.5b1-cp310-abi3-macosx_10_12_x86_64.whl

Download URL datafog_core-0.4.5b1-cp310-abi3-macosx_10_12_x86_64.whl
Size 1.8 MB
Tags CPython 3.10 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
89ef1b781ab88d8f9c44a20b2d580ef82c6fd47da6179d33b7a04685cf81f14e
BLAKE2b-256 checksum
How to use checksums
4ec351b60a09e546029ec48d63d594f82c5aeced847052bdbb39b0e688efdac7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.

Transparency log

Security for datafog-core 0.4.5b1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 6 files in this release have been uploaded with provenance metadata.

Select from 6 files

Attestation for datafog_core-0.4.5b1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page