Encrypted session
encrypted_session ¶
Encrypted session service wrapping ADK's DatabaseSessionService.
Provides transparent field-level encryption for session state and event data by subclassing DatabaseSessionService and injecting encrypted SQLAlchemy model classes via _get_schema_classes() and prepare_tables() overrides. All CRUD operations are delegated to the parent class — no method overrides needed.
SQLAlchemy (with the asyncio extra) is declared as a direct dependency of this package: google-adk 2.x moved it behind its optional db extra, so it can no longer be inherited transitively. aiosqlite, the driver behind the default sqlite+aiosqlite:// URL, is declared for the same reason.
Examples:
Basic usage with FernetBackend:
from adk_secure_sessions import FernetBackend, EncryptedSessionService
backend = FernetBackend("my-secret-passphrase")
service = EncryptedSessionService(
db_url="sqlite+aiosqlite:///sessions.db",
backend=backend,
)
session = await service.create_session(
app_name="my-agent",
user_id="user-123",
state={"secret": "sensitive-data"},
)
Multi-backend migration (Fernet to AES-256-GCM):
from adk_secure_sessions import (
AesGcmBackend,
FernetBackend,
EncryptedSessionService,
)
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
fernet = FernetBackend("old-passphrase")
aes_gcm = AesGcmBackend(key=AESGCM.generate_key(bit_length=256))
service = EncryptedSessionService(
db_url="sqlite+aiosqlite:///sessions.db",
backend=aes_gcm,
additional_backends=[fernet],
)
See Also
adk_secure_sessions.backends.fernet: Fernet encryption backend. adk_secure_sessions.protocols: EncryptionBackend protocol definition.
EncryptedSessionService ¶
Bases: DatabaseSessionService
flowchart TD
adk_secure_sessions.services.encrypted_session.EncryptedSessionService[EncryptedSessionService]
click adk_secure_sessions.services.encrypted_session.EncryptedSessionService href "" "adk_secure_sessions.services.encrypted_session.EncryptedSessionService"
Encrypted session service wrapping DatabaseSessionService.
Subclasses ADK's DatabaseSessionService to inject encrypted SQLAlchemy models via _get_schema_classes() and prepare_tables(). All CRUD methods (create_session, get_session, list_sessions, delete_session, append_event) are inherited without modification.
Supports multiple encryption backends for incremental migration. The backend parameter is the primary backend used for new writes. The additional_backends parameter provides legacy decrypt capability. Backends are fixed after construction — they cannot be added or removed post-init.
| ATTRIBUTE | DESCRIPTION |
|---|---|
db_engine | The SQLAlchemy async engine (inherited). TYPE: |
Examples:
Create a service with SQLite:
from adk_secure_sessions import FernetBackend, EncryptedSessionService
backend = FernetBackend("my-secret-passphrase")
service = EncryptedSessionService(
db_url="sqlite+aiosqlite:///sessions.db",
backend=backend,
)
session = await service.create_session(
app_name="my-agent",
user_id="user-123",
state={"secret": "sensitive-data"},
)
Multi-backend migration (new writes use AES-GCM, legacy Fernet sessions remain readable):
from adk_secure_sessions import (
AesGcmBackend,
FernetBackend,
EncryptedSessionService,
)
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
fernet = FernetBackend("old-passphrase")
aes_gcm = AesGcmBackend(key=AESGCM.generate_key(bit_length=256))
service = EncryptedSessionService(
db_url="sqlite+aiosqlite:///sessions.db",
backend=aes_gcm,
additional_backends=[fernet],
)
Source code in src/adk_secure_sessions/services/encrypted_session.py
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 | |
__init__ ¶
__init__(
db_url: str,
backend: EncryptionBackend,
additional_backends: Sequence[EncryptionBackend] = (),
**kwargs: Any,
) -> None
Initialize the encrypted session service.
Uses backend.sync_encrypt, backend.sync_decrypt, and backend.backend_id from the protocol to configure the EncryptedJSON TypeDecorator. When additional_backends are provided, their decrypt functions are included in the dispatch map (keyed by backend_id) for reading legacy-encrypted data.
Backends are fixed after construction. The cache_ok = True on EncryptedJSON means SQLAlchemy may cache the type instance — post-init mutation would be a correctness bug.
| PARAMETER | DESCRIPTION |
|---|---|
db_url | SQLAlchemy connection string (e.g., TYPE: |
backend | Primary encryption backend. Used for all new writes and included in the decrypt dispatch map. TYPE: |
additional_backends | Extra backends for decrypt-only dispatch. Each must conform to TYPE: |
| PARAMETER | DESCRIPTION |
|---|---|
**kwargs | Additional keyword arguments passed to TYPE: |
| RAISES | DESCRIPTION |
|---|---|
ConfigurationError | If backend or any entry in additional_backends does not conform to |
Source code in src/adk_secure_sessions/services/encrypted_session.py
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | |
prepare_tables async ¶
Create encrypted tables using custom DeclarativeBase metadata.
Overrides the parent hook to use our encrypted model metadata instead of ADK's built-in schema. Upstream calls this lazily before every CRUD operation; it is safe to call eagerly at startup and safe to call more than once.
ADK renamed this hook from _prepare_tables() to the public prepare_tables() in google-adk 2.4.0. _prepare_tables below keeps the older call path working.