or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

client-side-encryption.mddynamodb.mdexperimental.mdindex.mds3-operations.mdsession-management.md

client-side-encryption.mddocs/

0

# Client-Side Encryption

1

2

Advanced S3 client-side encryption capabilities for secure data storage with async support. The S3 CSE (Client-Side Encryption) functionality provides encryption and decryption of data before sending to or receiving from S3, ensuring data security at rest and in transit.

3

4

## Capabilities

5

6

### S3 CSE Client

7

8

Main client-side encryption client that wraps S3 operations with encryption/decryption capabilities.

9

10

```python { .api }

11

class S3CSEClient:

12

def __init__(

13

self,

14

s3_client,

15

kms_key_id: str = None,

16

encryption_key = None,

17

key_wrap_algorithm: str = None

18

):

19

"""

20

Initialize S3 client-side encryption client.

21

22

Parameters:

23

- s3_client: Underlying S3 client

24

- kms_key_id: KMS key ID for key encryption

25

- encryption_key: Master encryption key

26

- key_wrap_algorithm: Algorithm for key wrapping

27

"""

28

29

async def __aenter__(self):

30

"""

31

Async context manager entry.

32

33

Returns:

34

self: The S3CSEClient instance

35

"""

36

37

async def __aexit__(self, exc_type, exc_val, exc_tb):

38

"""

39

Async context manager exit.

40

41

Parameters:

42

- exc_type: Exception type if an exception occurred

43

- exc_val: Exception value if an exception occurred

44

- exc_tb: Exception traceback if an exception occurred

45

"""

46

47

async def put_object(self, **kwargs):

48

"""

49

Put an encrypted object to S3.

50

51

Parameters:

52

- Bucket: S3 bucket name

53

- Key: S3 object key

54

- Body: Object body (will be encrypted)

55

- **kwargs: Additional S3 put_object parameters

56

57

Returns:

58

Response from S3 put_object operation

59

"""

60

61

async def get_object(self, **kwargs):

62

"""

63

Get and decrypt an object from S3.

64

65

Parameters:

66

- Bucket: S3 bucket name

67

- Key: S3 object key

68

- **kwargs: Additional S3 get_object parameters

69

70

Returns:

71

Decrypted response with Body containing decrypted data

72

"""

73

74

async def upload_file(

75

self,

76

filename: str,

77

bucket: str,

78

key: str,

79

**kwargs

80

):

81

"""

82

Upload and encrypt a file to S3.

83

84

Parameters:

85

- filename: Local file path

86

- bucket: S3 bucket name

87

- key: S3 object key

88

- **kwargs: Additional upload parameters

89

"""

90

91

async def download_file(

92

self,

93

bucket: str,

94

key: str,

95

filename: str,

96

**kwargs

97

):

98

"""

99

Download and decrypt a file from S3.

100

101

Parameters:

102

- bucket: S3 bucket name

103

- key: S3 object key

104

- filename: Local file path to save decrypted data

105

- **kwargs: Additional download parameters

106

"""

107

```

108

109

### S3 CSE Bucket

110

111

Bucket resource wrapper with client-side encryption support.

112

113

```python { .api }

114

class S3CSEBucket:

115

def __init__(self, bucket_resource, cse_client):

116

"""

117

Initialize S3 CSE bucket wrapper.

118

119

Parameters:

120

- bucket_resource: S3 bucket resource

121

- cse_client: S3CSEClient instance

122

"""

123

124

async def __aenter__(self):

125

"""

126

Async context manager entry.

127

128

Returns:

129

self: The S3CSEBucket instance

130

"""

131

132

async def __aexit__(self, exc_type, exc_val, exc_tb):

133

"""

134

Async context manager exit.

135

"""

136

137

async def put_object(self, key: str, body, **kwargs):

138

"""

139

Put encrypted object to this bucket.

140

141

Parameters:

142

- key: S3 object key

143

- body: Object body (will be encrypted)

144

- **kwargs: Additional parameters

145

"""

146

147

async def get_object(self, key: str, **kwargs):

148

"""

149

Get and decrypt object from this bucket.

150

151

Parameters:

152

- key: S3 object key

153

- **kwargs: Additional parameters

154

155

Returns:

156

Decrypted object data

157

"""

158

```

