Metadata-Version: 2.4
Name: mloda-anonymizer-binary
Version: 0.1.2
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Rust
License-File: LICENSE
License-File: NOTICE
Summary: Anonymizer binary model for mloda: license-gated HMAC-SHA256 tokenization shipped as a platform wheel
License-Expression: LicenseRef-Proprietary
Requires-Python: >=3.10
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM

# mloda-anonymizer-binary

The license-gated binary behind mloda's anonymizer FeatureGroup: keyed HMAC-SHA256 pseudonyms of a
utf8 column, as 64 lowercase hex characters. Nulls stay null. The binary sends no data anywhere.

## Install

```bash
pip install "mloda-enterprise[anonymizer]"
```

This brings the FeatureGroup, this wheel and pyarrow.

Wheels exist for Linux x86_64 and aarch64 (manylinux2014), macOS x86_64 (10.12+) and arm64 (11.0+), and
Windows x86_64, Python 3.10 or newer. There is no source distribution.

## License

Every run needs a license entitling `anonymizer_binary`, read from the first of these that is set:

- `MLODA_LICENSE_FILE`: path to the license file
- `MLODA_LICENSE_KEY`: the license token itself

Without one the binary exits with a license error before reading any data. A license that names an
unknown key id may need a newer release of this wheel.

## Key

The pseudonymization key is 32 bytes, given as 64 hex characters in the environment variable that the
FeatureGroup's `pii_key_env` option names. Keep it secret and stable: another key gives unrelated
pseudonyms, so changing it re-tokenizes everything.

To get the same tokens as the `anonymizer-rs` tool for its master key file, use the key it derives
(HKDF-SHA256, no salt, info `anonymizer-rs-anon`) from the file's raw bytes. Hex-encoding the master key
file itself also passes the format check but gives tokens that never match.

```python
import hashlib, hmac, pathlib

master = pathlib.Path("master.key").read_bytes()
assert len(master) >= 32, "the anonymizer-rs tool rejects master keys under 32 bytes"
prk = hmac.new(bytes(32), master, hashlib.sha256).digest()
print(hmac.new(prk, b"anonymizer-rs-anon\x01", hashlib.sha256).hexdigest())
```

A master key of 32 bytes `0x11` gives `14dd3905a43d3e02b42887fea94185e3881af0b62c8d5f6a7ccf470df9446477`.

