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. The next release 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 (unreleased). Complete PEM private-key blocks are also detected as PRIVATE_KEY by default (unreleased); see the private-key reference. Context-labeled US_ROUTING_NUMBER detection is also available (unreleased); see the detector rules. Context-labeled NPI detection is also available (unreleased); 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.
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 }, transform: ... } so
detection settings remain separate from transformation policy.
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
German structured identifiers (unreleased)
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.
The 0.4.0 candidate 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 Python 4.9 adapter requires a subsequently published compatible Core wheel; this source change does not update its extra pin or publish a release.
UUID identifiers (unreleased)
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.
The source candidate targets 0.4.0; publication and downstream Python integration are separate release gates. See the candidate release checklist, runtime capabilities, and 0.4.x compatibility policy.
Release files for datafog-core 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| datafog_core-0.4.0.tar.gz | 94.4 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| datafog_core-0.4.0-cp310-abi3-win_amd64.whl | CPython 3.10 | abi3 | Windows x86-64 | Details |
| datafog_core-0.4.0-cp310-abi3-manylinux_2_28_x86_64.whl | CPython 3.10 | abi3 | Linux glibc 2.28+ x86-64 | Details |
| datafog_core-0.4.0-cp310-abi3-manylinux_2_28_aarch64.whl | CPython 3.10 | abi3 | Linux glibc 2.28+ ARM64 | Details |
| datafog_core-0.4.0-cp310-abi3-macosx_11_0_arm64.whl | CPython 3.10 | abi3 | macOS 11.0+ ARM64 | Details |
| datafog_core-0.4.0-cp310-abi3-macosx_10_12_x86_64.whl | CPython 3.10 | abi3 | macOS 10.12+ x86-64 | Details |
Total release size: 8.3 MB
Release files / datafog_core-0.4.0.tar.gz
| Download URL | datafog_core-0.4.0.tar.gz |
|---|---|
| Size | 94.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1dddef680065860882b8c2394aeab21c702f08d1bbbd260527691ffd66fe0003
|
|
BLAKE2b-256 checksum How to use checksums |
92ff75fc783e7861c3a49ba147c789ea9f1ab95b6a4f11310a10f827cb7582a9
|
| 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 Sep 28, 2026.
Transparency logRelease files / datafog_core-0.4.0-cp310-abi3-win_amd64.whl
| Download URL | datafog_core-0.4.0-cp310-abi3-win_amd64.whl |
|---|---|
| Size | 1.4 MB |
| Tags | CPython 3.10 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
854cacaaa63d6ac22efdd2641ccfae42ede0b473caef9fa6bb09bb17fbec61be
|
|
BLAKE2b-256 checksum How to use checksums |
d2c1b94fff64f708c1bf76418bf0a76eabf61b1c29b45303a40919f8d37176c8
|
| 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 Sep 28, 2026.
Transparency logRelease files / datafog_core-0.4.0-cp310-abi3-manylinux_2_28_x86_64.whl
| Download URL | datafog_core-0.4.0-cp310-abi3-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 1.8 MB |
| Tags | CPython 3.10 Linux glibc 2.28+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
6610d43ae891344a1000e769b52ff22101d634072a6b258b169dd4c02be9b0b6
|
|
BLAKE2b-256 checksum How to use checksums |
c43c1fdd9cdc425eb431488c969d006bd36f65f3177b1c07af3b8b4f9a799833
|
| 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 Sep 28, 2026.
Transparency logRelease files / datafog_core-0.4.0-cp310-abi3-manylinux_2_28_aarch64.whl
| Download URL | datafog_core-0.4.0-cp310-abi3-manylinux_2_28_aarch64.whl |
|---|---|
| Size | 1.7 MB |
| Tags | CPython 3.10 Linux glibc 2.28+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
71181f3e665b39d1583aae5a1a194519c4de80e22e3438137f880f49ddde0681
|
|
BLAKE2b-256 checksum How to use checksums |
1c0071b28e1b4192eaeee6cfc666a720de005ffca1a29fb5415a501621aaf0cf
|
| 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 Sep 28, 2026.
Transparency logRelease files / datafog_core-0.4.0-cp310-abi3-macosx_11_0_arm64.whl
| Download URL | datafog_core-0.4.0-cp310-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 1.6 MB |
| Tags | CPython 3.10 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
b4217c2a9834cb774d89a13b9543166dd7f38512a233b1c80984ea9c07c5162c
|
|
BLAKE2b-256 checksum How to use checksums |
32b70998320e2d240f530dc85c22fa002fbbba819adb65d416f9e29c26c02408
|
| 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 Sep 28, 2026.
Transparency logRelease files / datafog_core-0.4.0-cp310-abi3-macosx_10_12_x86_64.whl
| Download URL | datafog_core-0.4.0-cp310-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 1.6 MB |
| Tags | CPython 3.10 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
b62252fd8a3bb50ef79a2b98bafa596745132ef50075b87d6791e58a4a82e258
|
|
BLAKE2b-256 checksum How to use checksums |
68ff5cdb12fbbcd27a6e27efeea1eca2edfa01458c62aef81047d6783eccd621
|
| 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 Sep 28, 2026.
Transparency log