Skip to content

Commit 9b9fb52

Browse files
authored
Improve docs regarding security (#119)
1 parent 10b1752 commit 9b9fb52

1 file changed

Lines changed: 79 additions & 7 deletions

File tree

splunklib/ai/README.md

Lines changed: 79 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,9 @@ async with Agent(
647647
await agent.invoke(...)
648648
```
649649

650-
**Note**: Input schemas can only be used by subagents, not by regular agents. When invoking agents with external data, see [Security](#security) for guidance on how to do this safely.
650+
> **Note**: Input schemas can only be used by subagents, not by regular agents. When invoking agents with external data, see [Security](#security) for guidance on how to do this safely.
651+
652+
> **Note**: Subagents with an `input_schema` receive their input via `invoke_with_data`, which separates instructions from data and reduces the risk of prompt injection. Subagents without an `input_schema` receive their input as a plain message, which provides weaker injection resistance - use them with caution when the supervisor may pass untrusted data.
651653
652654
## Middleware
653655

@@ -1003,9 +1005,27 @@ Additionally logs from local tools are also forwarded to this logger.
10031005

10041006
## Security
10051007

1006-
When invoking the agent with external data (log entries, alert payloads, API responses, etc.),
1007-
use `invoke_with_data` instead of `invoke`. It separates your instructions from the untrusted
1008-
data, reducing the risk of prompt injection:
1008+
The SDK provides layered, automatic defenses and opt-in utilities to help you build secure
1009+
agentic applications. Automatic protections are active for every agent with no configuration
1010+
required. Opt-in utilities give you additional control where your use case requires it.
1011+
1012+
### What's on by default
1013+
1014+
| Protection | Default |
1015+
|---|---|
1016+
| Token limit | 200 000 tokens |
1017+
| Step limit | 100 steps |
1018+
| Timeout | 600 seconds per `invoke` |
1019+
| System prompt hardening | Automatic - security rules are appended to every agent's system prompt |
1020+
1021+
See [Overriding defaults](#overriding-defaults) to customize or override these limits.
1022+
1023+
### Prompt injection
1024+
1025+
The SDK automatically appends injection-resistance rules to every agent's system prompt, so you
1026+
do not need to add them manually. For additional protection when passing external or user-supplied
1027+
data into the agent, use `invoke_with_data` instead of `invoke`. It separates your instructions
1028+
from the untrusted data, reducing the risk of prompt injection:
10091029

10101030
```py
10111031
from splunklib.ai.messages import HumanMessage
@@ -1035,6 +1055,7 @@ result = await agent.invoke([
10351055
])
10361056
```
10371057

1058+
For additional opt-in protection, the SDK provides `truncate_input` and `detect_injection`.
10381059
`truncate_input` caps the input length inline when constructing a message. `detect_injection`
10391060
scans for common injection patterns - one way to apply it consistently is via `agent_middleware`,
10401061
which gives you a single place to enforce the policy across every `invoke()` call. You decide
@@ -1068,10 +1089,61 @@ async with Agent(
10681089
await agent.invoke([HumanMessage(content=truncate_input(user_input))])
10691090
```
10701091

1071-
The SDK provides structural defenses. App developers are recommended to:
1092+
### Tool and subagent results
1093+
1094+
Tool results and subagent responses are delivered to the LLM using the `tool` message role,
1095+
which models recognize as data rather than instructions. In addition, the SDK automatically
1096+
appends security rules to every agent's system prompt instructing the LLM to treat all tool
1097+
and subagent results as data to analyze, not commands to execute.
1098+
1099+
Subagents are internally represented as tools - their responses go through the same `tool`
1100+
message role and are covered by the same system prompt rules.
1101+
1102+
These defenses significantly reduce the risk of indirect prompt injection through results,
1103+
but they are not a 100% guarantee. Developers should:
1104+
1105+
- Use models that reliably respect message roles and system prompt instructions
1106+
- Validate or sanitize results from external systems before passing them through tools or subagents
1107+
- Apply the principle of least privilege - the fewer tools an agent has, the smaller the
1108+
attack surface if a result is adversarial
1109+
1110+
### Audit logging
1111+
1112+
The SDK's built-in logger (see [Logger](#logger)) emits structured debug events for tool calls,
1113+
subagent calls, and model interactions. These events include tool names, call IDs, and
1114+
success/failure status - metadata only, never message content.
1115+
1116+
When adding custom logging via middleware or hooks, avoid logging message content or any data
1117+
that may contain sensitive information or PII. Log metadata instead:
1118+
1119+
```py
1120+
from splunklib.ai.middleware import tool_middleware, ToolMiddlewareHandler, ToolRequest, ToolResponse
1121+
1122+
@tool_middleware
1123+
async def audit_tool_calls(request: ToolRequest, handler: ToolMiddlewareHandler) -> ToolResponse:
1124+
logger.info("tool_call started", extra={"tool": request.call.name})
1125+
return await handler(request)
1126+
```
1127+
1128+
### Developer responsibility
1129+
1130+
The SDK provides structural guardrails, but cannot enforce every security rule for every use
1131+
case. As the application developer, you are responsible for the data that flows through your
1132+
application and into the LLM.
1133+
1134+
We recommend that you:
1135+
1136+
- Audit which data sources feed into `invoke` / `invoke_with_data` and verify that no
1137+
sensitive data is included unintentionally
1138+
- Use the logger and middleware to observe agent behavior during development and confirm
1139+
that data flows match your expectations
1140+
- Choose an LLM provider appropriate for your data sensitivity requirements - for example,
1141+
a self-hosted model for highly sensitive or regulated data
1142+
1143+
### Further reading
10721144

1073-
- Use `invoke_with_data` whenever passing external or user-supplied data to the agent
1074-
- Ensure tool return values contain only the data the LLM needs
1145+
For a comprehensive overview of LLM-specific risks, see the
1146+
[OWASP Top 10 for LLM Applications 2025](https://owasp.org/www-project-top-10-for-large-language-model-applications/).
10751147

10761148
## Known issues
10771149

0 commit comments

Comments
 (0)