Metadata-Version: 2.4
Name: gl-observability-masking-binary
Version: 0.0.0b2
Summary: Shared standard-library-only regex masking primitives
Author: GDP Labs
Requires-Python: <3.14,>=3.11
Description-Content-Type: text/markdown
Provides-Extra: dev
Requires-Dist: pytest<10.0.0,>=9.0.0; extra == "dev"
Requires-Dist: pytest-cov<6.0.0,>=5.0.0; extra == "dev"
Requires-Dist: coverage<8.0.0,>=7.6.10; extra == "dev"
Requires-Dist: pre-commit<4.0.0,>=3.7.0; extra == "dev"
Requires-Dist: mypy<2.0.0,>=1.11.2; extra == "dev"
Requires-Dist: ruff<1.0.0,>=0.11.12; extra == "dev"

# GL Observability Masking

`gl-observability-masking` is a shared helper library for masking components designed
for use by **GLLM Core** and **GL Observability**. It provides reusable rules and text
masking primitives so the two libraries can share masking behavior without depending
on each other.

> **For application developers:** use [GLLM Core](../gllm-core/README.md) or
> [GL Observability](../gl-observability/README.md). This package is a supporting
> dependency and is not intended to be installed or used directly in applications.

## Key Features

- **Shared rule catalog:** 28 built-in rules for credentials, tokens, and personal data.
- **Reusable masking primitives:** immutable rule definitions, compiled patterns,
  and ordered text substitution with `[NAME]` placeholders.
- **Common failure vocabulary:** rule-specific errors and failure modes for the
  consuming libraries.
- **No runtime dependencies:** uses only the Python standard library and supports
  Python 3.11–3.13.
- **No logging side effects:** emits no logs, avoiding feedback loops when called
  by logging components.

## Installation

### Prerequisites

- Python 3.11–3.13 — [Install Python](https://www.python.org/downloads/).
- One package manager: [pip](https://pip.pypa.io/en/stable/installation/),
  [uv](https://docs.astral.sh/uv/getting-started/installation/), or
  [Poetry](https://python-poetry.org/docs/#installation).
- For development from Git: [Git](https://git-scm.com/downloads), SSH access to
  the [GDP Labs SDK repository](https://github.com/GDP-ADMIN/gl-sdk), and `uv`.

### Installation from PyPI

Install the released binary distribution using one of these package managers:

#### Using pip

```bash
pip install gl-observability-masking-binary
```

#### Using uv

```bash
uv add gl-observability-masking-binary
```

#### Using Poetry

```bash
poetry add gl-observability-masking-binary
```

The distribution name is `gl-observability-masking-binary`; the Python import
name is `gl_observability_masking`. No runtime extras are required.

### Development Installation (Git)

To work on the library's source code:

```bash
git clone git@github.com:GDP-ADMIN/gl-sdk.git
cd gl-sdk/libs/gl-observability-masking
uv sync --all-extras
```

The `dev` extra installs the testing, linting, and type-checking tools. Consuming
libraries should depend on released distributions rather than this development
checkout.

## Shared Components

The following components are provided for maintainers integrating this package into
GLLM Core and GL Observability:

| Purpose | Components |
| --- | --- |
| Define and select rules | `MaskingRule`, `BuiltInMaskingRule` |
| Compile rules and mask strings | `CompiledMaskingRule`, `mask_text` |
| Identify substitution failures | `MaskingRuleError` |
| Express failure behavior | `MaskingMode` |

Each consumer or application selects its rules and their order. This package
provides no ordered rule list or default rule set and operates only on strings.
Consuming libraries define their own failure marker, policy, value traversal,
and failure handling. `mask_text` applies the supplied rules sequentially and
raises `MaskingRuleError` on substitution failure; it does not apply a failure
mode itself.

For example, a consumer can explicitly select email and mobile masking:

```python
from gl_observability_masking import BuiltInMaskingRule, CompiledMaskingRule, mask_text

rules = tuple(
    CompiledMaskingRule.from_masking_rule(rule) for rule in (BuiltInMaskingRule.EMAIL, BuiltInMaskingRule.ID_MOBILE)
)
print(mask_text("Contact alice@example.com at +6281234567890", rules))
# Contact [EMAIL] at [ID_MOBILE]
```

Each rule processes the previous rule's output. Order can change the placeholder
or leave part of a sensitive value visible:

- Select `ID_NPWP` before `IPV4`: the reverse order turns
  `01.234.567.8-901.000` into `[IPV4]-901.000`.
- Select `CONN_STRING_CREDS` before `EMAIL`: the reverse order leaves the
  connection string's user name visible.
- Select `BEARER_TOKEN` before `JWT` to replace a bearer JWT with one placeholder;
  the reverse order produces `Bearer [JWT]`.

`mask_text` follows the caller's order without validating or rearranging it.

Regex masking is a safety net, not a guarantee that every sensitive value is removed.
Rules can over-match ordinary values: `CARD_LIKE_LUHN` does not perform a Luhn check
and can match numeric timestamps, while `IPV4` can match four-part version numbers.
`ID_MOBILE` handles contiguous digits, not phone numbers with spaces or dashes.
`FAIL_OPEN` exposes the original unmasked value and is intended for non-production use.

## Local Development

These commands are for contributors working on this helper library. Run them from
the library directory with Python 3.11–3.13 and `uv` installed:

```bash
uv sync --all-extras
uv run python -m pytest
uv run ruff check .
uv run ruff format --check .
uv run mypy gl_observability_masking
```
