Skip to content

Commit 0b8c14e

Browse files
committed
correctness pass - agent guardrails, intro, basics
1 parent 2eb36c5 commit 0b8c14e

File tree

8 files changed

+134
-140
lines changed

8 files changed

+134
-140
lines changed

docs/assets/invariant.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,11 @@ span.parser-badge::before {
516516
content: 'Built-in functions are pre-defined functions that are available for use in your code without requiring any additional imports.';
517517
}
518518

519+
.no-border-top_header {
520+
border-top: none !important;
521+
padding-top: 0pt !important;
522+
}
523+
519524
eb279c8597c001a60e752
520525
.parser-badge:hover::after,
521526
.detector-badge:hover::after,

docs/guardrails/basics.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ raise "Found pattern" if:
8080
# actual rule logic
8181
```
8282

83-
The rule logic above, will be applied to every `Message`, `ToolCall`, and `ToolOutput` object encountered during operation, enabling you to easily check your agents for bad behaviors.
83+
The rule logic above will be applied to every `Message`, `ToolCall`, and `ToolOutput` object encountered during operation, enabling you to easily check your agents for bad behaviors.
8484

8585
## Data Model
8686

@@ -111,7 +111,7 @@ class ImageContent(Content):
111111

112112
##### `role` <span class='type'>string</span> <span class='required'/>
113113

114-
The role of the event, e.g., `user`, `assistant`, `system` or something else.
114+
The role of the event, e.g., `user`, `assistant`, `system`, or something else.
115115

116116
##### `content` <span class='type'>string | list[Content]</span> <span class='optional'/>
117117

@@ -126,11 +126,11 @@ A list of tool calls made by the agent as part of this message.
126126
!!! note "Examples"
127127
Simple message
128128

129-
```
129+
```json
130130
{ "role": "user", "content": "Hello, how are you?" }
131131
```
132132

133-
Message with tool call
133+
A message with a tool call
134134

135135
```json
136136
{

docs/guardrails/code-validation.md

Lines changed: 52 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,59 @@ Code validation is a critical component of any code-generating LLM system, as it
1414
!!! danger "Code Validation Risks"
1515
Code validation is a critical component of any code-generating LLM system. An insecure agent could:
1616

17-
- Generate code that contains **security vulnerabilities**, such as SQL injection or cross-site scripting
18-
- Generate code that **contains bugs or errors**, causing the system to crash or behave unexpectedly
19-
- Produce code that escapes a **sandboxed execution environment**
20-
- Generate code that is **not well-formed or does not follow best practices**, causing the system to be difficult to maintain or understand
17+
- Generate code that contains **security vulnerabilities**, such as SQL injection or cross-site scripting.
18+
- Generate code that **contains bugs or errors**, causing the system to crash or behave unexpectedly.
19+
- Produce code that escapes a **sandboxed execution environment**.
20+
- Generate code that is **not well-formed or does not follow best practices**, causing the system to be difficult to maintain or understand.
2121

22-
To validate code as part of Guardrails, Invariant allows you to invoke external code checking tools as part of the guardrailing process. That means with Invariant you can build code validation right into your LLM layer, without worrying about it on the agent side.
22+
To validate code as part of Guardrails, Invariant allows you to invoke external code-checking tools as part of the guardrailing process. That means with Invariant you can build code validation right into your LLM layer, without worrying about it on the agent side.
2323

2424
For this, two main components are supported: (1) code parsing and (2) semgrep integration.
2525

26-
## Code Parsing
26+
## Code Parsing
2727

2828
The code parsing feature allows you to parse generated code, and access its abstract syntax tree, to implement custom validation rules.
2929

30-
This is useful for checking the structure and syntax of the code, as well as for identifying potential security vulnerabilities.
30+
This is useful for checking the structure and syntax of the code and identifying potential security vulnerabilities. Invariant provides the `python_code` function for this.
31+
32+
## python_code <span class="detector-badge"/> {: .no-border-top_header }
33+
```python
34+
def python_code(
35+
data: Union[str, List[str]],
36+
ipython_mode: bool = False
37+
) -> List[str]
38+
```
39+
40+
Parses the provided Python code and returns a `PythonDetectorResult` object.
41+
42+
**Parameters**
43+
44+
| Name | Type | Description |
45+
|-------------|--------|----------------------------------------|
46+
| `data` | `str | list | dict` | The Python code to be parsed. |
47+
| `ipython_mode` | `bool` | If set to <span class='boolean-value-true'>TRUE</span>, the code will be parsed in IPython mode. This is useful for parsing code that uses IPython-specific features or syntax. |
48+
49+
**Returns**
50+
51+
| Type | Description |
52+
|--------|----------------------------------------|
53+
| `PythonDetectorResult` | The result of the detector. |
54+
55+
56+
### `PythonDetectorResult` objects
57+
`PythonDetectorResult` objects represent the analysis results of a Python code snippet.
58+
59+
| Name | Type | Description |
60+
|-------------|--------|----------------------------------------|
61+
| `.imports` | `list[str]` | This field contains a list of imported modules in the provided code. It is useful for identifying which libraries or modules are being used in the code. |
62+
| `.builtins` | `list[str]` | A list of built-in functions used in the provided code. |
63+
| `.syntax_error` | `bool` | A boolean flag indicating whether the provided code has syntax errors. |
64+
| `.syntax_error_exception` | `str | None` | A string containing the exception message if a syntax error occurred while parsing the provided code. |
65+
| `.function_calls` | `set[str]` | A set of function call identifier names in the provided code. |
66+
67+
### Example Usage
68+
69+
The `eval` function in Python presents several potential security vulnerabilities, so you may want to prevent it from being present in generated code.
3170

3271
**Example:** Validating the function calls in a code snippet.
3372
```guardrail
@@ -56,12 +95,12 @@ Similarly, you can check for syntactic errors in the code, or check for the pres
5695

