Skip to main content

Universal middleware for safeguarding AI‑generated content

Project description

Universal LLM Safeguard Layer

Project overview

Universal LLM Safeguard Layer is a modular middleware written in Python that enforces content safety for applications interacting with large language models (LLMs). It implements a canonical filter pipeline designed for the Trinity framework: every decision is explicit, logged and auditable, and there are no silent failure modes. The layer normalises inputs, checks for authorised override phrases, runs a configurable suite of filters, aggregates the results and writes a structured log entry on every invocation. This makes it suitable for AI systems that must meet strict safety and audit requirements while remaining easy to integrate into existing code bases.

The high‑level pipeline is:

  • Pre‑processing – sanitise and normalise the incoming text and attach any contextual metadata.
  • Override detection – detect exactly one authorised phrase (e.g. from a parent or moderator) and, if present, strip it from the text and permit the message regardless of filter output. Ambiguous or missing overrides are rejected and logged.
  • Filtering – run the configured filters on the cleaned text. The built‑in filters include:
    • Keyword/regex filter – checks for banned keywords and regular expressions.
    • Classifier filter – optionally uses a HuggingFace model to score toxicity/abuse categories and compares them against configurable warn/block thresholds.
    • Perspective API filter – optionally calls the Google Perspective API for additional scoring.

Each filter returns (allowed, flags, reasons) where:

  • allowed is a boolean,

  • flags is a list of machine‑readable identifiers,

  • reasons is a list of human‑readable explanations.

  • Aggregation – merge and deduplicate flags and reasons across all filters.

  • Logging – write a JSON‑lines entry with the timestamp, status, flags, reasons, override metadata, user/session identifiers, anonymised text and any additional context.

  • Post‑processing – allow downstream hooks to augment the result before returning a canonical dictionary.

The return value from the pipeline always includes the keys:

  • status"allowed" or "blocked"
  • flags – list of flag identifiers (e.g. "keyword", "classifier_toxic")
  • reasons – corresponding human‑readable explanations
  • overrideTrue if an override phrase was used
  • role"parent", "moderator" or None

This strict schema promotes type‑safety, cognitive alignment and ease of integration. Unexpected errors are never swallowed; instead they are logged with status="error" and the exception is re‑raised.


Installation

The package is distributed on PyPI under the name safeguard. A minimal installation installs only the core filtering logic; optional extras install framework adapters.

pip install safeguard

# Framework extras (optional)
pip install "safeguard[flask]"    # Flask integration
pip install "safeguard[fastapi]"  # FastAPI integration
pip install "safeguard[django]"   # Django integration

To work from source:

git clone <repository_url>
cd safeguard
python3 -m venv .venv
source .venv/bin/activate    # Use .venv\Scripts\activate on Windows
pip install -U pip setuptools
pip install .
pip install ".[dev]"         # Installs test and lint dependencies

Configuration

Configuration is provided via a JSON file or Python dictionary. The default file lives in safeguarding/config/safeguard_config.json and is merged onto sensible defaults by load_config().

Important configuration sections:

  • rules.banned_keywords – list of lower‑cased substrings. If any appear, the message is blocked with the "keyword" flag.
  • rules.banned_regex – list of regex patterns. Matches add a "regex" flag and block the message.
  • classifier.enabled – enables HuggingFace classifier. Scores are compared to warn/block thresholds.
  • perspective_api.enabled – enables Google Perspective API. Thresholds mirror classifier logic.
  • logging.log_path – file path for audit logs.
  • logging.anonymize – whether to redact text in logs (default: true).
  • override.parent_phrases, override.moderator_phrases – lists of allowed override phrases.

Example safeguard_config.json

{
  "rules": {
    "banned_keywords": ["sex", "drugs", "violence", "suicide"],
    "banned_regex": [".*naked.*", ".*let's keep this secret.*"]
  },
  "classifier": {
    "enabled": false,
    "model": "unitary/toxic-bert",
    "thresholds": {
      "toxic": { "warn": 0.5, "block": 0.7 },
      "insult": { "warn": 0.5, "block": 0.7 }
    }
  },
  "perspective_api": {
    "enabled": false
  },
  "logging": {
    "log_path": "safeguard_flags.log",
    "anonymize": true
  },
  "override": {
    "parent_phrases": ["override123"],
    "moderator_phrases": ["modunlock!"]
  }
}