159

160

### S3 CSE Object

161

162

Object resource wrapper with client-side encryption support.

163

164

```python { .api }

165

class S3CSEObject:

166

def __init__(self, object_resource, cse_client):

167

"""

168

Initialize S3 CSE object wrapper.

169

170

Parameters:

171

- object_resource: S3 object resource

172

- cse_client: S3CSEClient instance

173

"""

174

175

async def __aenter__(self):

176

"""

177

Async context manager entry.

178

179

Returns:

180

self: The S3CSEObject instance

181

"""

182

183

async def __aexit__(self, exc_type, exc_val, exc_tb):

184

"""

185

Async context manager exit.

186

"""

187

188

async def put(self, body, **kwargs):

189

"""

190

Put encrypted data to this object.

191

192

Parameters:

193

- body: Object body (will be encrypted)

194

- **kwargs: Additional parameters

195

"""

196

197

async def get(self, **kwargs):

198

"""

199

Get and decrypt this object's data.

200

201

Parameters:

202

- **kwargs: Additional parameters

203

204

Returns:

205

Decrypted object data

206

"""

207

```

208

209

### Encryption Utilities

210

211

Supporting classes and functions for encryption operations.

212

213

```python { .api }

214

class DummyAIOFile:

215

def __init__(self, data: bytes):

216

"""

217

Async file wrapper for encrypted data.

218

219

Parameters:

220

- data: Encrypted/decrypted byte data

221

"""

222

223

async def read(self, n: int = -1) -> bytes:

224

"""

225

Read data from the file.

226

227

Parameters:

228

- n: Number of bytes to read (-1 for all)

229

230

Returns:

231

Byte data

232

"""

233

234

async def readany(self) -> bytes:

235

"""

236

Read any available data.

237

238

Returns:

239

Available byte data

240

"""

241

242

async def readexactly(self, n: int) -> bytes:

243

"""

244

Read exactly n bytes.

245

246

Parameters:

247

- n: Number of bytes to read

248

249

Returns:

250

Exactly n bytes of data

251

"""

252

253

async def readchunk(self) -> tuple:

254

"""

255

Read a chunk of data.

256

257

Returns:

258

Tuple of (data, is_eof)

259

"""

260

```

261

262

## Usage Examples

263

264

### Basic Encryption Setup

265

266

```python

267

import aioboto3

268

from aioboto3.s3.cse import S3CSEClient

269

270

async def basic_cse_usage():

271

session = aioboto3.Session()

272

273

# Create regular S3 client first

274

async with session.client('s3', region_name='us-east-1') as s3_client:

275

# Create CSE client with KMS key

276

cse_client = S3CSEClient(

277

s3_client=s3_client,

278

kms_key_id='arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012'

279

)

280

281

async with cse_client:

282

# Upload encrypted data

283

await cse_client.put_object(

284

Bucket='my-secure-bucket',

285

Key='sensitive-data.txt',

286

Body=b'This is sensitive information'

287

)

288

289

# Download and decrypt data

290

response = await cse_client.get_object(

291

Bucket='my-secure-bucket',

292

Key='sensitive-data.txt'

293

)

294

295

decrypted_data = await response['Body'].read()

296

print(f"Decrypted: {decrypted_data}")

297

```

298

299

### File Upload/Download with Encryption

300

301

```python

302

async def file_operations_with_encryption():

303

session = aioboto3.Session()

304

305

async with session.client('s3', region_name='us-east-1') as s3_client:

306

cse_client = S3CSEClient(

307

s3_client=s3_client,

308

kms_key_id='your-kms-key-id'

309

)

310

311

async with cse_client:

312

# Upload encrypted file

313

await cse_client.upload_file(

314

'/path/to/sensitive/document.pdf',

315

'my-secure-bucket',

316

'documents/encrypted-document.pdf'

317

)

318

319

# Download and decrypt file

320

await cse_client.download_file(

321

'my-secure-bucket',

322

'documents/encrypted-document.pdf',

323

'/path/to/decrypted/document.pdf'

324

)

325

```

326

327

### Using Master Encryption Key

328

329

