or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-operations.mdbackup-recovery.mdcrypto-operations.mdimport-export.mdindex.mdkey-management.mdrotation-policies.md

backup-recovery.mddocs/

0

# Key Backup and Recovery

1

2

Backup and restore functionality for keys, enabling key migration and disaster recovery scenarios. Azure Key Vault provides comprehensive backup and recovery capabilities including full key backup/restore and soft-delete protection with recovery options for accidental deletion scenarios.

3

4

## Capabilities

5

6

### Key Backup and Restore

7

8

Create portable backups of keys for migration and disaster recovery.

9

10

```python { .api }

11

def backup_key(name: str, **kwargs) -> bytes:

12

"""

13

Back up a key from the Key Vault.

14

15

Parameters:

16

- name: The name of the key to back up

17

18

Returns:

19

bytes: The key backup as opaque bytes (includes all versions and metadata)

20

21

Raises:

22

- ResourceNotFoundError: If the key doesn't exist

23

- ForbiddenError: If backup permission is not granted

24

"""

25

26

def restore_key_backup(backup: bytes, **kwargs) -> KeyVaultKey:

27

"""

28

Restore a key from a backup.

29

30

Parameters:

31

- backup: The key backup bytes from backup_key()

32

33

Returns:

34

KeyVaultKey: The restored key

35

36

Raises:

37

- InvalidArgumentError: If backup data is invalid

38

- ConflictError: If a key with the same name already exists

39

- ForbiddenError: If restore permission is not granted

40

"""

41

```

42

43

#### Usage Examples

44

45

```python

46

from azure.keyvault.keys import KeyClient

47

from azure.identity import DefaultAzureCredential

48

49

client = KeyClient("https://vault.vault.azure.net/", DefaultAzureCredential())

50

51

# Create a key to backup

52

key = client.create_rsa_key("backup-demo-key", size=2048)

53

54

# Backup the key

55

backup_data = client.backup_key("backup-demo-key")

56

print(f"Backup size: {len(backup_data)} bytes")

57

58

# Save backup to file (optional)

59

with open("key-backup.bin", "wb") as f:

60

f.write(backup_data)

61

62

# Delete the key

63

client.begin_delete_key("backup-demo-key").wait()

64

client.purge_deleted_key("backup-demo-key")

65

66

# Restore the key from backup

67

restored_key = client.restore_key_backup(backup_data)

68

print(f"Restored key: {restored_key.name}")

69

70

# Restore from file (optional)

71

with open("key-backup.bin", "rb") as f:

72

backup_data = f.read()

73

restored_key = client.restore_key_backup(backup_data)

74

```

75

76

### Soft Delete Management

77

78

Manage soft-deleted keys with recovery capabilities.

79

80

```python { .api }

81

def list_deleted_keys(**kwargs) -> ItemPaged[DeletedKey]:

82

"""

83

List all soft-deleted keys in the vault.

84

85

Returns:

86

ItemPaged[DeletedKey]: Paginated list of deleted keys with recovery information

87

"""

88

89

def get_deleted_key(name: str, **kwargs) -> DeletedKey:

90

"""

91

Get information about a soft-deleted key.

92

93

Parameters:

94

- name: The name of the deleted key

95

96

Returns:

97

DeletedKey: The deleted key with recovery information

98

99

Raises:

100

- ResourceNotFoundError: If the deleted key doesn't exist

101

"""

102

103

def begin_recover_deleted_key(name: str, **kwargs) -> LROPoller[KeyVaultKey]:

104

"""

105

Begin recovering a soft-deleted key.

106

107

Parameters:

108

- name: The name of the deleted key to recover

109

110

Returns:

111

LROPoller[KeyVaultKey]: Long-running operation poller for the recovery

112

113

Raises:

114

- ResourceNotFoundError: If the deleted key doesn't exist

115

- ConflictError: If a key with the same name already exists (active)

116

"""

117

118

def purge_deleted_key(name: str, **kwargs) -> None:

119

"""

120

Permanently delete a soft-deleted key (cannot be recovered).

121

122

Parameters:

123

- name: The name of the deleted key to purge

124

125

Raises:

126

- ResourceNotFoundError: If the deleted key doesn't exist

127

- ForbiddenError: If purge permission is not granted

128

"""

129

```

130

131

#### Usage Examples

132

133

```python

134

# Delete a key (soft delete)

135

delete_poller = client.begin_delete_key("my-key")

136

deleted_key = delete_poller.result()

137

print(f"Key deleted on: {deleted_key.deleted_date}")

138

print(f"Scheduled purge date: {deleted_key.scheduled_purge_date}")

139

140

# List all deleted keys

141

print("Deleted keys:")

142

for deleted_key in client.list_deleted_keys():

143

print(f"- {deleted_key.name} (deleted: {deleted_key.deleted_date})")

144

145

# Get specific deleted key info

146

deleted_key = client.get_deleted_key("my-key")

147

print(f"Recovery ID: {deleted_key.recovery_id}")

148

149

# Recover a deleted key

150

recover_poller = client.begin_recover_deleted_key("my-key")

151

recovered_key = recover_poller.result()

152

print(f"Recovered key: {recovered_key.name}")

153

154

# Permanently delete (purge) a key

155

client.purge_deleted_key("my-key")

156

print("Key permanently deleted")

157

```

