PHI Boundary Gate
PHI Boundary Gate detects, gates, redacts, and reports PHI candidate movement across AI context boundaries: user messages, RAG context, tool output, model input, memory, debug logs, and provider requests.
It is built for healthcare and insurance AI workflows where an identifier match is only the start. The report answers which layer the value entered, where it came from, where it is going, and what policy says should happen before it moves again.
The package ships as both a CLI and a Python library. Use the CLI for offline audits that produce Markdown, JSON, and redacted JSONL traces. Use the library inside another service to scan text, redact policy-matched spans, or block model calls when the configured PHI and compliance policy says the route is not allowed.
| Boundary-first reports | Groups repeated PHI candidates across trace events so you can see the path, not only the match. |
| Hybrid candidate detection | Built-in regex rules cover common synthetic PHI variants; optional local Presidio detection can add NER-backed spans. |
| Trace corpus baseline | Synthetic trace expectations cover boundary flow, near misses, free text, structured payloads, and provider-boundary paths. |
| Policy-driven redaction | YAML policy decides whether each category is allowed, should be redacted, or is a violation in each layer. |
| Provider-call guard | Checks organization-supplied BAA, covered service, model, feature, logging, and storage facts before PHI is sent. |
| Audit-safe by default | Compliance decisions can be serialized without detected raw PHI values unless controlled debugging explicitly asks for them. |
| Synthetic samples only | The repository contains no real PHI and does not claim HIPAA compliance. |
Quick Start
Run the bundled sample
Use this path when you have cloned this repository and are running commands from the repo root. The sample trace, policy, and report paths below are repository files, not package data installed into another project.
python3 -m pip install -e .
phi-boundary-gate \
--trace samples/traces/claim_agent_minimal.jsonl \
--policy samples/policies/default.yml \
--out reports/sample-report.md \
--json reports/sample-report.json
Run the same command without installing the package:
PYTHONPATH=src python3 -m phi_boundary_gate.cli \
--trace samples/traces/claim_agent_minimal.jsonl \
--policy samples/policies/default.yml \
--out reports/sample-report.md \
--json reports/sample-report.json \
--redacted-trace reports/sample-redacted-trace.jsonl
Invalid trace or policy input returns exit code 2 and writes the validation
error to stderr.
Install from another project
Use the PyPI package for normal consumption:
python3 -m pip install "phi-boundary-gate>=0.5,<0.6"
The consuming environment needs Python 3.11 or newer and pip. pip installs
the runtime dependency PyYAML>=6.0.
Optional local NER support is available for projects that want Presidio-assisted span detection in addition to the built-in regex rules:
python3 -m pip install "phi-boundary-gate[ner]>=0.5,<0.6"
python3 -m spacy download en_core_web_lg
Then enable it explicitly:
phi-boundary-gate \
--trace samples/traces/expanded_phi_variants.jsonl \
--policy samples/policies/default.yml \
--out reports/expanded-report.md \
--json reports/expanded-report.json \
--enable-presidio
Without --enable-presidio, scans stay dependency-light and use only the bundled
deterministic rules.
Consuming projects must provide their own PHI policy YAML. If they use the
compliance guard, they must also provide their own compliance policy YAML with
organization-approved BAA, covered service, model, feature, logging, and storage
facts. The sample files under samples/ are examples to copy and adapt; they are
not installed as importable package resources.
To bootstrap a consuming project with starter policy files:
phi-boundary-gate init
phi-boundary-gate check-config
This creates .phi-boundary-gate/config.json, config/phi-policy.yml, and
config/phi-compliance-policy.yml. Review those files with the owners of your
logging, prompting, memory, provider, and compliance controls before using them
with real PHI.
Update from another project
Update consuming projects through the package index:
python3 -m pip install --upgrade "phi-boundary-gate>=0.5,<0.6"
Production projects should use a compatible version range such as
phi-boundary-gate>=0.5,<0.6 and let Dependabot, Renovate, or a lockfile update
workflow propose patch/minor updates through CI. Git tag installs remain a
fallback for environments that cannot access PyPI, but they are no longer the
primary consumption path.
For requirements.txt and pyproject.toml examples, see
Install and Consume as a Package. For release notes, see
CHANGELOG.
What It Reads
The trace is JSONL. Each event records the layer, content, source path, and destination path for one piece of context:
{"event_id":"evt_003","timestamp":"2026-01-15T09:00:03Z","layer":"tool_output","source":{"type":"synthetic_claim_lookup","path":"tools.claim_lookup.response"},"destinations":[{"layer":"model_input","path":"prompt.context[1]"},{"layer":"debug_log","path":"logs.debug.claim_lookup"}],"content":"Lookup result: claim_id=CLM-SYN-44501 member_id=MBR-SYN-8842 mrn=MRN-SYN-22091 address=101 Example Harbor Rd."}
Supported source layers:
user_messagerag_contexttool_outputmodel_inputmemorydebug_log
Destination paths may also point at model_provider.
The PHI policy is YAML. It maps detector categories to layer decisions:
version: 1
categories:
member_id:
description: Synthetic insurance member identifier.
high_risk: true
deny_layers:
- debug_log
redact_layers:
- model_input
- rag_context
- tool_output
- memory
redaction: "[REDACTED_MEMBER_ID]"
See Trace Schema and Policy Schema for the full contract.
Configuration You Provide
At minimum, callers provide a PHI policy YAML file. Keep it in the consuming
project's config path, for example config/phi-policy.yml, and review it with
the team that owns logging, prompting, memory, and trace retention.
If a project sends PHI to model providers or other covered services, also provide
a compliance policy YAML file, for example config/phi-compliance-policy.yml.
That file should be owned by the organization, not inferred by this package. The
guard only enforces the facts in the file; it does not verify contracts or vendor
terms.
Do not commit real PHI, real traces, raw provider payloads, raw logs, or generated reports that contain real PHI. The bundled samples are synthetic fixtures for development and documentation.
Operational Safety
- Treat every detector result as a PHI candidate, not confirmed PHI.
- Keep real PHI, raw provider payloads, raw logs, and reports containing real PHI out of source control.
- Remember that Markdown and JSON reports include matched values unless the caller keeps reports synthetic or adds its own report-value redaction workflow.
- Enable Presidio only in environments approved to process the text locally; it adds local candidate spans but does not replace policy review.
- Use
guard_compliancebefore routing PHI-bearing text to a covered service; the guard enforces only the BAA/service/model facts supplied by your organization.
What It Reports
The CLI writes two report formats from the same scan:
- Markdown for human review, with summary counts, boundary exposures, findings, sources, destinations, and recommended actions.
- JSON for CI, dashboards, or downstream audit storage.
Each finding includes the matched value, category, span, detector confidence, trace source, trace destinations, policy disposition, risk level, and suggested redaction value. Boundary exposures group the same PHI candidate across events, then sort by the worst policy disposition so violations rise to the top.
When --redacted-trace is provided, the CLI also writes a JSONL trace whose
content fields use policy redaction placeholders. Exact repeats of a detected
value are replaced across the trace.
Redaction is detector-driven. If the detector misses a value, the package cannot redact it, so production use still needs caller-side controls and human review.
The bundled regex detector now covers broader synthetic variants for phone numbers, fax numbers, email addresses, SSNs, street addresses, PO boxes, ZIP codes, healthcare dates, member/subscriber IDs, claims and authorization IDs, MRNs, policy/group/account/license/device/vehicle identifiers, URLs, and IP addresses. Optional Presidio support can add local NER spans for names, locations, dates, and other PII-like entities; policy decisions and redaction are still made by this package.
The synthetic trace corpus is documented in Trace Corpus.
Its committed coverage baseline is regenerated by tools/trace_corpus_report.py
and checked in CI.
Library API
After installing the package, other Python projects can import the scanner and redactor directly:
from pathlib import Path
from phi_boundary_gate import guard_text, load_policy
policy = load_policy(Path("config/phi-policy.yml"))
decision = guard_text(
"member_id=MBR-SYN-8842",
layer="debug_log",
policy=policy,
mode="block_on_violation",
)
if decision.should_block:
raise RuntimeError(decision.recommended_action)
safe_text = decision.redacted_text
guard_text handles PHI detection and layer policy only. It supports
report_only, redact, and block_on_violation modes. See
Library API for the typed ScanFinding and
GuardDecision shapes.
Projects that initialize .phi-boundary-gate/config.json can use the SDK facade:
from phi_boundary_gate import PhiBoundaryGate
gate = PhiBoundaryGate.from_project()
decision = gate.guard_model_input("member_id=MBR-SYN-8842")
if decision.should_block:
raise RuntimeError(decision.recommended_action)
safe_log_text = gate.redact_for_log("debug member_id=MBR-SYN-8842")
audit_payload = decision.to_safe_dict()
Compliance Guard
Projects that route PHI to covered services can run the compliance guard before provider calls:
from pathlib import Path
from phi_boundary_gate import (
ComplianceContext,
guard_compliance,
load_compliance_policy,
load_policy,
)
phi_policy = load_policy(Path("config/phi-policy.yml"))
compliance_policy = load_compliance_policy(Path("config/phi-compliance-policy.yml"))
decision = guard_compliance(
"member_id=MBR-SYN-8842",
layer="model_input",
phi_policy=phi_policy,
compliance_policy=compliance_policy,
context=ComplianceContext(
phi_status="real_phi",
vendor="google",
service="vertex_ai",
endpoint="generate_content",
model="gemini-2.5-pro",
feature="online_prediction",
environment="production",
logging="redacted_only",
storage="none",
),
)
if decision.should_block:
raise RuntimeError(decision.block_reasons)
text_for_model = decision.redacted_text
audit_payload = decision.to_dict()
The guard enforces facts supplied by your organization. It cannot discover whether a BAA is signed, whether a service is covered, or whether a vendor changed its terms. Keep the bundled compliance sample as a schema example, not a contract source of truth.
See Compliance Guard and Compliance Policy Schema.
Development
Set up a local development environment:
python3 -m pip install -e ".[dev]"
Run the tests:
PYTHONPATH=src python3 -m unittest discover -s tests
Current release: v0.5.0.
Limits
- No real PHI is stored in this repository.
- No HIPAA compliance guarantee is provided.
- No medical decision-making is performed.
- No automatic vendor contract discovery is attempted.
- Detector results are PHI candidates and need human review.
License
MIT - see LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file phi_boundary_gate-0.5.0.tar.gz.
File metadata
- Download URL: phi_boundary_gate-0.5.0.tar.gz
- Upload date:
- Size: 37.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5009873093937e98819a851c5c94b3d4ec2f4082544ddb8f7a350a93b1af0862
|
|
| MD5 |
fa1e7ca46bba41740fe692bfed5c0067
|
|
| BLAKE2b-256 |
cebf7d08a0bc257f19d8741e8dcac7667013ef5b5fc3a7e90c3d8de3ea3f4ded
|
Provenance
The following attestation bundles were made for phi_boundary_gate-0.5.0.tar.gz:
Publisher:
publish.yml on tigerless-labs/phi-boundary-gate
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
phi_boundary_gate-0.5.0.tar.gz -
Subject digest:
5009873093937e98819a851c5c94b3d4ec2f4082544ddb8f7a350a93b1af0862 - Sigstore transparency entry: 2335639224
- Sigstore integration time:
-
Permalink:
tigerless-labs/phi-boundary-gate@30334e62743e1943c5866bc0fbb19523005d5576 -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/tigerless-labs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@30334e62743e1943c5866bc0fbb19523005d5576 -
Trigger Event:
push
-
Statement type:
File details
Details for the file phi_boundary_gate-0.5.0-py3-none-any.whl.
File metadata
- Download URL: phi_boundary_gate-0.5.0-py3-none-any.whl
- Upload date:
- Size: 30.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
69fe5cdd2e3d152b7dfe997639f60ca8581f510aa5098eeb9cf6069feb906e57
|
|
| MD5 |
0e9a99980e75d7f5d874b7c309f4a6e2
|
|
| BLAKE2b-256 |
bb8b574711495d2f41c2327b62e43d5d58076ae934e12375acc88505db2c62eb
|
Provenance
The following attestation bundles were made for phi_boundary_gate-0.5.0-py3-none-any.whl:
Publisher:
publish.yml on tigerless-labs/phi-boundary-gate
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
phi_boundary_gate-0.5.0-py3-none-any.whl -
Subject digest:
69fe5cdd2e3d152b7dfe997639f60ca8581f510aa5098eeb9cf6069feb906e57 - Sigstore transparency entry: 2335639245
- Sigstore integration time:
-
Permalink:
tigerless-labs/phi-boundary-gate@30334e62743e1943c5866bc0fbb19523005d5576 -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/tigerless-labs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@30334e62743e1943c5866bc0fbb19523005d5576 -
Trigger Event:
push
-
Statement type: