You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/sessions.md
+53Lines changed: 53 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -242,6 +242,57 @@ if __name__ == "__main__":
242
242
asyncio.run(main())
243
243
```
244
244
245
+
### Encrypted sessions
246
+
247
+
For applications requiring encryption of conversation data at rest, you can use `EncryptedSession` to wrap any session backend with transparent encryption and automatic TTL-based expiration. This requires the `encrypt` extra: `pip install openai-agents[encrypt]`.
248
+
249
+
The `EncryptedSession` uses Fernet encryption with per-session key derivation (HKDF) and supports automatic expiration of old messages. When items exceed the TTL, they are silently skipped during retrieval.
250
+
251
+
**Example: Encrypting SQLAlchemy session data**
252
+
253
+
```python
254
+
import asyncio
255
+
from agents import Agent, Runner
256
+
from agents.extensions.memory import EncryptedSession, SQLAlchemySession
257
+
258
+
asyncdefmain():
259
+
# Create underlying session (works with any SessionABC implementation)
encryption_key="your-encryption-key", # Use a secure key from your secrets management
271
+
ttl=600, # 10 minutes - items older than this are silently skipped
272
+
)
273
+
274
+
agent = Agent("Assistant")
275
+
result =await Runner.run(agent, "Hello", session=session)
276
+
print(result.final_output)
277
+
278
+
if__name__=="__main__":
279
+
asyncio.run(main())
280
+
```
281
+
282
+
**Key features:**
283
+
284
+
-**Transparent encryption**: Automatically encrypts all session items before storage and decrypts on retrieval
285
+
-**Per-session key derivation**: Uses HKDF with the session ID as salt to derive unique encryption keys
286
+
-**TTL-based expiration**: Automatically expires old messages based on configurable time-to-live (default: 10 minutes)
287
+
-**Flexible key input**: Accepts either Fernet keys or raw strings as encryption keys
288
+
-**Wraps any session**: Works with SQLite, SQLAlchemy, or custom session implementations
289
+
290
+
!!! warning "Important security notes"
291
+
292
+
- Store your encryption key securely (e.g., environment variables, secrets manager)
293
+
- Expired tokens are rejected based on the application server's system clock - ensure all servers are time-synchronized with NTP to avoid valid tokens being rejected due to clock drift
294
+
- The underlying session still stores encrypted data, so you maintain control over your database infrastructure
295
+
245
296
246
297
## Custom memory implementations
247
298
@@ -304,6 +355,7 @@ Use meaningful session IDs that help you organize conversations:
304
355
- Use file-based SQLite (`SQLiteSession("session_id", "path/to/db.sqlite")`) for persistent conversations
305
356
- Use SQLAlchemy-powered sessions (`SQLAlchemySession("session_id", engine=engine, create_tables=True)`) for production systems with existing databases supported by SQLAlchemy
306
357
- Use OpenAI-hosted storage (`OpenAIConversationsSession()`) when you prefer to store history in the OpenAI Conversations API
358
+
- Use encrypted sessions (`EncryptedSession(session_id, underlying_session, encryption_key)`) to wrap any session with transparent encryption and TTL-based expiration
307
359
- Consider implementing custom session backends for other production systems (Redis, Django, etc.) for more advanced use cases
308
360
309
361
### Session management
@@ -402,3 +454,4 @@ For detailed API documentation, see:
0 commit comments