Load with:

from safeguarding.utils.config_loader import load_config
config = load_config()

Programmatic usage

The core entry point is run_all_filters() from safeguarding.core.orchestrator.

from safeguarding.core.orchestrator import run_all_filters
from safeguarding.utils.config_loader import load_config

config = load_config()
config["classifier"]["enabled"] = False
config["perspective_api"]["enabled"] = False

result = run_all_filters(
    text="Let's talk about drugs override123",
    source="input",
    user_id="user42",
    session_id="sessionA",
    config=config
)

if result["status"] == "blocked":
    print("Content blocked:", result["reasons"])
else:
    print("Allowed:", result)

Return schema:

Key Type Description
status str "allowed" or "blocked"
flags List[str|dict] Identifiers for filter hits (e.g. "regex")
reasons List[str] Human-readable explanations
override bool True if override used
role str or None "parent", "moderator", or None

Logging and override behaviour

Every run creates a JSON audit log containing:

  • timestamp
  • source – e.g. "input" or "output"
  • status"allowed", "blocked", "override" or "error"
  • flags, reasons
  • override_used, override_role
  • text[REDACTED] or full content
  • user_id, session_id
  • action_type – e.g. "block" or "allow"
  • context – any additional metadata

Override phrases must match exactly. Zero or multiple matches = reject. All override attempts are logged.


Framework integration

Adapters are provided for Flask and FastAPI.

Flask

from flask import Flask, request, jsonify
from safeguarding.middleware.flask_adapter import safeguard_filter, safeguard_endpoint
from safeguarding.utils.config_loader import load_config

app = Flask(__name__)
config = load_config()

@app.route("/filter", methods=["POST"])
def filter_text():
    data = request.get_json() or {}
    text = data.get("text", "")
    result = safeguard_filter(text, config=config)
    if result["status"] != "allowed":
        return jsonify(result), 403
    return jsonify(result)

@app.route("/chat", methods=["POST"])
@safeguard_endpoint(config)
def chat():
    return jsonify({"message": "Hello!"})

FastAPI

from fastapi import FastAPI
from safeguarding.middleware.fastapi_adapter import FastAPISafeguardMiddleware
from safeguarding.utils.config_loader import load_config

app = FastAPI()
config = load_config()

app.add_middleware(FastAPISafeguardMiddleware, config=config)

@app.post("/messages")
async def receive(data: dict):
    return {"echo": data.get("text")}

Both return 403 with flags/reasons on block. All overrides are logged.


Version and licence

Current version: 0.1.0
Licence: MIT
See LICENSE for terms.


Contributing

Contributions welcome! Please open issues or PRs. Follow the design principles:

  • No hidden behaviour
  • No silent failures
  • Full auditability
  • Include tests for new logic

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_safeguard-0.1.0.tar.gz (20.5 kB view details)

Uploaded Source

Built Distribution

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

llm_safeguard-0.1.0-py3-none-any.whl (27.8 kB view details)

Uploaded Python 3

File details

Details for the file llm_safeguard-0.1.0.tar.gz.

File metadata

  • Download URL: llm_safeguard-0.1.0.tar.gz
  • Upload date:
  • Size: 20.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for llm_safeguard-0.1.0.tar.gz
Algorithm Hash digest
SHA256 75fa80587d3505847530f9086e5347bee08b32b4277e81137cd60da46aea178b
MD5 b54237f15367bcbc0a8fcf00dfaba8b3
BLAKE2b-256 f5c82d78869a06b00441f42103725fc5af25a653a187d12fb2f075f2908d9d42

See more details on using hashes here.

File details

Details for the file llm_safeguard-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: llm_safeguard-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 27.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for llm_safeguard-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 39cf9d2bc0819cf960e09ab699105620eed5c8694c181b4766c85e9de2c86932
MD5 a5303673eac65ab0bd829d80a7a7fa9a
BLAKE2b-256 d8e3f7908dd5d7b1d6121032bb9131bb46ee48287f9f03abc27017dd00d6ec8e

See more details on using hashes here.

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