Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/ref/extensions/memory/encrypt_session.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# `Encrypt Session`
# `EncryptedSession`

::: agents.extensions.memory.encrypt_session
::: agents.extensions.memory.encrypt_session.EncryptedSession
53 changes: 53 additions & 0 deletions docs/sessions.md
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,57 @@ if __name__ == "__main__":
asyncio.run(main())
```

### Encrypted sessions

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]`.

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.

**Example: Encrypting SQLAlchemy session data**

```python
import asyncio
from agents import Agent, Runner
from agents.extensions.memory import EncryptedSession, SQLAlchemySession

async def main():
# Create underlying session (works with any SessionABC implementation)
underlying_session = SQLAlchemySession.from_url(
session_id="user-123",
url="postgresql+asyncpg://app:secret@db.example.com/agents",
create_tables=True,
)

# Wrap with encryption and TTL-based expiration
session = EncryptedSession(
session_id="user-123",
underlying_session=underlying_session,
encryption_key="your-encryption-key", # Use a secure key from your secrets management
ttl=600, # 10 minutes - items older than this are silently skipped
)

agent = Agent("Assistant")
result = await Runner.run(agent, "Hello", session=session)
print(result.final_output)

if __name__ == "__main__":
asyncio.run(main())
```

**Key features:**

- **Transparent encryption**: Automatically encrypts all session items before storage and decrypts on retrieval
- **Per-session key derivation**: Uses HKDF with the session ID as salt to derive unique encryption keys
- **TTL-based expiration**: Automatically expires old messages based on configurable time-to-live (default: 10 minutes)
- **Flexible key input**: Accepts either Fernet keys or raw strings as encryption keys
- **Wraps any session**: Works with SQLite, SQLAlchemy, or custom session implementations

!!! warning "Important security notes"

- Store your encryption key securely (e.g., environment variables, secrets manager)
- 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
- The underlying session still stores encrypted data, so you maintain control over your database infrastructure


## Custom memory implementations

Expand Down Expand Up @@ -304,6 +355,7 @@ Use meaningful session IDs that help you organize conversations:
- Use file-based SQLite (`SQLiteSession("session_id", "path/to/db.sqlite")`) for persistent conversations
- Use SQLAlchemy-powered sessions (`SQLAlchemySession("session_id", engine=engine, create_tables=True)`) for production systems with existing databases supported by SQLAlchemy
- Use OpenAI-hosted storage (`OpenAIConversationsSession()`) when you prefer to store history in the OpenAI Conversations API
- Use encrypted sessions (`EncryptedSession(session_id, underlying_session, encryption_key)`) to wrap any session with transparent encryption and TTL-based expiration
- Consider implementing custom session backends for other production systems (Redis, Django, etc.) for more advanced use cases

### Session management
Expand Down Expand Up @@ -402,3 +454,4 @@ For detailed API documentation, see:
- [`SQLiteSession`][agents.memory.SQLiteSession] - SQLite implementation
- [`OpenAIConversationsSession`](ref/memory/openai_conversations_session.md) - OpenAI Conversations API implementation
- [`SQLAlchemySession`][agents.extensions.memory.sqlalchemy_session.SQLAlchemySession] - SQLAlchemy-powered implementation
- [`EncryptedSession`][agents.extensions.memory.encrypt_session.EncryptedSession] - Encrypted session wrapper with TTL
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ plugins:
- ref/extensions/handoff_prompt.md
- ref/extensions/litellm.md
- ref/extensions/memory/sqlalchemy_session.md
- ref/extensions/memory/encrypt_session.md

- locale: ja
name: 日本語
Expand Down