Skip to main content

A compliance control layer between your app and any LLM: PII/PCI redaction, cost tracking, and privacy-safe audit logging. GCC-focused.

Project description

llm-guardrails-kit

A compliance control layer that sits between your application and any LLM API — redacting PII/PCI, tracking cost, and writing privacy-safe audit logs.

PyPI Python versions License: MIT CI

Built by Gulf Business Machines (GBM) with a focus on regulated GCC sectors — finance, healthcare, and government.


Why this exists

Sending raw customer data — names, card numbers, Emirates IDs, IBANs — to a third-party LLM provider is a data-protection and compliance risk for organizations in regulated sectors. Once data leaves your perimeter you lose control of where it is stored, logged, or used for training.

llm-guardrails-kit gives you a thin, auditable control layer you own:

  • 🛡️ Redaction — detect and mask PII/PCI before the prompt leaves your network, and transparently restore the originals in the response.
  • 💰 Cost governance — meter every request and roll up spend per model.
  • 📝 Auditability — append a structured, privacy-safe JSON-Lines record for every call, proving what was sent without ever recording the raw values.

It is provider-agnostic (works with any LLM via a callable you supply) and the core install has zero third-party dependencies — easy to vet, easy to run in locked-down environments.

Data-protection regimes across the GCC (for example the UAE PDPL, DIFC and ADGM data-protection regulations, Saudi PDPL, and sector rules from regulators such as central banks and health authorities) place obligations on how personal data is processed and shared. This library is a control to help you meet those obligations — see the disclaimer.


Install

# Core — zero third-party dependencies
pip install llm-guardrails-kit

# Optional: LiteLLM integration (one client for 100+ providers)
pip install "llm-guardrails-kit[litellm]"

# Development (pytest, build, ruff)
pip install "llm-guardrails-kit[dev]"

Requires Python 3.11+.


Quickstart

Redact a prompt containing a card number, Emirates ID, and email; send it through a GuardedClient with a dummy completion function; and inspect the audit record — all without an API key.

from llm_guardrails_kit import GuardedClient, AuditLogger, CostTracker

# 1. A stand-in for your real LLM call. It receives the ALREADY-REDACTED prompt.
#    Swap this for OpenAI, Anthropic, LiteLLM, Bedrock — anything.
def my_llm(prompt: str, model: str, **kwargs) -> dict:
    # A real LLM never sees the raw PII — only placeholders like [CARD_1].
    print("LLM received:", prompt)
    return {
        "text": "Thanks! I've noted the details for [EMAIL_1].",
        "input_tokens": 42,
        "output_tokens": 12,
    }

# 2. Wire up the control layer.
audit = AuditLogger(path="audit.jsonl")
client = GuardedClient(my_llm, cost_tracker=CostTracker(), audit_logger=audit)

# 3. Call it with sensitive data.
result = client.complete(
    "Charge card 5555 5555 5555 4444 for Emirates ID 784-1984-1234567-4 "
    "and email the receipt to jane.doe@example.com",
    model="gpt-4o",
)

print("Returned to app:", result.text)
print("Redaction counts:", result.redaction_counts)
print("Cost (USD):", result.cost.total_cost)
audit.close()

Output (abridged):

LLM received: Charge card [CARD_1] for Emirates ID [EMIRATES_ID_1] and email the receipt to [EMAIL_1]
Returned to app: Thanks! I've noted the details for jane.doe@example.com.
Redaction counts: {'credit_card': 1, 'emirates_id': 1, 'email': 1}
Cost (USD): 0.000225

The audit.jsonl record — note there is no raw PII, only counts:

{"input_tokens": 42, "latency_ms": 0.05, "metadata": {}, "model": "gpt-4o", "output_tokens": 12, "redaction_counts": {"credit_card": 1, "email": 1, "emirates_id": 1}, "request_id": "d3b0...", "timestamp": "2026-07-03T09:15:22.104531Z", "total_cost": 0.000225}

Redaction on its own

from llm_guardrails_kit import Redactor

r = Redactor()
res = r.redact("Wire to AE07 0331 2345 6789 0123 456, call +971 50 123 4567")
print(res.redacted_text)  # Wire to [IBAN_1], call [PHONE_1]
print(res.counts)         # {'iban': 1, 'phone': 1}

# Fully reversible for the caller:
print(r.restore("Confirmed [IBAN_1]", res.mapping))  # Confirmed AE07 0331 2345 6789 0123 456

Partial masking (show only the last 4 of a card)

from llm_guardrails_kit import Redactor, RedactionPolicy, MaskStyle

policy = RedactionPolicy(mask_style=MaskStyle.PARTIAL)
print(Redactor(policy).redact("Card 5555 5555 5555 4444").redacted_text)
# Card **** **** **** 4444

Using it with LiteLLM (optional extra)

from llm_guardrails_kit import GuardedClient, AuditLogger

client = GuardedClient.from_litellm(audit_logger=AuditLogger(path="audit.jsonl"))
result = client.complete("Email jane.doe@example.com", model="gpt-4o")

What gets detected

