tealtiger-semantic-kernel
Deterministic governance filter for Semantic Kernel — function-call authorization, PII scanning, cost budgets, and structured audit trail.
<2ms per evaluation. No LLM in the governance path. Apache 2.0.
What it does
tealtiger-semantic-kernel adds a governance layer to Semantic Kernel agents using the native Filter system. Before any function executes (whether invoked directly or auto-invoked by the LLM planner), the filter evaluates your policy and returns ALLOW or DENY.
| Capability | What it protects |
|---|---|
| Function allowlist/denylist | Control which plugins and functions can be called. Block dangerous tools. |
| PII scanning | Detect emails, phone numbers, SSNs, credit cards in function arguments. |
| Secret scanning | Detect hardcoded API keys, passwords, tokens before they reach external services. |
| Cost budget | Per-session and daily USD limits with reserve-then-reconcile tracking. |
| Kill switch | Instantly freeze a runaway agent. Terminate the entire invocation loop. |
| Structured audit | Every decision logged: correlation_id, action, reason_codes, risk_score, timing. |
Key Design
Addressing the critique in issue #14056:
- AutoFunctionInvocationFilter: On DENY, sets
context.terminate = TrueAND does NOT callnext(). This terminates the entire invocation loop — the LLM planner cannot continue calling more functions. - Budget: Uses reserve-then-reconcile — estimated cost is debited before the function runs, then reconciled with actual cost after. Prevents overspend in parallel scenarios.
Quick Start
1. Install
pip install tealtiger-semantic-kernel
2. Configure and register
import semantic_kernel as sk
from tealtiger_semantic_kernel import (
TealTigerFilter,
GovernancePolicy,
FunctionPolicy,
PIIScanPolicy,
BudgetTracker,
)
# Define policy
policy = GovernancePolicy(
mode="ENFORCE",
function_policy=FunctionPolicy(
denylist=["HttpPlugin-*", "*-delete_*"],
allowlist=["MathPlugin-*", "TextPlugin-*"],
),
pii_scan=PIIScanPolicy(enabled=True, action="block"),
)
# Budget: $5 per session, $20 daily
budget = BudgetTracker(per_session_usd=5.00, per_agent_daily_usd=20.00)
# Create filter
gov = TealTigerFilter(policy=policy, budget=budget, session_id="session-001")
# Register with Semantic Kernel
kernel = sk.Kernel()
kernel.add_filter("function_invocation", gov.function_invocation_filter)
kernel.add_filter("auto_function_invocation", gov.auto_function_invocation_filter)
3. Done
Every function call — whether directly invoked or auto-invoked by the LLM planner — is evaluated against your governance policy before execution.
Governance Modes
| Mode | Behavior |
|---|---|
ENFORCE |
Block violations. Auto-invocations terminate the loop. Direct invocations raise GovernanceDenyError. |
MONITOR |
Log violations but allow execution. For rollout testing. |
OBSERVE |
Passthrough with full audit trail. Zero enforcement. |
Start with OBSERVE to see what your agent does, then move to MONITOR, then ENFORCE.
Policy Configuration
Function allowlist/denylist
Patterns use plugin_name-function_name with glob matching:
FunctionPolicy(
denylist=[
"HttpPlugin-*", # Block entire plugin
"*-delete_*", # Block any delete function
"FilePlugin-write_file", # Block specific function
],
allowlist=[
"MathPlugin-*", # Allow entire plugin
"TextPlugin-summarize", # Allow specific function
],
)
Denylist is checked first. If allowlist is non-empty, functions must match at least one pattern.
PII Scanning
PIIScanPolicy(
enabled=True,
action="block", # "block" | "redact" | "log"
categories=["email", "phone", "ssn", "credit_card"],
)
Secret Scanning
SecretScanPolicy(
enabled=True,
action="block",
categories=["api_key", "password", "token", "private_key", "aws_key"],
)
Budget Tracking
Reserve-then-reconcile prevents overspend:
budget = BudgetTracker(per_session_usd=5.00, per_agent_daily_usd=20.00)
# Before function call:
budget.reserve(0.05) # Returns False if would exceed limit
# After function call:
budget.reconcile(actual_cost=0.03, reserved=0.05) # Frees $0.02 back
# Check current state:
print(f"Spent: ${budget.spent:.4f}")
print(f"Remaining: ${budget.remaining:.4f}")
Kill Switch
# Emergency freeze
gov.freeze()
# Resume normal operation
gov.unfreeze()
When frozen, ALL invocations are blocked with context.terminate = True.
Audit Trail
# Get all decisions
for decision in gov.audit_trail:
print(decision.to_dict())
Each decision includes:
{
"correlation_id": "uuid-v4",
"timestamp_ms": 1719849600000,
"action": "DENY",
"reason": "Function denied: 'HttpPlugin-fetch_url' matches denylist pattern 'HttpPlugin-*'",
"reason_codes": ["FUNCTION_DENIED"],
"risk_score": 0.9,
"evaluation_time_ms": 0.4,
"function_name": "fetch_url",
"plugin_name": "HttpPlugin",
"session_id": "session-001",
"cumulative_cost": 0.0340
}
How it works
LLM decides to call a function
→ Semantic Kernel AutoFunctionInvocationFilter fires
→ TealTigerFilter evaluates governance policy (<2ms)
→ If ALLOW:
Reserve budget → call next(context) → reconcile budget
→ If DENY (ENFORCE mode):
Set context.terminate = True
Do NOT call next()
→ Entire invocation loop terminates
→ LLM planner cannot call more functions
→ Decision appended to audit trail
Related
- TealTiger — Core governance SDK
- Semantic Kernel Filters — Filter system reference
- GitHub Issue #14056 — Governance integration proposal
License
Apache 2.0
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 tealtiger_semantic_kernel-0.1.0.tar.gz.
File metadata
- Download URL: tealtiger_semantic_kernel-0.1.0.tar.gz
- Upload date:
- Size: 16.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a6c047f086a257a5f99c3ca36a6249221f4a6222257f6d92a64dc7e66e161c46
|
|
| MD5 |
ca49b744a2bc0941f4a7550d1e249e86
|
|
| BLAKE2b-256 |
d8057bac8461ab848d8fce483f87ce0a43db06202d3f14bfa6903efaa6052e56
|
File details
Details for the file tealtiger_semantic_kernel-0.1.0-py3-none-any.whl.
File metadata
- Download URL: tealtiger_semantic_kernel-0.1.0-py3-none-any.whl
- Upload date:
- Size: 14.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8afd29ebe949f2c6efb48757578214357c6b59df68fd6761a0dff9a20d0cf059
|
|
| MD5 |
5b9edf75b755f7f9afeb330d35fcbeef
|
|
| BLAKE2b-256 |
06aec1cf19c6c34180f314d43018e208efb22107bcec0341854781bc69953117
|