```python

330

from cryptography.hazmat.primitives.ciphers.aead import AESGCM

331

import os

332

333

async def master_key_encryption():

334

session = aioboto3.Session()

335

336

# Generate or load master key

337

master_key = AESGCM.generate_key(bit_length=256)

338

339

async with session.client('s3', region_name='us-east-1') as s3_client:

340

cse_client = S3CSEClient(

341

s3_client=s3_client,

342

encryption_key=master_key,

343

key_wrap_algorithm='AES-GCM'

344

)

345

346

async with cse_client:

347

# Encrypt and upload data

348

sensitive_data = "Secret business information"

349

350

await cse_client.put_object(

351

Bucket='my-secure-bucket',

352

Key='business/secret.txt',

353

Body=sensitive_data.encode()

354

)

355

356

# Decrypt and retrieve data

357

response = await cse_client.get_object(

358

Bucket='my-secure-bucket',

359

Key='business/secret.txt'

360

)

361

362

decrypted_content = await response['Body'].read()

363

print(f"Retrieved: {decrypted_content.decode()}")

364

```

365

366

### Batch Operations with Encryption

367

368

```python

369

async def batch_encrypted_operations():

370

session = aioboto3.Session()

371

372

async with session.client('s3', region_name='us-east-1') as s3_client:

373

cse_client = S3CSEClient(

374

s3_client=s3_client,

375

kms_key_id='your-kms-key-id'

376

)

377

378

async with cse_client:

379

# Upload multiple encrypted files

380

files_to_encrypt = [

381

('file1.txt', b'Content of file 1'),

382

('file2.txt', b'Content of file 2'),

383

('file3.txt', b'Content of file 3')

384

]

385

386

for filename, content in files_to_encrypt:

387

await cse_client.put_object(

388

Bucket='my-secure-bucket',

389

Key=f'encrypted/{filename}',

390

Body=content

391

)

392

393

# Download and decrypt all files

394

for filename, _ in files_to_encrypt:

395

response = await cse_client.get_object(

396

Bucket='my-secure-bucket',

397

Key=f'encrypted/{filename}'

398

)

399

400

decrypted = await response['Body'].read()

401

print(f"{filename}: {decrypted}")

402

```

403

404

### Error Handling with CSE

405

406

```python

407

import botocore.exceptions

408

from cryptography.exceptions import InvalidTag

409

410

async def cse_error_handling():

411

session = aioboto3.Session()

412

413

try:

414

async with session.client('s3', region_name='us-east-1') as s3_client:

415

cse_client = S3CSEClient(

416

s3_client=s3_client,

417

kms_key_id='your-kms-key-id'

418

)

419

420

async with cse_client:

421

response = await cse_client.get_object(

422

Bucket='my-secure-bucket',

423

Key='encrypted-file.txt'

424

)

425

426

data = await response['Body'].read()

427

428

except InvalidTag:

429

print("Decryption failed - invalid authentication tag")

430

431

except botocore.exceptions.ClientError as e:

432

error_code = e.response['Error']['Code']

433

434

if error_code == 'AccessDenied':

435

print("Access denied - check KMS key permissions")

436

elif error_code == 'NoSuchKey':

437

print("Encrypted object not found")

438

else:

439

print(f"S3 error: {error_code}")

440

441

except Exception as e:

442

print(f"Encryption/decryption error: {e}")

443

```

444

445

### Configuring Encryption Algorithms

446

447

```python

448

async def advanced_encryption_config():

449

session = aioboto3.Session()

450

451

async with session.client('s3', region_name='us-east-1') as s3_client:

452

# Configure with specific encryption settings

453

cse_client = S3CSEClient(

454

s3_client=s3_client,

455

kms_key_id='your-kms-key-id',

456

key_wrap_algorithm='AES-GCM' # Specify key wrapping algorithm

457

)

458

459

async with cse_client:

460

# Upload with metadata about encryption

461

await cse_client.put_object(

462

Bucket='my-secure-bucket',

463

Key='metadata-encrypted.txt',

464

Body=b'Data with encryption metadata',

465

Metadata={

466

'encryption-info': 'client-side-encrypted',

467

'algorithm': 'AES-GCM'

468

}

469

)

470

```