Detector Placeholder Validation
Email [EMAIL_n] RFC-ish pattern
Phone (intl + UAE/GCC) [PHONE_n] E.164 digit-count (7–15)
Credit card [CARD_n] Luhn checksum + length 13–19
Generic PCI [PCI_n] 4×4 card-shaped grouping (defensive)
IBAN [IBAN_n] ISO 13616 mod-97 + per-country length
Emirates ID [EMIRATES_ID_n] 784-YYYY-NNNNNNN-C format + Luhn
IPv4 address [IP_n] Octet range 0–255
Custom [NAME_n] Your regex

Every numeric detector uses real structural validation, not just a regex, so 1234 5678 9012 3456 is not mistaken for a valid card, and a corrupted IBAN is rejected by its checksum.


API overview

Symbol Purpose
Redactor(policy=None) .redact(text) -> RedactionResult; .restore(text, mapping) -> str
RedactionPolicy Toggle detectors, add custom_patterns, pick mask_style
RedactionResult .redacted_text, .mapping, .counts, .total_redactions
MaskStyle PLACEHOLDER (default, reversible), PARTIAL (last 4), FULL
CostTracker(prices=None, default_price=None) .record(model, in, out), .total(), .reset(), .set_price()
CostTracker.from_litellm_prices() Build a tracker from LiteLLM's live price data
DEFAULT_PRICES / load_litellm_prices() Built-in snapshot / live price loader
AuditLogger(path=None, sink=None) .log(...) -> AuditRecord; JSON-Lines, never logs raw PII
GuardedClient(completion_fn, ...) .complete(prompt, model); .from_litellm(...) optional helper
luhn_valid, iban_valid, emirates_id_valid Standalone validators

Cost prices — three ways, from convenient to real

Model prices change, so pick the source that matches how much accuracy you need.

1. Built-in snapshot (default). DEFAULT_PRICES in cost.py is a small, hand-maintained table of per-1M-token prices for common OpenAI/Anthropic models. Convenient, but it drifts — treat it as a fallback, not gospel.

2. Live prices (recommended for production). Load the continuously-updated price table used by LiteLLM (hundreds of models across providers). It uses the installed litellm package if present, otherwise fetches the public price JSON with the standard library — no third-party dependency required:

from llm_guardrails_kit import CostTracker

tracker = CostTracker.from_litellm_prices()   # self-updating, ~2400+ models

The network fetch needs valid CA certificates. On a fresh python.org install on macOS, run the bundled "Install Certificates.command" once, or install the [litellm] extra so prices are read locally with no network call. If loading fails (e.g. offline), it falls back to DEFAULT_PRICES automatically.

3. Your own contracted rates (most accurate). If GBM has committed-use or negotiated pricing, that contract is the real price — feed it in directly:

from llm_guardrails_kit import CostTracker, ModelPrice

tracker = CostTracker(prices=my_rate_table)          # whole table
tracker.set_price("gpt-4o", ModelPrice(2.3, 9.0))    # or one model

Development

pip install -e ".[dev]"
ruff check .
pytest
python -m build

Disclaimer

llm-guardrails-kit is a helper control layer, not a guarantee of regulatory compliance. It reduces the risk of leaking sensitive data to third-party LLMs, but:

  • No automated redactor detects 100% of sensitive data in free-form text.
  • It does not claim any specific certification or regulatory approval.
  • You remain responsible for validating it against your own legal, regulatory, and contractual obligations before relying on it in production.

Test it thoroughly with your own data and threat model. Use of this software is subject to the MIT License and provided "as is", without warranty.


Built by Gulf Business Machines (GBM). Maintainer: Hasan Odeh.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

llm_guardrails_kit-0.2.0.tar.gz (23.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

llm_guardrails_kit-0.2.0-py3-none-any.whl (20.0 kB view details)

Uploaded Python 3

File details

Details for the file llm_guardrails_kit-0.2.0.tar.gz.

File metadata

  • Download URL: llm_guardrails_kit-0.2.0.tar.gz
  • Upload date:
  • Size: 23.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for llm_guardrails_kit-0.2.0.tar.gz
Algorithm Hash digest
SHA256 b4ce0b7a94b53091c8391d8a9bf7c81dafaec7e6a8ce81395760cf26f23e7db7
MD5 97587b736522a24ed6fea2c39669df8b
BLAKE2b-256 1e3a2e733f9736b9b7bfb4f9450512625e00ebc50f739877b45324204065306a

See more details on using hashes here.

Provenance

The following attestation bundles were made for llm_guardrails_kit-0.2.0.tar.gz:

Publisher: publish.yml on GBMUAE/llm-guardrails-kit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file llm_guardrails_kit-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for llm_guardrails_kit-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bb8b5801eb889445d30f41b868ca0615fe63ffdae76add331144574a27a6510a
MD5 edb51fc02cf3a6a0fabc3b78b2e01eaa
BLAKE2b-256 5de8d851cacf8730b3273a224b34d7ecc9712b577ac38e184f0e904ef2625323

See more details on using hashes here.

Provenance

The following attestation bundles were made for llm_guardrails_kit-0.2.0-py3-none-any.whl:

Publisher: publish.yml on GBMUAE/llm-guardrails-kit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page