5796
**Example:** Validating the imports in a code snippet.
5897
```guardrail
59-
from invariant.detectors.code import ipython_code
98+
from invariant.detectors.code import python_code
6099
61100
raise "syntax error" if:
62101
(call: ToolCall)
63102
call.function.name == "ipython"
64-
ipython_code(call.function.arguments.code).syntax_error
103+
python_code(call.function.arguments.code).syntax_error
65104
```
66105
```example-trace
67106
[
@@ -88,55 +127,6 @@ raise "syntax error" if:
88127
]
89128
```
90129

91-
<!-- template -->
92-
<!-- **Parameters**
93-
94-
| Name | Type | Description |
95-
|-------------|--------|----------------------------------------|
96-
| `data` | `Union[str, List[str]]` | A single message or a list of messages to detect PII in. |
97-
| `entities` | `Optional[List[str]]` | A list of [PII entity types](https://microsoft.github.io/presidio/supported_entities/) to detect. Defaults to detecting all types. |
98-
99-
**Returns**
100-
101-
| Type | Description |
102-
|--------|----------------------------------------|
103-
| `List[str]` | A list of all the detected PII in `data` | -->
104-
105-
## python_code <span class="detector-badge"/>
106-
```python
107-
def python_code(
108-
data: Union[str, List[str]],
109-
ipython_mode: bool = False
110-
) -> List[str]
111-
```
112-
113-
Parses provided Python code and returns a `PythonDetectorResult` object.
114-
115-
**Parameters**
116-
117-
| Name | Type | Description |
118-
|-------------|--------|----------------------------------------|
119-
| `data` | `str | list | dict` | The Python code to be parsed. |
120-
| `ipython_mode` | `bool` | If set to <span class='boolean-value-true'>TRUE</span>, the code will be parsed in IPython mode. This is useful for parsing code that uses IPython-specific features or syntax. |
121-
122-
**Returns**
123-
124-
| Type | Description |
125-
|--------|----------------------------------------|
126-
| `PythonDetectorResult` | The result of the detector. |
127-
128-
129-
### `PythonDetectorResult` objects
130-
`PythonDetectorResult` objects represent the analysis results of a Python code snippet.
131-
132-
| Name | Type | Description |
133-
|-------------|--------|----------------------------------------|
134-
| `.imports` | `list[str]` | This field contains a list of imported modules in the provided code. It is useful for identifying which libraries or modules are being used in the code. |
135-
| `.builtins` | `list[str]` | A list of built-in functions used in the provided code. |
136-
| `.syntax_error` | `bool` | A boolean flag indicating whether the provided code has syntax errors. |
137-
| `.syntax_error_exception` | `str | None` | A string containing the exception message if a syntax error occurred while parsing the provided code. |
138-
| `.function_calls` | `set[str]` | A set of function call identifier names in the provided code. |
139-
140130
## Static Code Analysis
141131

142132
Static code analysis allows for powerful pattern-based detection of vulnerabilities and insecure coding practices. Invariant integrates [Semgrep](https://semgrep.dev) directly into your guardrails, enabling deep analysis of assistant-generated code before it's executed.
@@ -151,7 +141,7 @@ Static code analysis allows for powerful pattern-based detection of vulnerabilit
151141

152142
You can use `semgrep` within a guardrail to scan code in Python, Bash, and other supported languages.
153143

154-
## semgrep <span class="detector-badge"></span> <span class="high-latency"></span>
144+
## semgrep <span class="detector-badge"></span> <span class="high-latency"></span> {: .no-border-top_header }
155145
```python
156146
def semgrep(
157147
data: str | list | dict,
@@ -165,7 +155,7 @@ Scans the given code using [Semgrep](http://semgrep.dev) and returns a list of `
165155

166156
| Name | Type | Description |
167157
|---------|-----------------------|-------------------------------------------------------|
168-
| `data` | `str | list | dict` | The code to scan. Can be a single string or list. |
158+
| `data` | `str | list | dict` | The code to scan. This can be a single string or list. |
169159
| `lang` | `str` | Programming language (`"python"`, `"bash"`, etc). |
170160

171161
**Returns**
@@ -188,13 +178,11 @@ class CodeSeverity(str, Enum)
188178
| `.description` | `str` | Description of the issue. |
189179
| `.severity` | `CodeSeverity` | Severity of the issue (e.g., "HIGH", "MEDIUM"). |
190180

191-
---
192-
193181
### Example Usage
194182

195-
Use semgrep to perform deep static analysis and identify potential vulnerabilities, bad practices, or policy violations in code. It complements python_code by enabling more powerful pattern-based detection.
183+
Use semgrep to perform deep static analysis and identify potential vulnerabilities, bad practices, or policy violations in code. It complements `python_code` by enabling more powerful pattern-based detection.
196184

197-
**Example:** Detecting Dangerous Patterns in Python Code
185+
**Example:** Detecting dangerous patterns in Python code.
198186
```guardrail
199187
from invariant.detectors import semgrep
200188

docs/guardrails/dataflow-rules.md

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,28 +19,28 @@ For instance, your agent may access an internal source of information like a dat
1919

2020
Invariant allows you to detect such contextually sensitive dataflow, and prevent it from happening.
2121

22-
This chapter discusses how Invariant Guardrails can be used to secure agentic dataflow, and make sure that sensitive data never leaves the system through unintended channels.
22+
This chapter discusses how Invariant Guardrails can be used to secure agentic dataflow and make sure that sensitive data never leaves the system through unintended channels.
2323

2424
<div class='risks'/>
2525
> **Dataflow Risks**<br/>
2626
2727
> Due to their dynamic nature, agentic systems often mix and combine data from different sources, and can easily leak sensitive information. For example, an insecure agent could:
2828
29-
> * Leak sensitive information, such as **API keys or passwords**, to an external service
29+
> * Leak sensitive information, such as **API keys or passwords**, to an external service.
3030
31-
> * Send sensitive information, such as **user data or PII**, to an external service
31+
> * Send sensitive information, such as **user data or PII**, to an external service.
3232
33-
> * Be prompt-injected by an external service via indirect channels, to **perform malicious actions** as injected by an potential attacker
33+
> * Be prompt-injected by an external service via indirect channels, to **perform malicious actions** as injected by a potential attacker.
3434
3535
## The Flow Operator `->`
3636

3737
<img src="site:/guardrails/flow.svg" alt="Flow Operator" class="flow-operator" style="display: block; margin: 40pt auto; width: 100%; max-width: 400pt;"/>
3838

39-
At the center of Invariant's data flow checking is the flow operator `->`. This operator enables you to precisely detect flows and ordering of operations in an agent trace.
39+
At the center of Invariant's data flow checking is the flow operator `->`. This operator enables you to precisely detect flows and the ordering of operations in an agent trace.
4040

41-
For example, to prevent a user message with the content `"send"` from triggering a `send_email` tool call, you can use the following rule:
41+
For example, to prevent a user message with the content `"send"` from triggering a `send_email` tool call, you can use the following rule.
4242

43-
**Example:** Preventing a simple flow
43+
**Example:** Preventing a simple flow.
4444
```guardrail
4545
raise "Must not call tool after user uses keyword" if:
4646
(msg: Message) -> (tool: ToolCall)
@@ -66,11 +66,12 @@ raise "Must not call tool after user uses keyword" if:
6666
}
6767
]
6868
```
69-
Evaluating this rule will highlight both, the relevant part of the user message, as well as the subsequent `send_email` call:
69+
70+
Evaluating this rule will highlight both the relevant part of the user message and the subsequent `send_email` call:
7071

7172
<img src="site:/guardrails/flow.png" alt="Flow Operator" class="flow-operator" style="display: block; margin: 0 auto; width: 100%; max-width: 500pt;"/>
7273

73-
This rule will raise an error on the given trace, because a user message with the content `"send"` is followed by a `send_email` tool call, and thus makes it impossible to send an email after the user uses the keyword `"send"`.
74+
This rule will raise an error on the given trace because a user message with the content `"send"` is followed by a `send_email` tool call, and thus makes it impossible to send an email after the user uses the keyword `"send"`.
7475

7576
Here, the line `(msg: Message) -> (tool: ToolCall)` specifies that the rule only applies, when a `Message` is followed by a `ToolCall`, where `msg` and `tool` are further constrained by the extra conditions in the following lines.
7677

@@ -119,9 +120,9 @@ raise "Must not call tool after user uses keyword" if:
119120
]
120121
```
121122

122-
Note that for this you have to use the `->` operator twice, in separate lines, to express the transitive connection between `msg`, `tool` and `tool2`.
123+
Note that for this you have to use the `->` operator twice, in separate lines, to express the transitive connection between `msg`, `tool`, and `tool2`.
123124

124-
## Direct Succession Flows with `~>`
125+
## Direct Succession Flows `~>`
125126

126127
<img src="site:/guardrails/direct-flow.svg" alt="Flow Operator" class="flow-operator" style="display: block; margin: 40pt auto; width: 100%; max-width: 400pt;"/>
127128

@@ -196,8 +197,6 @@ In a trace, this looks like this:
196197

197198
Here, the `ToolOutput` is a direct successor of the `ToolCall`, and thus the rule will match.
198199

199-
---
200-
201200
## Combining Content Guardrails with Dataflow Rules
202201

203202
Naturally, the `->` operator can also be combined with content guardrails, to specify more complex rules.

0 commit comments

Comments
 (0)