158

159

### Recovery Scenarios

160

161

Common backup and recovery patterns for different scenarios.

162

163

#### Cross-Vault Migration

164

165

```python

166

# Backup from source vault

167

source_client = KeyClient("https://source-vault.vault.azure.net/", credential)

168

backup_data = source_client.backup_key("migration-key")

169

170

# Restore to destination vault

171

dest_client = KeyClient("https://dest-vault.vault.azure.net/", credential)

172

restored_key = dest_client.restore_key_backup(backup_data)

173

```

174

175

#### Disaster Recovery

176

177

```python

178

import os

179

from datetime import datetime

180

181

# Regular backup process

182

keys_to_backup = ["critical-key-1", "critical-key-2", "signing-key"]

183

backup_dir = "/secure/backups"

184

185

for key_name in keys_to_backup:

186

try:

187

backup_data = client.backup_key(key_name)

188

timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")

189

backup_file = os.path.join(backup_dir, f"{key_name}_{timestamp}.backup")

190

191

with open(backup_file, "wb") as f:

192

f.write(backup_data)

193

print(f"Backed up {key_name} to {backup_file}")

194

except Exception as e:

195

print(f"Failed to backup {key_name}: {e}")

196

197

# Recovery process

198

def recover_from_backup(backup_file_path: str):

199

with open(backup_file_path, "rb") as f:

200

backup_data = f.read()

201

202

try:

203

restored_key = client.restore_key_backup(backup_data)

204

print(f"Successfully restored key: {restored_key.name}")

205

return restored_key

206

except Exception as e:

207

print(f"Failed to restore from {backup_file_path}: {e}")

208

return None

209

```

210

211

#### Accidental Deletion Recovery

212

213

```python

214

def recover_accidentally_deleted_key(key_name: str):

215

"""Recover a key that was accidentally deleted."""

216

try:

217

# Check if key is soft-deleted

218

deleted_key = client.get_deleted_key(key_name)

219

print(f"Found deleted key: {deleted_key.name}")

220

print(f"Deleted on: {deleted_key.deleted_date}")

221

print(f"Scheduled purge: {deleted_key.scheduled_purge_date}")

222

223

# Recover the key

224

recover_poller = client.begin_recover_deleted_key(key_name)

225

recovered_key = recover_poller.result()

226

print(f"Successfully recovered key: {recovered_key.name}")

227

return recovered_key

228

229

except ResourceNotFoundError:

230

print(f"Key '{key_name}' not found in deleted keys")

231

return None

232

except Exception as e:

233

print(f"Error recovering key: {e}")

234

return None

235

236

# Example usage

237

recovered_key = recover_accidentally_deleted_key("accidentally-deleted-key")

238

```

239

240

## Types

241

242

```python { .api }

243

class DeletedKey(KeyVaultKey):

244

"""A deleted key's properties, cryptographic material and deletion information."""

245

# Inherits all properties from KeyVaultKey, plus:

246

deleted_date: datetime

247

recovery_id: str

248

scheduled_purge_date: datetime

249

250

class LROPoller:

251

"""Long-running operation poller."""

252

def result(timeout: int = None) -> Any:

253

"""Get the final result of the long-running operation."""

254

255

def wait(timeout: int = None) -> None:

256

"""Wait for the operation to complete."""

257

258

def done() -> bool:

259

"""Check if the operation is complete."""

260

261

def status() -> str:

262

"""Get the current status of the operation."""

263

264

class ItemPaged:

265

"""Paginated collection of items."""

266

def __iter__():

267

"""Iterate over all items across pages."""

268

269

def by_page():

270

"""Iterate page by page."""

271

```

272

273

## Error Handling

274

275

Common exceptions and error scenarios in backup and recovery operations.

276

277

```python

278

from azure.core.exceptions import (

279

ResourceNotFoundError,

280

ConflictError,

281

ForbiddenError,

282

InvalidArgumentError

283

)

284

285

def safe_backup_key(client: KeyClient, key_name: str) -> bytes:

286

"""Safely backup a key with error handling."""

287

try:

288

return client.backup_key(key_name)

289

except ResourceNotFoundError:

290

print(f"Key '{key_name}' not found")

291

return None

292

except ForbiddenError:

293

print(f"Insufficient permissions to backup key '{key_name}'")

294

return None

295

except Exception as e:

296

print(f"Unexpected error backing up key '{key_name}': {e}")

297

return None

298

299

def safe_restore_key(client: KeyClient, backup_data: bytes) -> KeyVaultKey:

300

"""Safely restore a key with error handling."""

301

try:

302

return client.restore_key_backup(backup_data)

303

except InvalidArgumentError:

304

print("Invalid backup data")

305

return None

306

except ConflictError:

307

print("Key with same name already exists")

308

return None

309

except ForbiddenError:

310

print("Insufficient permissions to restore key")

311

return None

312

except Exception as e:

313

print(f"Unexpected error restoring key: {e}")

314

return None

315

```