pangea-sdk 3.8.0__py3-none-any.whl → 5.3.0__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. pangea/__init__.py +2 -1
  2. pangea/asyncio/__init__.py +1 -0
  3. pangea/asyncio/file_uploader.py +39 -0
  4. pangea/asyncio/request.py +46 -23
  5. pangea/asyncio/services/__init__.py +2 -0
  6. pangea/asyncio/services/audit.py +46 -20
  7. pangea/asyncio/services/authn.py +123 -61
  8. pangea/asyncio/services/authz.py +57 -31
  9. pangea/asyncio/services/base.py +21 -2
  10. pangea/asyncio/services/embargo.py +2 -2
  11. pangea/asyncio/services/file_scan.py +24 -9
  12. pangea/asyncio/services/intel.py +104 -30
  13. pangea/asyncio/services/redact.py +52 -3
  14. pangea/asyncio/services/sanitize.py +217 -0
  15. pangea/asyncio/services/share.py +733 -0
  16. pangea/asyncio/services/vault.py +1709 -766
  17. pangea/crypto/rsa.py +135 -0
  18. pangea/deep_verify.py +7 -1
  19. pangea/dump_audit.py +9 -8
  20. pangea/file_uploader.py +35 -0
  21. pangea/request.py +70 -49
  22. pangea/response.py +36 -17
  23. pangea/services/__init__.py +2 -0
  24. pangea/services/audit/audit.py +57 -29
  25. pangea/services/audit/models.py +12 -3
  26. pangea/services/audit/signing.py +6 -5
  27. pangea/services/audit/util.py +3 -3
  28. pangea/services/authn/authn.py +120 -66
  29. pangea/services/authn/models.py +167 -11
  30. pangea/services/authz.py +53 -30
  31. pangea/services/base.py +16 -2
  32. pangea/services/embargo.py +2 -2
  33. pangea/services/file_scan.py +32 -15
  34. pangea/services/intel.py +155 -30
  35. pangea/services/redact.py +132 -3
  36. pangea/services/sanitize.py +388 -0
  37. pangea/services/share/file_format.py +170 -0
  38. pangea/services/share/share.py +1440 -0
  39. pangea/services/vault/models/asymmetric.py +120 -18
  40. pangea/services/vault/models/common.py +439 -141
  41. pangea/services/vault/models/keys.py +94 -0
  42. pangea/services/vault/models/secret.py +27 -3
  43. pangea/services/vault/models/symmetric.py +68 -22
  44. pangea/services/vault/vault.py +1690 -766
  45. pangea/tools.py +6 -7
  46. pangea/utils.py +94 -33
  47. pangea/verify_audit.py +270 -83
  48. {pangea_sdk-3.8.0.dist-info → pangea_sdk-5.3.0.dist-info}/METADATA +21 -29
  49. pangea_sdk-5.3.0.dist-info/RECORD +56 -0
  50. {pangea_sdk-3.8.0.dist-info → pangea_sdk-5.3.0.dist-info}/WHEEL +1 -1
  51. pangea_sdk-3.8.0.dist-info/RECORD +0 -46
@@ -2,38 +2,48 @@
2
2
  # Author: Pangea Cyber Corporation
3
3
  from __future__ import annotations
4
4
 
5
- import datetime
6
- from typing import Dict, Optional, Union
5
+ from typing import TYPE_CHECKING, Any, List, Literal, Optional, Union, cast, overload
7
6
 
8
- from pangea.config import PangeaConfig
9
- from pangea.response import PangeaResponse
7
+ from pydantic import Field, TypeAdapter
8
+ from typing_extensions import Annotated
9
+
10
+ from pangea.response import PangeaResponse, PangeaResponseResult
10
11
  from pangea.services.base import ServiceBase
11
12
  from pangea.services.vault.models.asymmetric import (
12
- AsymmetricGenerateRequest,
13
- AsymmetricGenerateResult,
14
- AsymmetricStoreRequest,
15
- AsymmetricStoreResult,
13
+ AsymmetricKey,
14
+ AsymmetricKeyAlgorithm,
15
+ AsymmetricKeyEncryptionAlgorithm,
16
+ AsymmetricKeyJwtAlgorithm,
17
+ AsymmetricKeyPkiAlgorithm,
18
+ AsymmetricKeyPurpose,
19
+ AsymmetricKeySigningAlgorithm,
16
20
  SignRequest,
17
21
  SignResult,
18
22
  VerifyRequest,
19
23
  VerifyResult,
20
24
  )
21
25
  from pangea.services.vault.models.common import (
22
- AsymmetricAlgorithm,
26
+ ClientSecret,
27
+ ClientSecretRotateRequest,
28
+ DecryptTransformRequest,
29
+ DecryptTransformResult,
23
30
  DeleteRequest,
24
31
  DeleteResult,
25
- EncodedPrivateKey,
26
- EncodedPublicKey,
27
- EncodedSymmetricKey,
28
32
  EncryptStructuredRequest,
29
33
  EncryptStructuredResult,
34
+ EncryptTransformRequest,
35
+ EncryptTransformResult,
36
+ ExportEncryptionAlgorithm,
37
+ ExportEncryptionType,
38
+ ExportRequest,
39
+ ExportResult,
40
+ Folder,
30
41
  FolderCreateRequest,
31
42
  FolderCreateResult,
43
+ GetBulkRequest,
32
44
  GetRequest,
33
- GetResult,
34
45
  ItemOrder,
35
46
  ItemOrderBy,
36
- ItemState,
37
47
  ItemType,
38
48
  ItemVersionState,
39
49
  JWKGetRequest,
@@ -42,37 +52,54 @@ from pangea.services.vault.models.common import (
42
52
  JWTSignResult,
43
53
  JWTVerifyRequest,
44
54
  JWTVerifyResult,
45
- KeyPurpose,
46
- KeyRotateRequest,
47
- KeyRotateResult,
48
55
  ListRequest,
49
56
  ListResult,
50
57
  Metadata,
58
+ PangeaToken,
59
+ PangeaTokenRotateRequest,
60
+ RequestManualRotationState,
61
+ RequestRotationState,
62
+ RotationState,
63
+ Secret,
51
64
  StateChangeRequest,
52
- StateChangeResult,
53
- SymmetricAlgorithm,
54
65
  Tags,
55
66
  TDict,
67
+ TransformAlphabet,
56
68
  UpdateRequest,
57
69
  UpdateResult,
58
70
  )
59
- from pangea.services.vault.models.secret import (
60
- SecretRotateRequest,
61
- SecretRotateResult,
62
- SecretStoreRequest,
63
- SecretStoreResult,
64
- )
71
+ from pangea.services.vault.models.keys import CommonGenerateRequest, KeyRotateRequest, KeyStoreRequest
72
+ from pangea.services.vault.models.secret import SecretRotateRequest, SecretStoreRequest, SecretStoreResult
65
73
  from pangea.services.vault.models.symmetric import (
66
74
  DecryptRequest,
67
75
  DecryptResult,
68
76
  EncryptRequest,
69
77
  EncryptResult,
70
- SymmetricGenerateRequest,
71
- SymmetricGenerateResult,
72
- SymmetricStoreRequest,
73
- SymmetricStoreResult,
78
+ SymmetricKey,
79
+ SymmetricKeyAlgorithm,
80
+ SymmetricKeyEncryptionAlgorithm,
81
+ SymmetricKeyFpeAlgorithm,
82
+ SymmetricKeyJwtAlgorithm,
83
+ SymmetricKeyPurpose,
74
84
  )
75
85
 
86
+ if TYPE_CHECKING:
87
+ import datetime
88
+ from collections.abc import Mapping
89
+
90
+ from pangea.config import PangeaConfig
91
+ from pangea.request import TResult
92
+
93
+
94
+ VaultItem = Annotated[
95
+ Union[AsymmetricKey, SymmetricKey, Secret, ClientSecret, Folder, PangeaToken], Field(discriminator="type")
96
+ ]
97
+ vault_item_adapter: TypeAdapter[VaultItem] = TypeAdapter(VaultItem)
98
+
99
+
100
+ class GetBulkResponse(PangeaResponseResult):
101
+ items: List[VaultItem]
102
+
76
103
 
77
104
  class Vault(ServiceBase):
78
105
  """Vault service client.
@@ -121,110 +148,137 @@ class Vault(ServiceBase):
121
148
  """
122
149
  super().__init__(token, config, logger_name)
123
150
 
124
- # Delete endpoint
125
- def delete(self, id: str) -> PangeaResponse[DeleteResult]:
151
+ def delete(self, item_id: str, *, recursive: bool = False) -> PangeaResponse[DeleteResult]:
126
152
  """
127
153
  Delete
128
154
 
129
155
  Delete a secret or key
130
156
 
131
- OperationId: vault_post_v1_delete
157
+ OperationId: vault_post_v2_delete
132
158
 
133
159
  Args:
134
- id (str): The item ID
135
- Raises:
136
- PangeaAPIException: If an API Error happens
160
+ item_id: The item ID.
161
+ recursive: Whether to delete the item and all its children
162
+ recursively. Only applicable to folders.
137
163
 
138
164
  Returns:
139
165
  A PangeaResponse where the id of the deleted secret or key
140
166
  is returned in the response.result field.
141
167
  Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#delete).
142
168
 
169
+ Raises:
170
+ PangeaAPIException: If an API Error happens
171
+
143
172
  Examples:
144
173
  vault.delete(id="pvi_p6g5i3gtbvqvc3u6zugab6qs6r63tqf5")
145
174
  """
146
- input = DeleteRequest(
147
- id=id,
148
- )
149
- return self.request.post("v1/delete", DeleteResult, data=input.dict(exclude_none=True))
175
+ return self.request.post("v2/delete", DeleteResult, data=DeleteRequest(id=item_id, recursive=recursive))
150
176
 
151
- # Get endpoint
152
177
  def get(
153
178
  self,
154
- id: str,
155
- version: Optional[Union[str, int]] = None,
156
- version_state: Optional[ItemVersionState] = None,
157
- verbose: Optional[bool] = None,
158
- ) -> PangeaResponse[GetResult]:
179
+ item_id: str,
180
+ *,
181
+ version: Union[Literal["all"], int, None] = None,
182
+ ) -> PangeaResponse[VaultItem]:
159
183
  """
160
184
  Retrieve
161
185
 
162
- Retrieve a secret or key, and any associated information
186
+ Retrieve a secret, key or folder, and any associated information.
163
187
 
164
- OperationId: vault_post_v1_get
188
+ OperationId: vault_post_v2_get
165
189
 
166
190
  Args:
167
- id (str): The item ID
168
- version (str, int, optional): The key version(s).
169
- - `all` for all versions
170
- - `num` for a specific version
171
- - `-num` for the `num` latest versions
172
- version_state (ItemVersionState, optional): The state of the item version
173
- verbose (bool, optional): Return metadata and extra fields. Default is `False`.
174
- Raises:
175
- PangeaAPIException: If an API Error happens
191
+ item_id: The item ID
192
+ version: The key version(s).
193
+ - `all` for all versions
194
+ - `num` for a specific version
195
+ - `-num` for the `num` latest versions
176
196
 
177
197
  Returns:
178
198
  A PangeaResponse where the secret or key
179
199
  is returned in the response.result field.
180
200
  Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#retrieve).
181
201
 
202
+ Raises:
203
+ PangeaAPIException: If an API Error happens
204
+
182
205
  Examples:
183
206
  response = vault.get(
184
207
  id="pvi_p6g5i3gtbvqvc3u6zugab6qs6r63tqf5",
185
208
  version=1,
186
- version_state=ItemVersionState.ACTIVE,
187
- verbose=True,
188
209
  )
189
210
  """
190
- input = GetRequest(
191
- id=id,
192
- version=version,
193
- verbose=verbose,
194
- version_state=version_state,
211
+ response = self.request.post("v2/get", PangeaResponseResult, data=GetRequest(id=item_id, version=version))
212
+ response.result = vault_item_adapter.validate_python(response.json["result"])
213
+ return cast(PangeaResponse[VaultItem], response)
214
+
215
+ def get_bulk(
216
+ self,
217
+ filter_: Mapping[str, str],
218
+ *,
219
+ size: int | None = None,
220
+ order: ItemOrder | None = None,
221
+ order_by: ItemOrderBy | None = None,
222
+ last: str | None = None,
223
+ ) -> PangeaResponse[GetBulkResponse]:
224
+ """
225
+ Get bulk
226
+
227
+ Retrieve details for multiple Vault items, including keys, secrets,
228
+ tokens, or folders, that match a given filter specification.
229
+
230
+ OperationId: vault_post_v2_get_bulk
231
+
232
+ Args:
233
+ filter: Filters to customize your search.
234
+ size: Maximum number of items in the response.
235
+ order: Direction for ordering the results.
236
+ order_by: Property by which to order the results.
237
+ last: Internal ID returned in the previous look up response. Used
238
+ for pagination.
239
+
240
+ Examples:
241
+ response = vault.get_bulk({"id": "pvi_..."})
242
+ """
243
+ return self.request.post(
244
+ "v2/get_bulk",
245
+ GetBulkResponse,
246
+ data=GetBulkRequest(filter=filter_, size=size, order=order, order_by=order_by, last=last),
195
247
  )
196
- return self.request.post("v1/get", GetResult, data=input.dict(exclude_none=True))
197
248
 
198
- # List endpoint
199
249
  def list(
200
250
  self,
201
- filter: Optional[Dict[str, str]] = None,
202
- last: Optional[str] = None,
251
+ *,
252
+ filter: Optional[Mapping[str, str]] = None,
253
+ size: int = 50,
203
254
  order: Optional[ItemOrder] = None,
204
- order_by: Optional[ItemOrderBy] = None,
205
- size: Optional[int] = None,
255
+ order_by: ItemOrderBy | None = None,
256
+ last: str | None = None,
206
257
  ) -> PangeaResponse[ListResult]:
207
258
  """
208
259
  List
209
260
 
210
- Look up a list of secrets, keys and folders, and their associated information
261
+ Retrieve a list of secrets, keys and folders, and their associated information.
211
262
 
212
- OperationId: vault_post_v1_list
263
+ OperationId: vault_post_v2_list
213
264
 
214
265
  Args:
215
- filter (dict, optional): A set of filters to help you customize your search. Examples:
216
- - "folder": "/tmp"
217
- - "tags": "personal"
218
- - "name__contains": "xxx"
219
- - "created_at__gt": "2020-02-05T10:00:00Z"
220
-
221
- For metadata, use: "metadata_": "\<value\>"
222
- last (str, optional): Internal ID returned in the previous look up response. Used for pagination.
223
- order (ItemOrder, optional): Ordering direction: `asc` or `desc`
224
- order_by (ItemOrderBy, optional): Property used to order the results. Supported properties: `id`,
266
+ filter: A set of filters to help you customize your search.
267
+
268
+ Examples:
269
+ - "folder": "/tmp"
270
+ - "tags": "personal"
271
+ - "name__contains": "xxx"
272
+ - "created_at__gt": "2020-02-05T10:00:00Z"
273
+
274
+ For metadata, use: "metadata_{key}": "{value}"
275
+ size: Maximum number of items in the response. Default is `50`.
276
+ order: Ordering direction: `asc` or `desc`
277
+ order_by: Property used to order the results. Supported properties: `id`,
225
278
  `type`, `created_at`, `algorithm`, `purpose`, `expiration`, `last_rotated`, `next_rotation`,
226
279
  `name`, `folder`, `item_state`.
227
- size (int, optional): Maximum number of items in the response. Default is `50`.
280
+ last: Internal ID returned in the previous look up response. Used
281
+ for pagination.
228
282
  Raises:
229
283
  PangeaAPIException: If an API Error happens
230
284
 
@@ -248,55 +302,52 @@ class Vault(ServiceBase):
248
302
  size=20,
249
303
  )
250
304
  """
251
- input = ListRequest(filter=filter, last=last, order=order, order_by=order_by, size=size)
252
- return self.request.post("v1/list", ListResult, data=input.dict(exclude_none=True))
305
+ return self.request.post(
306
+ "v2/list",
307
+ ListResult,
308
+ data=ListRequest(filter=filter, size=size, order=order, order_by=order_by, last=last),
309
+ )
253
310
 
254
- # Update endpoint
255
311
  def update(
256
312
  self,
257
- id: str,
258
- name: Optional[str] = None,
259
- folder: Optional[str] = None,
260
- metadata: Optional[Metadata] = None,
261
- tags: Optional[Tags] = None,
262
- rotation_frequency: Optional[str] = None,
263
- rotation_state: Optional[ItemVersionState] = None,
264
- rotation_grace_period: Optional[str] = None,
265
- expiration: Optional[datetime.datetime] = None,
266
- item_state: Optional[ItemState] = None,
313
+ item_id: str,
314
+ *,
315
+ name: str | None = None,
316
+ folder: str | None = None,
317
+ metadata: Metadata | None = None,
318
+ tags: Tags | None = None,
319
+ disabled_at: str | None = None,
320
+ enabled: bool | None = None,
321
+ rotation_frequency: str | None = None,
322
+ rotation_state: RequestRotationState = RequestRotationState.INHERITED,
323
+ rotation_grace_period: str | None = None,
267
324
  ) -> PangeaResponse[UpdateResult]:
268
325
  """
269
326
  Update
270
327
 
271
- Update information associated with a secret or key.
328
+ Update information associated with a secret, key or folder.
272
329
 
273
- OperationId: vault_post_v1_update
330
+ OperationId: vault_post_v2_update
274
331
 
275
332
  Args:
276
- id (str): The item ID
277
- name (str, optional): The name of this item
278
- folder (string, optional): The folder where this item is stored
279
- metadata (dict, optional): User-provided metadata
280
- tags (list[str], optional): A list of user-defined tags
281
- rotation_frequency (str, optional): Period of time between item rotations
282
- rotation_state (ItemVersionState, optional): State to which the previous version should transition upon rotation.
283
- Supported options:
284
- - `deactivated`
285
- - `destroyed`
286
-
287
- Default is `deactivated`.
288
- rotation_grace_period (str, optional): Grace period for the previous version of the Pangea Token
289
- expiration (str, optional): Expiration timestamp
290
- item_state (ItemState, optional): The new state of the item. Supported options:
291
- - `enabled`
292
- - `disabled`
293
- Raises:
294
- PangeaAPIException: If an API Error happens
333
+ item_id: The item ID.
334
+ name: The name of this item
335
+ folder: The folder where this item is stored.
336
+ metadata: User-provided metadata.
337
+ tags: A list of user-defined tags.
338
+ disabled_at: Timestamp indicating when the item will be disabled.
339
+ enabled: True if the item is enabled.
340
+ rotation_frequency: Period of time between item rotations.
341
+ rotation_state: State to which the previous version should transition upon rotation.
342
+ rotation_grace_period: Grace period for the previous version of the Pangea Token.
295
343
 
296
344
  Returns:
297
- A PangeaResponse where the item ID
298
- is returned in the response.result field.
299
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#update).
345
+ A PangeaResponse where the item ID is returned in the
346
+ response.result field. Available response fields can be found in our
347
+ [API documentation](https://pangea.cloud/docs/api/vault#update).
348
+
349
+ Raises:
350
+ PangeaAPIException: If an API Error happens
300
351
 
301
352
  Examples:
302
353
  response = vault.update(
@@ -313,688 +364,1395 @@ class Vault(ServiceBase):
313
364
  ],
314
365
  rotation_frequency="10d",
315
366
  rotation_state=ItemVersionState.DEACTIVATED,
316
- rotation_grace_period="1d",
317
- expiration="2025-01-01T10:00:00Z",
318
- item_state=ItemState.DISABLED,
319
367
  )
320
368
  """
321
- input = UpdateRequest(
322
- id=id,
323
- name=name,
324
- folder=folder,
325
- metadata=metadata,
326
- tags=tags,
327
- rotation_frequency=rotation_frequency,
328
- rotation_state=rotation_state,
329
- rotation_grace_period=rotation_grace_period,
330
- expiration=expiration,
331
- item_state=item_state,
369
+ return self.request.post(
370
+ "v2/update",
371
+ UpdateResult,
372
+ data=UpdateRequest(
373
+ id=item_id,
374
+ name=name,
375
+ folder=folder,
376
+ metadata=metadata,
377
+ tags=tags,
378
+ disabled_at=disabled_at,
379
+ enabled=enabled,
380
+ rotation_frequency=rotation_frequency,
381
+ rotation_state=rotation_state,
382
+ rotation_grace_period=rotation_grace_period,
383
+ ),
384
+ )
385
+
386
+ def _secret_store(
387
+ self,
388
+ *,
389
+ item_type: Literal["secret", "pangea_token", "pangea_client_secret"] = "secret",
390
+ result_class: type[TResult] = SecretStoreResult, # type: ignore[assignment]
391
+ name: str | None = None,
392
+ folder: str | None = None,
393
+ metadata: Metadata | None = None,
394
+ tags: Tags | None = None,
395
+ disabled_at: datetime.datetime | None = None,
396
+ **kwargs: Any,
397
+ ) -> PangeaResponse[TResult]:
398
+ return self.request.post(
399
+ "v2/secret/store",
400
+ result_class,
401
+ data=SecretStoreRequest(
402
+ type=item_type,
403
+ name=name,
404
+ folder=folder,
405
+ metadata=metadata,
406
+ tags=tags,
407
+ disabled_at=disabled_at,
408
+ **kwargs,
409
+ ),
332
410
  )
333
- return self.request.post("v1/update", UpdateResult, data=input.dict(exclude_none=True))
334
411
 
335
- def secret_store(
412
+ def store_secret(
336
413
  self,
337
414
  secret: str,
338
- name: str,
339
- folder: Optional[str] = None,
340
- metadata: Optional[Metadata] = None,
341
- tags: Optional[Tags] = None,
342
- rotation_frequency: Optional[str] = None,
343
- rotation_state: Optional[ItemVersionState] = None,
344
- expiration: Optional[datetime.datetime] = None,
345
- ) -> PangeaResponse[SecretStoreResult]:
415
+ *,
416
+ name: str | None = None,
417
+ folder: str | None = None,
418
+ metadata: Metadata | None = None,
419
+ tags: Tags | None = None,
420
+ disabled_at: datetime.datetime | None = None,
421
+ ) -> PangeaResponse[Secret]:
346
422
  """
347
- Secret store
423
+ Store secret
348
424
 
349
- Import a secret
350
-
351
- OperationId: vault_post_v1_secret_store 1
425
+ Store a secret.
352
426
 
353
427
  Args:
354
- secret (str): The secret value
355
- name (str): The name of this item
356
- folder (str, optional): The folder where this item is stored
357
- metadata (dict, optional): User-provided metadata
358
- tags (list[str], optional): A list of user-defined tags
359
- rotation_frequency (str, optional): Period of time between item rotations
360
- rotation_state (ItemVersionState, optional): State to which the previous version should transition upon rotation.
361
- Supported options:
362
- - `deactivated`
363
- - `destroyed`
364
- expiration (str, optional): Expiration timestamp
428
+ secret: The secret value.
429
+ name: The name of this item.
430
+ folder: The folder where this item is stored.
431
+ metadata: User-provided metadata.
432
+ tags: A list of user-defined tags.
433
+ disabled_at: Timestamp indicating when the item will be disabled.
365
434
 
366
435
  Raises:
367
436
  PangeaAPIException: If an API Error happens
368
437
 
369
- Returns:
370
- A PangeaResponse where the secret
371
- is returned in the response.result field.
372
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#import-a-secret).
373
-
374
438
  Examples:
375
- response = vault.secret_store(
376
- secret="12sdfgs4543qv@#%$casd",
377
- name="my-very-secret-secret",
378
- folder="/personal",
379
- metadata={
380
- "created_by": "John Doe",
381
- "used_in": "Google products"
382
- },
383
- tags=[
384
- "irs_2023",
385
- "personal"
386
- ],
387
- rotation_frequency="10d",
388
- rotation_state=ItemVersionState.DEACTIVATED,
389
- expiration="2025-01-01T10:00:00Z",
390
- )
439
+ response = vault.store_secret(secret="foobar")
391
440
  """
392
- input = SecretStoreRequest(
393
- type=ItemType.SECRET,
441
+
442
+ return self._secret_store(
443
+ item_type="secret",
444
+ result_class=Secret,
394
445
  secret=secret,
395
446
  name=name,
396
447
  folder=folder,
397
448
  metadata=metadata,
398
449
  tags=tags,
399
- rotation_frequency=rotation_frequency,
400
- rotation_state=rotation_state,
401
- expiration=expiration,
450
+ disabled_at=disabled_at,
402
451
  )
403
- return self.request.post("v1/secret/store", SecretStoreResult, data=input.dict(exclude_none=True))
404
452
 
405
- def pangea_token_store(
453
+ def store_pangea_token(
406
454
  self,
407
- pangea_token: str,
408
- name: str,
409
- folder: Optional[str] = None,
410
- metadata: Optional[Metadata] = None,
411
- tags: Optional[Tags] = None,
412
- rotation_frequency: Optional[str] = None,
413
- rotation_state: Optional[ItemVersionState] = None,
414
- expiration: Optional[datetime.datetime] = None,
415
- ) -> PangeaResponse[SecretStoreResult]:
455
+ token: str,
456
+ *,
457
+ name: str | None = None,
458
+ folder: str | None = None,
459
+ metadata: Metadata | None = None,
460
+ tags: Tags | None = None,
461
+ disabled_at: datetime.datetime | None = None,
462
+ rotation_frequency: str | None = None,
463
+ rotation_state: RotationState | None = None,
464
+ rotation_grace_period: str | None = None,
465
+ ) -> PangeaResponse[PangeaToken]:
416
466
  """
417
- Pangea token store
467
+ Store secret
418
468
 
419
- Import a secret
420
-
421
- OperationId: vault_post_v1_secret_store 2
469
+ Store a Pangea token.
422
470
 
423
471
  Args:
424
- pangea_token (str): The pangea token to store
425
- name (str): the name of this item
426
- folder (str, optional): The folder where this item is stored
427
- metadata (dict, optional): User-provided metadata
428
- tags (list[str], optional): A list of user-defined tags
429
- rotation_frequency (str, optional): Period of time between item rotations
430
- rotation_state (ItemVersionState, optional): State to which the previous version should
431
- transition upon rotation. Supported options:
432
- - `deactivated`
433
- - `destroyed`
434
- expiration (str, optional): Expiration timestamp
472
+ token: The Pangea token value.
473
+ name: The name of this item.
474
+ folder: The folder where this item is stored.
475
+ metadata: User-provided metadata.
476
+ tags: A list of user-defined tags.
477
+ disabled_at: Timestamp indicating when the item will be disabled.
435
478
 
436
479
  Raises:
437
480
  PangeaAPIException: If an API Error happens
438
481
 
439
- Returns:
440
- A PangeaResponse where the token
441
- is returned in the response.result field.
442
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#import-a-secret).
443
-
444
482
  Examples:
445
- response = vault.pangea_token_store(
446
- pangea_token="ptv_x6fdiizbon6j3bsdvnpmwxsz2aan7fqd",
447
- name="my-very-secret-secret",
448
- folder="/personal",
449
- metadata={
450
- "created_by": "John Doe",
451
- "used_in": "Google products"
452
- },
453
- tags=[
454
- "irs_2023",
455
- "personal"
456
- ],
457
- rotation_frequency="10d",
458
- rotation_state=ItemVersionState.DEACTIVATED,
459
- expiration="2025-01-01T10:00:00Z",
460
- )
483
+ response = vault.store_pangea_token(token="foobar")
461
484
  """
462
- input = SecretStoreRequest(
463
- type=ItemType.PANGEA_TOKEN,
464
- secret=pangea_token,
485
+
486
+ return self._secret_store(
487
+ item_type="pangea_token",
488
+ result_class=PangeaToken,
489
+ token=token,
465
490
  name=name,
466
491
  folder=folder,
467
492
  metadata=metadata,
468
493
  tags=tags,
494
+ disabled_at=disabled_at,
469
495
  rotation_frequency=rotation_frequency,
470
496
  rotation_state=rotation_state,
471
- expiration=expiration,
497
+ rotation_grace_period=rotation_grace_period,
472
498
  )
473
- return self.request.post("v1/secret/store", SecretStoreResult, data=input.dict(exclude_none=True))
474
499
 
475
- # Rotate endpoint
476
- def secret_rotate(
477
- self, id: str, secret: str, rotation_state: Optional[ItemVersionState] = None
478
- ) -> PangeaResponse[SecretRotateResult]:
500
+ def store_pangea_client_secret(
501
+ self,
502
+ client_secret: str,
503
+ client_id: str,
504
+ client_secret_id: str,
505
+ *,
506
+ name: str | None = None,
507
+ folder: str | None = None,
508
+ metadata: Metadata | None = None,
509
+ tags: Tags | None = None,
510
+ disabled_at: datetime.datetime | None = None,
511
+ rotation_frequency: str | None = None,
512
+ rotation_state: RotationState | None = None,
513
+ rotation_grace_period: str | None = None,
514
+ ) -> PangeaResponse[ClientSecret]:
479
515
  """
480
- Secret rotate
516
+ Store secret
481
517
 
482
- Rotate a secret
483
-
484
- OperationId: vault_post_v1_secret_rotate 1
518
+ Store a Pangea client secret.
485
519
 
486
520
  Args:
487
- id (str): The item ID
488
- secret (str): The secret value
489
- rotation_state (ItemVersionState, optional): State to which the previous version should transition upon rotation.
490
- Supported options:
491
- - `deactivated`
492
- - `suspended`
493
- - `destroyed`
494
-
495
- Default is `deactivated`.
521
+ client_secret: The oauth client secret.
522
+ client_id: The oauth client ID.
523
+ client_secret_id: The oauth client secret ID.
524
+ name: The name of this item.
525
+ folder: The folder where this item is stored.
526
+ metadata: User-provided metadata.
527
+ tags: A list of user-defined tags.
528
+ disabled_at: Timestamp indicating when the item will be disabled.
529
+ rotation_frequency: Period of time between item rotations.
530
+ rotation_state: State to which the previous version should
531
+ transition upon rotation.
532
+ rotation_grace_period: Grace period for the previous version of the
533
+ Pangea Token.
496
534
 
497
535
  Raises:
498
536
  PangeaAPIException: If an API Error happens
499
537
 
500
- Returns:
501
- A PangeaResponse where the secret
502
- is returned in the response.result field.
503
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#rotate-a-secret).
504
-
505
538
  Examples:
506
- response = vault.secret_rotate(
507
- id="pvi_p6g5i3gtbvqvc3u6zugab6qs6r63tqf5",
508
- secret="12sdfgs4543qv@#%$casd",
509
- rotation_state=ItemVersionState.DEACTIVATED,
539
+ response = vault.store_pangea_client_secret(
540
+ client_secret="foo",
541
+ client_id="bar",
542
+ client_secret_id="baz",
510
543
  )
511
544
  """
512
- input = SecretRotateRequest(id=id, secret=secret, rotation_state=rotation_state)
513
- return self.request.post("v1/secret/rotate", SecretRotateResult, data=input.dict(exclude_none=True))
514
545
 
515
- # Rotate endpoint
516
- def pangea_token_rotate(self, id: str) -> PangeaResponse[SecretRotateResult]:
517
- """
518
- Token rotate
546
+ return self._secret_store(
547
+ item_type="pangea_client_secret",
548
+ result_class=ClientSecret,
549
+ client_secret=client_secret,
550
+ client_id=client_id,
551
+ client_secret_id=client_secret_id,
552
+ name=name,
553
+ folder=folder,
554
+ metadata=metadata,
555
+ tags=tags,
556
+ disabled_at=disabled_at,
557
+ rotation_frequency=rotation_frequency,
558
+ rotation_state=rotation_state,
559
+ rotation_grace_period=rotation_grace_period,
560
+ )
519
561
 
520
- Rotate a Pangea token
562
+ def rotate_secret(
563
+ self,
564
+ item_id: str,
565
+ secret: str,
566
+ *,
567
+ rotation_state: RequestManualRotationState = RequestManualRotationState.DEACTIVATED,
568
+ ) -> PangeaResponse[Secret]:
569
+ """
570
+ Rotate secret
521
571
 
522
- OperationId: vault_post_v1_secret_rotate 2
572
+ Rotate a secret.
523
573
 
524
574
  Args:
525
- id (str): The item ID
575
+ item_id: The item ID.
576
+ secret: The secret value.
577
+ rotation_state: State to which the previous version should
578
+ transition upon rotation.
526
579
 
527
580
  Raises:
528
581
  PangeaAPIException: If an API Error happens
529
582
 
530
- Returns:
531
- A PangeaResponse where the token
532
- is returned in the response.result field.
533
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#rotate-a-secret).
534
-
535
583
  Examples:
536
- response = vault.pangea_token_rotate(
537
- id="pvi_p6g5i3gtbvqvc3u6zugab6qs6r63tqf5",
538
- )
584
+ response = vault.rotate_secret(item_id="foo", secret="bar")
539
585
  """
540
- input = SecretRotateRequest(id=id) # type: ignore[call-arg]
541
- return self.request.post("v1/secret/rotate", SecretRotateResult, data=input.dict(exclude_none=True))
542
586
 
543
- def symmetric_generate(
587
+ return self.request.post(
588
+ "v2/secret/rotate",
589
+ Secret,
590
+ data=SecretRotateRequest(id=item_id, secret=secret, rotation_state=rotation_state),
591
+ )
592
+
593
+ def rotate_pangea_token(
544
594
  self,
545
- algorithm: SymmetricAlgorithm,
546
- purpose: KeyPurpose,
547
- name: Optional[str] = None,
548
- folder: Optional[str] = None,
549
- metadata: Optional[Metadata] = None,
550
- tags: Optional[Tags] = None,
551
- rotation_frequency: Optional[str] = None,
552
- rotation_state: Optional[ItemVersionState] = None,
553
- expiration: Optional[datetime.datetime] = None,
554
- ) -> PangeaResponse[SymmetricGenerateResult]:
595
+ item_id: str,
596
+ *,
597
+ rotation_grace_period: str | None = None,
598
+ rotation_state: RequestManualRotationState = RequestManualRotationState.DEACTIVATED,
599
+ ) -> PangeaResponse[PangeaToken]:
555
600
  """
556
- Symmetric generate
557
-
558
- Generate a symmetric key
601
+ Rotate secret
559
602
 
560
- OperationId: vault_post_v1_key_generate 2
603
+ Rotate a Pangea token.
561
604
 
562
605
  Args:
563
- algorithm (SymmetricAlgorithm): The algorithm of the key
564
- purpose (KeyPurpose): The purpose of this key
565
- name (str): The name of this item
566
- folder (str, optional): The folder where this item is stored
567
- metadata (dict, optional): User-provided metadata
568
- tags (list[str], optional): A list of user-defined tags
569
- rotation_frequency (str, optional): Period of time between item rotations, or `never` to disallow rotation
570
- rotation_state (ItemVersionState, optional): State to which the previous version should transition upon rotation.
571
- Supported options:
572
- - `deactivated`
573
- - `destroyed`
574
- expiration (str, optional): Expiration timestamp
606
+ item_id: The item ID.
607
+ rotation_grace_period: Grace period for the previous version of the
608
+ Pangea Token.
609
+ rotation_state: State to which the previous version should
610
+ transition upon rotation.
575
611
 
576
612
  Raises:
577
- PangeaAPIException: If an API Error happens
578
-
579
- Returns:
580
- A PangeaResponse where the ID of the key
581
- is returned in the response.result field.
582
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#generate).
613
+ PangeaAPIException: If an API Error happens.
583
614
 
584
615
  Examples:
585
- response = vault.symmetric_generate(
586
- algorithm=SymmetricAlgorithm.AES,
587
- purpose=KeyPurpose.ENCRYPTION,
588
- name="my-very-secret-secret",
589
- folder="/personal",
590
- metadata={
591
- "created_by": "John Doe",
592
- "used_in": "Google products"
593
- },
594
- tags=[
595
- "irs_2023",
596
- "personal"
597
- ],
598
- rotation_frequency="10d",
599
- rotation_state=ItemVersionState.DEACTIVATED,
600
- expiration="2025-01-01T10:00:00Z",
601
- )
616
+ response = vault.rotate_pangea_token(item_id="foo")
602
617
  """
603
- input = SymmetricGenerateRequest(
604
- type=ItemType.SYMMETRIC_KEY,
605
- algorithm=algorithm,
606
- purpose=purpose,
607
- name=name, # type: ignore[arg-type]
608
- folder=folder,
609
- metadata=metadata,
610
- tags=tags,
611
- rotation_frequency=rotation_frequency,
612
- rotation_state=rotation_state,
613
- expiration=expiration,
614
- )
618
+
615
619
  return self.request.post(
616
- "v1/key/generate",
617
- SymmetricGenerateResult,
618
- data=input.dict(exclude_none=True),
620
+ "v2/secret/rotate",
621
+ PangeaToken,
622
+ data=PangeaTokenRotateRequest(
623
+ id=item_id, rotation_grace_period=rotation_grace_period, rotation_state=rotation_state
624
+ ),
619
625
  )
620
626
 
621
- def asymmetric_generate(
627
+ def rotate_client_secret(
622
628
  self,
623
- algorithm: AsymmetricAlgorithm,
624
- purpose: KeyPurpose,
625
- name: Optional[str] = None,
626
- folder: Optional[str] = None,
627
- metadata: Optional[Metadata] = None,
628
- tags: Optional[Tags] = None,
629
- rotation_frequency: Optional[str] = None,
630
- rotation_state: Optional[ItemVersionState] = None,
631
- expiration: Optional[datetime.datetime] = None,
632
- ) -> PangeaResponse[AsymmetricGenerateResult]:
629
+ item_id: str,
630
+ *,
631
+ rotation_grace_period: str | None = None,
632
+ rotation_state: RequestManualRotationState = RequestManualRotationState.DEACTIVATED,
633
+ ) -> PangeaResponse[ClientSecret]:
633
634
  """
634
- Asymmetric generate
635
+ Rotate secret
635
636
 
636
- Generate an asymmetric key
637
-
638
- OperationId: vault_post_v1_key_generate 1
637
+ Rotate a client secret.
639
638
 
640
639
  Args:
641
- algorithm (AsymmetricAlgorithm): The algorithm of the key
642
- purpose (KeyPurpose): The purpose of this key
643
- name (str): The name of this item
644
- folder (str, optional): The folder where this item is stored
645
- metadata (dict, optional): User-provided metadata
646
- tags (list[str], optional): A list of user-defined tags
647
- rotation_frequency (str, optional): Period of time between item rotations, or `never` to disallow rotation
648
- rotation_state (ItemVersionState, optional): State to which the previous version should transition upon rotation.
649
- Supported options:
650
- - `deactivated`
651
- - `destroyed`
652
- expiration (str, optional): Expiration timestamp
640
+ item_id: The item ID.
641
+ rotation_grace_period: Grace period for the previous version of the
642
+ Pangea Token.
643
+ rotation_state: State to which the previous version should
644
+ transition upon rotation.
653
645
 
654
646
  Raises:
655
- PangeaAPIException: If an API Error happens
656
-
657
- Returns:
658
- A PangeaResponse where the ID of the key
659
- is returned in the response.result field.
660
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#generate).
647
+ PangeaAPIException: If an API Error happens.
661
648
 
662
649
  Examples:
663
- response = vault.asymmetric_generate(
664
- algorithm=AsymmetricAlgorithm.RSA,
665
- purpose=KeyPurpose.SIGNING,
666
- name="my-very-secret-secret",
667
- folder="/personal",
668
- metadata={
669
- "created_by": "John Doe",
670
- "used_in": "Google products"
671
- },
672
- tags=[
673
- "irs_2023",
674
- "personal"
675
- ],
676
- rotation_frequency="10d",
677
- rotation_state=ItemVersionState.DEACTIVATED,
678
- expiration="2025-01-01T10:00:00Z",
679
- )
650
+ response = vault.rotate_client_secret(item_id="foo")
680
651
  """
681
- input = AsymmetricGenerateRequest(
682
- type=ItemType.ASYMMETRIC_KEY,
683
- algorithm=algorithm,
684
- purpose=purpose,
685
- name=name, # type: ignore[arg-type]
686
- folder=folder,
687
- metadata=metadata,
688
- tags=tags,
689
- rotation_frequency=rotation_frequency,
690
- rotation_state=rotation_state,
691
- expiration=expiration,
692
- )
652
+
693
653
  return self.request.post(
694
- "v1/key/generate",
695
- AsymmetricGenerateResult,
696
- data=input.dict(exclude_none=True),
654
+ "v2/secret/rotate",
655
+ ClientSecret,
656
+ data=ClientSecretRotateRequest(
657
+ id=item_id, rotation_grace_period=rotation_grace_period, rotation_state=rotation_state
658
+ ),
697
659
  )
698
660
 
699
- # Store endpoints
700
- def asymmetric_store(
661
+ @overload
662
+ def generate_key(
701
663
  self,
702
- private_key: EncodedPrivateKey,
703
- public_key: EncodedPublicKey,
704
- algorithm: AsymmetricAlgorithm,
705
- purpose: KeyPurpose,
706
- name: str,
707
- folder: Optional[str] = None,
708
- metadata: Optional[Metadata] = None,
709
- tags: Optional[Tags] = None,
710
- rotation_frequency: Optional[str] = None,
711
- rotation_state: Optional[ItemVersionState] = None,
712
- expiration: Optional[datetime.datetime] = None,
713
- ) -> PangeaResponse[AsymmetricStoreResult]:
664
+ *,
665
+ key_type: Literal[ItemType.ASYMMETRIC_KEY],
666
+ purpose: Literal[AsymmetricKeyPurpose.SIGNING],
667
+ algorithm: AsymmetricKeySigningAlgorithm,
668
+ name: str | None = None,
669
+ folder: str | None = None,
670
+ metadata: Metadata | None = None,
671
+ tags: Tags | None = None,
672
+ rotation_frequency: str | None = None,
673
+ rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
674
+ disabled_at: datetime.datetime | None = None,
675
+ exportable: bool = False,
676
+ ) -> PangeaResponse[AsymmetricKey]:
714
677
  """
715
- Asymmetric store
678
+ Generate key
716
679
 
717
- Import an asymmetric key
718
-
719
- OperationId: vault_post_v1_key_store 1
680
+ Generate an asymmetric signing key.
720
681
 
721
682
  Args:
722
- private_key (EncodedPrivateKey): The private key in PEM format
723
- public_key (EncodedPublicKey): The public key in PEM format
724
- algorithm (AsymmetricAlgorithm): The algorithm of the key
725
- purpose (KeyPurpose): The purpose of this key. `signing`, `encryption`, or `jwt`.
726
- name (str): The name of this item
727
- folder (str, optional): The folder where this item is stored
728
- metadata (dict, optional): User-provided metadata
729
- tags (list[str], optional): A list of user-defined tags
730
- rotation_frequency (str, optional): Period of time between item rotations, or `never` to disallow rotation
731
- rotation_state (ItemVersionState, optional): State to which the previous version should transition upon rotation.
732
- Supported options:
733
- - `deactivated`
734
- - `destroyed`
735
- expiration (str, optional): Expiration timestamp
683
+ key_type: Key type.
684
+ purpose: The purpose of this key.
685
+ algorithm: The algorithm of the key.
686
+ name: The name of this item.
687
+ folder: The folder where this item is stored.
688
+ metadata: User-provided metadata.
689
+ tags: A list of user-defined tags.
690
+ rotation_frequency: Period of time between item rotations.
691
+ rotation_state: State to which the previous version should
692
+ transition upon rotation.
693
+ disabled_at: Timestamp indicating when the item will be disabled.
694
+ exportable: Whether the key is exportable or not.
736
695
 
737
696
  Raises:
738
- PangeaAPIException: If an API Error happens
739
-
740
- Returns:
741
- A PangeaResponse where the ID and public key
742
- is returned in the response.result field.
743
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#import-a-key).
697
+ PangeaAPIException: If an API Error happens.
744
698
 
745
699
  Examples:
746
- response = vault.asymmetric_store(
747
- private_key="private key example",
748
- public_key="-----BEGIN PUBLIC KEY-----\\nMCowBQYDK2VwAyEA8s5JopbEPGBylPBcMK+L5PqHMqPJW/5KYPgBHzZGncc=\\n-----END PUBLIC KEY-----",
749
- algorithm=AsymmetricAlgorithm.RSA,
750
- purpose=KeyPurpose.SIGNING,
751
- name="my-very-secret-secret",
752
- folder="/personal",
753
- metadata={
754
- "created_by": "John Doe",
755
- "used_in": "Google products"
756
- },
757
- tags=[
758
- "irs_2023",
759
- "personal"
760
- ],
761
- rotation_frequency="10d",
762
- rotation_state=ItemVersionState.DEACTIVATED,
763
- expiration="2025-01-01T10:00:00Z",
700
+ response = vault.generate_key(
701
+ key_type=ItemType.ASYMMETRIC_KEY,
702
+ purpose=AsymmetricKeyPurpose.SIGNING,
703
+ algorithm=AsymmetricKeySigningAlgorithm.ED25519,
764
704
  )
765
705
  """
766
- input = AsymmetricStoreRequest(
767
- type=ItemType.ASYMMETRIC_KEY,
768
- algorithm=algorithm,
769
- purpose=purpose,
770
- public_key=public_key,
771
- private_key=private_key,
772
- name=name,
773
- folder=folder,
774
- metadata=metadata,
775
- tags=tags,
776
- rotation_frequency=rotation_frequency,
777
- rotation_state=rotation_state,
778
- expiration=expiration,
779
- )
780
- return self.request.post("v1/key/store", AsymmetricStoreResult, data=input.dict(exclude_none=True))
781
706
 
782
- def symmetric_store(
707
+ @overload
708
+ def generate_key(
783
709
  self,
784
- key: str,
785
- algorithm: SymmetricAlgorithm,
786
- purpose: KeyPurpose,
787
- name: str,
788
- folder: Optional[str] = None,
789
- metadata: Optional[Metadata] = None,
790
- tags: Optional[Tags] = None,
791
- rotation_frequency: Optional[str] = None,
792
- rotation_state: Optional[ItemVersionState] = None,
793
- expiration: Optional[datetime.datetime] = None,
794
- ) -> PangeaResponse[SymmetricStoreResult]:
710
+ *,
711
+ key_type: Literal[ItemType.ASYMMETRIC_KEY],
712
+ purpose: Literal[AsymmetricKeyPurpose.ENCRYPTION],
713
+ algorithm: AsymmetricKeyEncryptionAlgorithm,
714
+ name: str | None = None,
715
+ folder: str | None = None,
716
+ metadata: Metadata | None = None,
717
+ tags: Tags | None = None,
718
+ rotation_frequency: str | None = None,
719
+ rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
720
+ disabled_at: datetime.datetime | None = None,
721
+ exportable: bool = False,
722
+ ) -> PangeaResponse[AsymmetricKey]:
795
723
  """
796
- Symmetric store
724
+ Generate key
797
725
 
798
- Import a symmetric key
799
-
800
- OperationId: vault_post_v1_key_store 2
726
+ Generate an asymmetric encryption key.
801
727
 
802
728
  Args:
803
- key (str): The key material (in base64)
804
- algorithm (SymmetricAlgorithm): The algorithm of the key
805
- purpose (KeyPurpose): The purpose of this key. `encryption` or `jwt`
806
- name (str): The name of this item
807
- folder (str, optional): The folder where this item is stored
808
- metadata (dict, optional): User-provided metadata
809
- tags (list[str], optional): A list of user-defined tags
810
- rotation_frequency (str, optional): Period of time between item rotations, or `never` to disallow rotation
811
- rotation_state (ItemVersionState, optional): State to which the previous version should transition upon rotation.
812
- Supported options:
813
- - `deactivated`
814
- - `destroyed`
815
- expiration (str, optional): Expiration timestamp
729
+ key_type: Key type.
730
+ purpose: The purpose of this key.
731
+ algorithm: The algorithm of the key.
732
+ name: The name of this item.
733
+ folder: The folder where this item is stored.
734
+ metadata: User-provided metadata.
735
+ tags: A list of user-defined tags.
736
+ rotation_frequency: Period of time between item rotations.
737
+ rotation_state: State to which the previous version should
738
+ transition upon rotation.
739
+ disabled_at: Timestamp indicating when the item will be disabled.
740
+ exportable: Whether the key is exportable or not.
816
741
 
817
742
  Raises:
818
- PangeaAPIException: If an API Error happens
819
-
820
- Returns:
821
- A PangeaResponse where the ID
822
- is returned in the response.result field.
823
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#import-a-key).
743
+ PangeaAPIException: If an API Error happens.
824
744
 
825
745
  Examples:
826
- response = vault.symmetric_store(
827
- key="lJkk0gCLux+Q+rPNqLPEYw==",
828
- algorithm=SymmetricAlgorithm.AES,
829
- purpose=KeyPurpose.ENCRYPTION,
830
- name="my-very-secret-secret",
831
- folder="/personal",
832
- metadata={
833
- "created_by": "John Doe",
834
- "used_in": "Google products"
835
- },
836
- tags=[
837
- "irs_2023",
838
- "personal"
839
- ],
840
- rotation_frequency="10d",
841
- rotation_state=ItemVersionState.DEACTIVATED,
842
- expiration="2025-01-01T10:00:00Z",
746
+ response = vault.generate_key(
747
+ key_type=ItemType.ASYMMETRIC_KEY,
748
+ purpose=AsymmetricKeyPurpose.ENCRYPTION,
749
+ algorithm=AsymmetricKeyEncryptionAlgorithm.RSA_OAEP_2048_SHA1,
843
750
  )
844
751
  """
845
- input = SymmetricStoreRequest(
846
- type=ItemType.SYMMETRIC_KEY,
847
- algorithm=algorithm,
848
- purpose=purpose,
849
- key=key, # type: ignore[arg-type]
850
- name=name,
851
- folder=folder,
852
- metadata=metadata,
853
- tags=tags,
854
- rotation_frequency=rotation_frequency,
855
- rotation_state=rotation_state,
856
- expiration=expiration,
857
- )
858
- return self.request.post("v1/key/store", SymmetricStoreResult, data=input.dict(exclude_none=True))
859
752
 
860
- # Rotate endpoint
861
- def key_rotate(
753
+ @overload
754
+ def generate_key(
862
755
  self,
863
- id: str,
864
- rotation_state: ItemVersionState,
865
- public_key: Optional[EncodedPublicKey] = None,
866
- private_key: Optional[EncodedPrivateKey] = None,
867
- key: Optional[EncodedSymmetricKey] = None,
868
- ) -> PangeaResponse[KeyRotateResult]:
756
+ *,
757
+ key_type: Literal[ItemType.ASYMMETRIC_KEY],
758
+ purpose: Literal[AsymmetricKeyPurpose.JWT],
759
+ algorithm: AsymmetricKeyJwtAlgorithm,
760
+ name: str | None = None,
761
+ folder: str | None = None,
762
+ metadata: Metadata | None = None,
763
+ tags: Tags | None = None,
764
+ rotation_frequency: str | None = None,
765
+ rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
766
+ disabled_at: datetime.datetime | None = None,
767
+ exportable: bool = False,
768
+ ) -> PangeaResponse[AsymmetricKey]:
869
769
  """
870
- Key rotate
770
+ Generate key
871
771
 
872
- Manually rotate a symmetric or asymmetric key
873
-
874
- OperationId: vault_post_v1_key_rotate
772
+ Generate an asymmetric JWT key.
875
773
 
876
774
  Args:
877
- id (str): The ID of the item
878
- rotation_state (ItemVersionState, optional): State to which the previous version should transition upon rotation.
879
- Supported options:
880
- - `deactivated`
881
- - `suspended`
882
- - `destroyed`
883
-
884
- Default is `deactivated`.
885
- public_key (EncodedPublicKey, optional): The public key (in PEM format)
886
- private_key (EncodedPrivateKey, optional): The private key (in PEM format)
887
- key (EncodedSymmetricKey, optional): The key material (in base64)
775
+ key_type: Key type.
776
+ purpose: The purpose of this key.
777
+ algorithm: The algorithm of the key.
778
+ name: The name of this item.
779
+ folder: The folder where this item is stored.
780
+ metadata: User-provided metadata.
781
+ tags: A list of user-defined tags.
782
+ rotation_frequency: Period of time between item rotations.
783
+ rotation_state: State to which the previous version should
784
+ transition upon rotation.
785
+ disabled_at: Timestamp indicating when the item will be disabled.
786
+ exportable: Whether the key is exportable or not.
888
787
 
889
788
  Raises:
890
- PangeaAPIException: If an API Error happens
891
-
892
- Returns:
893
- A PangeaResponse where the ID
894
- is returned in the response.result field.
895
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#rotate).
789
+ PangeaAPIException: If an API Error happens.
896
790
 
897
791
  Examples:
898
- response = vault.key_rotate(
899
- id="pvi_p6g5i3gtbvqvc3u6zugab6qs6r63tqf5",
900
- rotation_state=ItemVersionState.DEACTIVATED,
901
- key="lJkk0gCLux+Q+rPNqLPEYw==",
792
+ response = vault.generate_key(
793
+ key_type=ItemType.ASYMMETRIC_KEY,
794
+ purpose=AsymmetricKeyPurpose.JWT,
795
+ algorithm=AsymmetricKeyJwtAlgorithm.ES512,
902
796
  )
903
797
  """
904
- input = KeyRotateRequest(
905
- id=id,
906
- public_key=public_key,
907
- private_key=private_key,
908
- key=key,
909
- rotation_state=rotation_state,
910
- )
911
- return self.request.post("v1/key/rotate", KeyRotateResult, data=input.dict(exclude_none=True))
912
798
 
913
- # Encrypt
914
- def encrypt(self, id: str, plain_text: str, version: Optional[int] = None) -> PangeaResponse[EncryptResult]:
799
+ @overload
800
+ def generate_key(
801
+ self,
802
+ *,
803
+ key_type: Literal[ItemType.ASYMMETRIC_KEY],
804
+ purpose: Literal[AsymmetricKeyPurpose.PKI],
805
+ algorithm: AsymmetricKeyPkiAlgorithm,
806
+ name: str | None = None,
807
+ folder: str | None = None,
808
+ metadata: Metadata | None = None,
809
+ tags: Tags | None = None,
810
+ rotation_frequency: str | None = None,
811
+ rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
812
+ disabled_at: datetime.datetime | None = None,
813
+ exportable: bool = False,
814
+ ) -> PangeaResponse[AsymmetricKey]:
915
815
  """
916
- Encrypt
917
-
918
- Encrypt a message using a key
816
+ Generate key
919
817
 
920
- OperationId: vault_post_v1_key_encrypt
818
+ Generate an asymmetric PKI key.
921
819
 
922
820
  Args:
923
- id (str): The item ID
924
- plain_text (str): A message to be in encrypted (in base64)
925
- version (int, optional): The item version
821
+ key_type: Key type.
822
+ purpose: The purpose of this key.
823
+ algorithm: The algorithm of the key.
824
+ name: The name of this item.
825
+ folder: The folder where this item is stored.
826
+ metadata: User-provided metadata.
827
+ tags: A list of user-defined tags.
828
+ rotation_frequency: Period of time between item rotations.
829
+ rotation_state: State to which the previous version should
830
+ transition upon rotation.
831
+ disabled_at: Timestamp indicating when the item will be disabled.
832
+ exportable: Whether the key is exportable or not.
926
833
 
927
834
  Raises:
928
- PangeaAPIException: If an API Error happens
929
-
930
- Returns:
931
- A PangeaResponse where the encrypted message in base64
932
- is returned in the response.result field.
933
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#encrypt).
835
+ PangeaAPIException: If an API Error happens.
934
836
 
935
837
  Examples:
936
- response = vault.encrypt(
937
- id="pvi_p6g5i3gtbvqvc3u6zugab6qs6r63tqf5",
938
- plain_text="lJkk0gCLux+Q+rPNqLPEYw==",
939
- version=1,
838
+ response = vault.generate_key(
839
+ key_type=ItemType.ASYMMETRIC_KEY,
840
+ purpose=AsymmetricKeyPurpose.PKI,
841
+ algorithm=AsymmetricKeyPkiAlgorithm.ED25519,
940
842
  )
941
843
  """
942
- input = EncryptRequest(id=id, plain_text=plain_text, version=version) # type: ignore[call-arg]
943
- return self.request.post("v1/key/encrypt", EncryptResult, data=input.dict(exclude_none=True))
944
844
 
945
- # Decrypt
946
- def decrypt(self, id: str, cipher_text: str, version: Optional[int] = None) -> PangeaResponse[DecryptResult]:
845
+ @overload
846
+ def generate_key(
847
+ self,
848
+ *,
849
+ key_type: Literal[ItemType.ASYMMETRIC_KEY],
850
+ purpose: AsymmetricKeyPurpose,
851
+ algorithm: AsymmetricKeyAlgorithm,
852
+ name: str | None = None,
853
+ folder: str | None = None,
854
+ metadata: Metadata | None = None,
855
+ tags: Tags | None = None,
856
+ rotation_frequency: str | None = None,
857
+ rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
858
+ disabled_at: datetime.datetime | None = None,
859
+ exportable: bool = False,
860
+ ) -> PangeaResponse[AsymmetricKey]:
947
861
  """
948
- Decrypt
862
+ Generate key
949
863
 
950
- Decrypt a message using a key
951
-
952
- OperationId: vault_post_v1_key_decrypt
864
+ Generate an asymmetric key.
953
865
 
954
866
  Args:
955
- id (str): The item ID
956
- cipher_text (str): A message encrypted by Vault (in base64)
957
- version (int, optional): The item version
867
+ key_type: Key type.
868
+ purpose: The purpose of this key.
869
+ algorithm: The algorithm of the key.
870
+ name: The name of this item.
871
+ folder: The folder where this item is stored.
872
+ metadata: User-provided metadata.
873
+ tags: A list of user-defined tags.
874
+ rotation_frequency: Period of time between item rotations.
875
+ rotation_state: State to which the previous version should
876
+ transition upon rotation.
877
+ disabled_at: Timestamp indicating when the item will be disabled.
878
+ exportable: Whether the key is exportable or not.
958
879
 
959
880
  Raises:
960
- PangeaAPIException: If an API Error happens
961
-
962
- Returns:
963
- A PangeaResponse where the decrypted message in base64
964
- is returned in the response.result field.
965
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#decrypt).
881
+ PangeaAPIException: If an API Error happens.
966
882
 
967
883
  Examples:
968
- response = vault.decrypt(
969
- id="pvi_p6g5i3gtbvqvc3u6zugab6qs6r63tqf5",
970
- cipher_text="lJkk0gCLux+Q+rPNqLPEYw==",
971
- version=1,
884
+ response = vault.generate_key(
885
+ key_type=ItemType.ASYMMETRIC_KEY,
886
+ purpose=AsymmetricKeyPurpose.PKI,
887
+ algorithm=AsymmetricKeyPkiAlgorithm.ED25519,
972
888
  )
973
889
  """
974
- input = DecryptRequest(id=id, cipher_text=cipher_text, version=version) # type: ignore[call-arg]
975
- return self.request.post("v1/key/decrypt", DecryptResult, data=input.dict(exclude_none=True))
976
890
 
977
- # Sign
978
- def sign(self, id: str, message: str, version: Optional[int] = None) -> PangeaResponse[SignResult]:
891
+ @overload
892
+ def generate_key(
893
+ self,
894
+ *,
895
+ key_type: Literal[ItemType.SYMMETRIC_KEY],
896
+ purpose: Literal[SymmetricKeyPurpose.ENCRYPTION],
897
+ algorithm: SymmetricKeyEncryptionAlgorithm,
898
+ name: str | None = None,
899
+ folder: str | None = None,
900
+ metadata: Metadata | None = None,
901
+ tags: Tags | None = None,
902
+ rotation_frequency: str | None = None,
903
+ rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
904
+ disabled_at: datetime.datetime | None = None,
905
+ exportable: bool = False,
906
+ ) -> PangeaResponse[SymmetricKey]:
979
907
  """
980
- Sign
908
+ Generate key
981
909
 
982
- Sign a message using a key
910
+ Generate a symmetric encryption key.
983
911
 
984
- OperationId: vault_post_v1_key_sign
912
+ Args:
913
+ key_type: Key type.
914
+ purpose: The purpose of this key.
915
+ algorithm: The algorithm of the key.
916
+ name: The name of this item.
917
+ folder: The folder where this item is stored.
918
+ metadata: User-provided metadata.
919
+ tags: A list of user-defined tags.
920
+ rotation_frequency: Period of time between item rotations.
921
+ rotation_state: State to which the previous version should
922
+ transition upon rotation.
923
+ disabled_at: Timestamp indicating when the item will be disabled.
924
+ exportable: Whether the key is exportable or not.
925
+
926
+ Raises:
927
+ PangeaAPIException: If an API Error happens.
928
+
929
+ Examples:
930
+ response = vault.generate_key(
931
+ key_type=ItemType.SYMMETRIC_KEY,
932
+ purpose=SymmetricKeyPurpose.ENCRYPTION,
933
+ algorithm=SymmetricKeyEncryptionAlgorithm.AES_CFB_128,
934
+ )
935
+ """
936
+
937
+ @overload
938
+ def generate_key(
939
+ self,
940
+ *,
941
+ key_type: Literal[ItemType.SYMMETRIC_KEY],
942
+ purpose: Literal[SymmetricKeyPurpose.JWT],
943
+ algorithm: SymmetricKeyJwtAlgorithm,
944
+ name: str | None = None,
945
+ folder: str | None = None,
946
+ metadata: Metadata | None = None,
947
+ tags: Tags | None = None,
948
+ rotation_frequency: str | None = None,
949
+ rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
950
+ disabled_at: datetime.datetime | None = None,
951
+ exportable: bool = False,
952
+ ) -> PangeaResponse[SymmetricKey]:
953
+ """
954
+ Generate key
955
+
956
+ Generate a symmetric JWT key.
957
+
958
+ Args:
959
+ key_type: Key type.
960
+ purpose: The purpose of this key.
961
+ algorithm: The algorithm of the key.
962
+ name: The name of this item.
963
+ folder: The folder where this item is stored.
964
+ metadata: User-provided metadata.
965
+ tags: A list of user-defined tags.
966
+ rotation_frequency: Period of time between item rotations.
967
+ rotation_state: State to which the previous version should
968
+ transition upon rotation.
969
+ disabled_at: Timestamp indicating when the item will be disabled.
970
+ exportable: Whether the key is exportable or not.
971
+
972
+ Raises:
973
+ PangeaAPIException: If an API Error happens.
974
+
975
+ Examples:
976
+ response = vault.generate_key(
977
+ key_type=ItemType.SYMMETRIC_KEY,
978
+ purpose=SymmetricKeyPurpose.JWT,
979
+ algorithm=SymmetricKeyJwtAlgorithm.HS512,
980
+ )
981
+ """
982
+
983
+ @overload
984
+ def generate_key(
985
+ self,
986
+ *,
987
+ key_type: Literal[ItemType.SYMMETRIC_KEY],
988
+ purpose: Literal[SymmetricKeyPurpose.FPE],
989
+ algorithm: SymmetricKeyFpeAlgorithm,
990
+ name: str | None = None,
991
+ folder: str | None = None,
992
+ metadata: Metadata | None = None,
993
+ tags: Tags | None = None,
994
+ rotation_frequency: str | None = None,
995
+ rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
996
+ disabled_at: datetime.datetime | None = None,
997
+ exportable: bool = False,
998
+ ) -> PangeaResponse[SymmetricKey]:
999
+ """
1000
+ Generate key
1001
+
1002
+ Generate a symmetric FPE key.
1003
+
1004
+ Args:
1005
+ key_type: Key type.
1006
+ purpose: The purpose of this key.
1007
+ algorithm: The algorithm of the key.
1008
+ name: The name of this item.
1009
+ folder: The folder where this item is stored.
1010
+ metadata: User-provided metadata.
1011
+ tags: A list of user-defined tags.
1012
+ rotation_frequency: Period of time between item rotations.
1013
+ rotation_state: State to which the previous version should
1014
+ transition upon rotation.
1015
+ disabled_at: Timestamp indicating when the item will be disabled.
1016
+ exportable: Whether the key is exportable or not.
1017
+
1018
+ Raises:
1019
+ PangeaAPIException: If an API Error happens.
1020
+
1021
+ Examples:
1022
+ response = vault.generate_key(
1023
+ key_type=ItemType.SYMMETRIC_KEY,
1024
+ purpose=SymmetricKeyPurpose.FPE,
1025
+ algorithm=SymmetricKeyFpeAlgorithm.AES_FF3_1_256_BETA,
1026
+ )
1027
+ """
1028
+
1029
+ @overload
1030
+ def generate_key(
1031
+ self,
1032
+ *,
1033
+ key_type: Literal[ItemType.SYMMETRIC_KEY],
1034
+ purpose: SymmetricKeyPurpose,
1035
+ algorithm: SymmetricKeyAlgorithm,
1036
+ name: str | None = None,
1037
+ folder: str | None = None,
1038
+ metadata: Metadata | None = None,
1039
+ tags: Tags | None = None,
1040
+ rotation_frequency: str | None = None,
1041
+ rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
1042
+ disabled_at: datetime.datetime | None = None,
1043
+ exportable: bool = False,
1044
+ ) -> PangeaResponse[SymmetricKey]:
1045
+ """
1046
+ Generate key
1047
+
1048
+ Generate a symmetric key.
1049
+
1050
+ Args:
1051
+ key_type: Key type.
1052
+ purpose: The purpose of this key.
1053
+ algorithm: The algorithm of the key.
1054
+ name: The name of this item.
1055
+ folder: The folder where this item is stored.
1056
+ metadata: User-provided metadata.
1057
+ tags: A list of user-defined tags.
1058
+ rotation_frequency: Period of time between item rotations.
1059
+ rotation_state: State to which the previous version should
1060
+ transition upon rotation.
1061
+ disabled_at: Timestamp indicating when the item will be disabled.
1062
+ exportable: Whether the key is exportable or not.
1063
+
1064
+ Raises:
1065
+ PangeaAPIException: If an API Error happens.
1066
+
1067
+ Examples:
1068
+ response = vault.generate_key(
1069
+ key_type=ItemType.SYMMETRIC_KEY,
1070
+ purpose=SymmetricKeyPurpose.FPE,
1071
+ algorithm=SymmetricKeyFpeAlgorithm.AES_FF3_1_256_BETA,
1072
+ )
1073
+ """
1074
+
1075
+ def generate_key(
1076
+ self,
1077
+ *,
1078
+ key_type: Literal[ItemType.ASYMMETRIC_KEY, ItemType.SYMMETRIC_KEY],
1079
+ purpose: SymmetricKeyPurpose | AsymmetricKeyPurpose,
1080
+ algorithm: AsymmetricKeyAlgorithm | SymmetricKeyAlgorithm,
1081
+ name: str | None = None,
1082
+ folder: str | None = None,
1083
+ metadata: Metadata | None = None,
1084
+ tags: Tags | None = None,
1085
+ rotation_frequency: str | None = None,
1086
+ rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
1087
+ disabled_at: datetime.datetime | None = None,
1088
+ exportable: bool = False,
1089
+ ) -> PangeaResponse[Any]:
1090
+ """
1091
+ Generate key
1092
+
1093
+ Generate a key.
1094
+
1095
+ Args:
1096
+ key_type: Key type.
1097
+ purpose: The purpose of this key.
1098
+ algorithm: The algorithm of the key.
1099
+ name: The name of this item.
1100
+ folder: The folder where this item is stored.
1101
+ metadata: User-provided metadata.
1102
+ tags: A list of user-defined tags.
1103
+ rotation_frequency: Period of time between item rotations.
1104
+ rotation_state: State to which the previous version should
1105
+ transition upon rotation.
1106
+ disabled_at: Timestamp indicating when the item will be disabled.
1107
+ exportable: Whether the key is exportable or not.
1108
+
1109
+ Raises:
1110
+ PangeaAPIException: If an API Error happens.
1111
+
1112
+ Examples:
1113
+ response = vault.generate_key(
1114
+ key_type=ItemType.SYMMETRIC_KEY,
1115
+ purpose=SymmetricKeyPurpose.FPE,
1116
+ algorithm=SymmetricKeyFpeAlgorithm.AES_FF3_1_256_BETA,
1117
+ )
1118
+ """
1119
+
1120
+ return self.request.post(
1121
+ "v2/key/generate",
1122
+ AsymmetricKey if key_type == ItemType.ASYMMETRIC_KEY else SymmetricKey,
1123
+ data=CommonGenerateRequest(
1124
+ type=key_type,
1125
+ purpose=purpose,
1126
+ algorithm=algorithm,
1127
+ name=name,
1128
+ folder=folder,
1129
+ metadata=metadata,
1130
+ tags=tags,
1131
+ rotation_frequency=rotation_frequency,
1132
+ rotation_state=rotation_state,
1133
+ disabled_at=disabled_at,
1134
+ exportable=exportable,
1135
+ ),
1136
+ )
1137
+
1138
+ @overload
1139
+ def store_key(
1140
+ self,
1141
+ *,
1142
+ key_type: Literal[ItemType.ASYMMETRIC_KEY],
1143
+ purpose: Literal[AsymmetricKeyPurpose.SIGNING],
1144
+ algorithm: AsymmetricKeySigningAlgorithm,
1145
+ public_key: str,
1146
+ private_key: str,
1147
+ name: str | None = None,
1148
+ folder: str | None = None,
1149
+ metadata: Metadata | None = None,
1150
+ tags: Tags | None = None,
1151
+ rotation_frequency: str | None = None,
1152
+ rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
1153
+ disabled_at: datetime.datetime | None = None,
1154
+ exportable: bool = False,
1155
+ ) -> PangeaResponse[AsymmetricKey]:
1156
+ """
1157
+ Store key
1158
+
1159
+ Import an asymmetric signing key.
1160
+
1161
+ Args:
1162
+ key_type: Key type.
1163
+ purpose: The purpose of this key.
1164
+ algorithm: The algorithm of the key.
1165
+ public_key: The public key (in PEM format).
1166
+ private_key: The private key (in PEM format).
1167
+ name: The name of this item.
1168
+ folder: The folder where this item is stored.
1169
+ metadata: User-provided metadata.
1170
+ tags: A list of user-defined tags.
1171
+ rotation_frequency: Period of time between item rotations.
1172
+ rotation_state: State to which the previous version should
1173
+ transition upon rotation.
1174
+ disabled_at: Timestamp indicating when the item will be disabled.
1175
+ exportable: Whether the key is exportable or not.
1176
+
1177
+ Raises:
1178
+ PangeaAPIException: If an API Error happens.
1179
+
1180
+ Examples:
1181
+ response = vault.store_key(
1182
+ key_type=ItemType.ASYMMETRIC_KEY,
1183
+ purpose=AsymmetricKeyPurpose.SIGNING,
1184
+ algorithm=AsymmetricKeySigningAlgorithm.ED25519,
1185
+ )
1186
+ """
1187
+
1188
+ @overload
1189
+ def store_key(
1190
+ self,
1191
+ *,
1192
+ key_type: Literal[ItemType.ASYMMETRIC_KEY],
1193
+ purpose: Literal[AsymmetricKeyPurpose.ENCRYPTION],
1194
+ algorithm: AsymmetricKeyEncryptionAlgorithm,
1195
+ public_key: str,
1196
+ private_key: str,
1197
+ name: str | None = None,
1198
+ folder: str | None = None,
1199
+ metadata: Metadata | None = None,
1200
+ tags: Tags | None = None,
1201
+ rotation_frequency: str | None = None,
1202
+ rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
1203
+ disabled_at: datetime.datetime | None = None,
1204
+ exportable: bool = False,
1205
+ ) -> PangeaResponse[AsymmetricKey]:
1206
+ """
1207
+ Store key
1208
+
1209
+ Import an asymmetric encryption key.
1210
+
1211
+ Args:
1212
+ key_type: Key type.
1213
+ purpose: The purpose of this key.
1214
+ algorithm: The algorithm of the key.
1215
+ public_key: The public key (in PEM format).
1216
+ private_key: The private key (in PEM format).
1217
+ name: The name of this item.
1218
+ folder: The folder where this item is stored.
1219
+ metadata: User-provided metadata.
1220
+ tags: A list of user-defined tags.
1221
+ rotation_frequency: Period of time between item rotations.
1222
+ rotation_state: State to which the previous version should
1223
+ transition upon rotation.
1224
+ disabled_at: Timestamp indicating when the item will be disabled.
1225
+ exportable: Whether the key is exportable or not.
1226
+
1227
+ Raises:
1228
+ PangeaAPIException: If an API Error happens.
1229
+
1230
+ Examples:
1231
+ response = vault.store_key(
1232
+ key_type=ItemType.ASYMMETRIC_KEY,
1233
+ purpose=AsymmetricKeyPurpose.ENCRYPTION,
1234
+ algorithm=AsymmetricKeyEncryptionAlgorithm.RSA_OAEP_2048_SHA1,
1235
+ )
1236
+ """
1237
+
1238
+ @overload
1239
+ def store_key(
1240
+ self,
1241
+ *,
1242
+ key_type: Literal[ItemType.ASYMMETRIC_KEY],
1243
+ purpose: Literal[AsymmetricKeyPurpose.JWT],
1244
+ algorithm: AsymmetricKeyJwtAlgorithm,
1245
+ public_key: str,
1246
+ private_key: str,
1247
+ name: str | None = None,
1248
+ folder: str | None = None,
1249
+ metadata: Metadata | None = None,
1250
+ tags: Tags | None = None,
1251
+ rotation_frequency: str | None = None,
1252
+ rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
1253
+ disabled_at: datetime.datetime | None = None,
1254
+ exportable: bool = False,
1255
+ ) -> PangeaResponse[AsymmetricKey]:
1256
+ """
1257
+ Store key
1258
+
1259
+ Import an asymmetric JWT key.
1260
+
1261
+ Args:
1262
+ key_type: Key type.
1263
+ purpose: The purpose of this key.
1264
+ algorithm: The algorithm of the key.
1265
+ public_key: The public key (in PEM format).
1266
+ private_key: The private key (in PEM format).
1267
+ name: The name of this item.
1268
+ folder: The folder where this item is stored.
1269
+ metadata: User-provided metadata.
1270
+ tags: A list of user-defined tags.
1271
+ rotation_frequency: Period of time between item rotations.
1272
+ rotation_state: State to which the previous version should
1273
+ transition upon rotation.
1274
+ disabled_at: Timestamp indicating when the item will be disabled.
1275
+ exportable: Whether the key is exportable or not.
1276
+
1277
+ Raises:
1278
+ PangeaAPIException: If an API Error happens.
1279
+
1280
+ Examples:
1281
+ response = vault.store_key(
1282
+ key_type=ItemType.ASYMMETRIC_KEY,
1283
+ purpose=AsymmetricKeyPurpose.JWT,
1284
+ algorithm=AsymmetricKeyJwtAlgorithm.ES512,
1285
+ )
1286
+ """
1287
+
1288
+ @overload
1289
+ def store_key(
1290
+ self,
1291
+ *,
1292
+ key_type: Literal[ItemType.ASYMMETRIC_KEY],
1293
+ purpose: Literal[AsymmetricKeyPurpose.PKI],
1294
+ algorithm: AsymmetricKeyPkiAlgorithm,
1295
+ public_key: str,
1296
+ private_key: str,
1297
+ name: str | None = None,
1298
+ folder: str | None = None,
1299
+ metadata: Metadata | None = None,
1300
+ tags: Tags | None = None,
1301
+ rotation_frequency: str | None = None,
1302
+ rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
1303
+ disabled_at: datetime.datetime | None = None,
1304
+ exportable: bool = False,
1305
+ ) -> PangeaResponse[AsymmetricKey]:
1306
+ """
1307
+ Store key
1308
+
1309
+ Import an asymmetric PKI key.
1310
+
1311
+ Args:
1312
+ key_type: Key type.
1313
+ purpose: The purpose of this key.
1314
+ algorithm: The algorithm of the key.
1315
+ public_key: The public key (in PEM format).
1316
+ private_key: The private key (in PEM format).
1317
+ name: The name of this item.
1318
+ folder: The folder where this item is stored.
1319
+ metadata: User-provided metadata.
1320
+ tags: A list of user-defined tags.
1321
+ rotation_frequency: Period of time between item rotations.
1322
+ rotation_state: State to which the previous version should
1323
+ transition upon rotation.
1324
+ disabled_at: Timestamp indicating when the item will be disabled.
1325
+ exportable: Whether the key is exportable or not.
1326
+
1327
+ Raises:
1328
+ PangeaAPIException: If an API Error happens.
1329
+
1330
+ Examples:
1331
+ response = vault.store_key(
1332
+ key_type=ItemType.ASYMMETRIC_KEY,
1333
+ purpose=AsymmetricKeyPurpose.PKI,
1334
+ algorithm=AsymmetricKeyPkiAlgorithm.ED25519,
1335
+ )
1336
+ """
1337
+
1338
+ @overload
1339
+ def store_key(
1340
+ self,
1341
+ *,
1342
+ key_type: Literal[ItemType.SYMMETRIC_KEY],
1343
+ purpose: Literal[SymmetricKeyPurpose.ENCRYPTION],
1344
+ algorithm: SymmetricKeyEncryptionAlgorithm,
1345
+ key: str,
1346
+ name: str | None = None,
1347
+ folder: str | None = None,
1348
+ metadata: Metadata | None = None,
1349
+ tags: Tags | None = None,
1350
+ rotation_frequency: str | None = None,
1351
+ rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
1352
+ disabled_at: datetime.datetime | None = None,
1353
+ exportable: bool = False,
1354
+ ) -> PangeaResponse[SymmetricKey]:
1355
+ """
1356
+ Store key
1357
+
1358
+ Import a symmetric encryption key.
1359
+
1360
+ Args:
1361
+ key_type: Key type.
1362
+ purpose: The purpose of this key.
1363
+ algorithm: The algorithm of the key.
1364
+ key: The key material.
1365
+ name: The name of this item.
1366
+ folder: The folder where this item is stored.
1367
+ metadata: User-provided metadata.
1368
+ tags: A list of user-defined tags.
1369
+ rotation_frequency: Period of time between item rotations.
1370
+ rotation_state: State to which the previous version should
1371
+ transition upon rotation.
1372
+ disabled_at: Timestamp indicating when the item will be disabled.
1373
+ exportable: Whether the key is exportable or not.
1374
+
1375
+ Raises:
1376
+ PangeaAPIException: If an API Error happens.
1377
+
1378
+ Examples:
1379
+ response = vault.store_key(
1380
+ key_type=ItemType.SYMMETRIC_KEY,
1381
+ purpose=SymmetricKeyPurpose.ENCRYPTION,
1382
+ algorithm=SymmetricKeyEncryptionAlgorithm.AES_CFB_128,
1383
+ )
1384
+ """
1385
+
1386
+ @overload
1387
+ def store_key(
1388
+ self,
1389
+ *,
1390
+ key_type: Literal[ItemType.SYMMETRIC_KEY],
1391
+ purpose: Literal[SymmetricKeyPurpose.JWT],
1392
+ algorithm: SymmetricKeyJwtAlgorithm,
1393
+ key: str,
1394
+ name: str | None = None,
1395
+ folder: str | None = None,
1396
+ metadata: Metadata | None = None,
1397
+ tags: Tags | None = None,
1398
+ rotation_frequency: str | None = None,
1399
+ rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
1400
+ disabled_at: datetime.datetime | None = None,
1401
+ exportable: bool = False,
1402
+ ) -> PangeaResponse[SymmetricKey]:
1403
+ """
1404
+ Store key
1405
+
1406
+ Import a symmetric JWT key.
1407
+
1408
+ Args:
1409
+ key_type: Key type.
1410
+ purpose: The purpose of this key.
1411
+ algorithm: The algorithm of the key.
1412
+ key: The key material.
1413
+ name: The name of this item.
1414
+ folder: The folder where this item is stored.
1415
+ metadata: User-provided metadata.
1416
+ tags: A list of user-defined tags.
1417
+ rotation_frequency: Period of time between item rotations.
1418
+ rotation_state: State to which the previous version should
1419
+ transition upon rotation.
1420
+ disabled_at: Timestamp indicating when the item will be disabled.
1421
+ exportable: Whether the key is exportable or not.
1422
+
1423
+ Raises:
1424
+ PangeaAPIException: If an API Error happens.
1425
+
1426
+ Examples:
1427
+ response = vault.store_key(
1428
+ key_type=ItemType.SYMMETRIC_KEY,
1429
+ purpose=SymmetricKeyPurpose.JWT,
1430
+ algorithm=SymmetricKeyJwtAlgorithm.HS512,
1431
+ )
1432
+ """
1433
+
1434
+ @overload
1435
+ def store_key(
1436
+ self,
1437
+ *,
1438
+ key_type: Literal[ItemType.SYMMETRIC_KEY],
1439
+ purpose: Literal[SymmetricKeyPurpose.FPE],
1440
+ algorithm: SymmetricKeyFpeAlgorithm,
1441
+ key: str,
1442
+ name: str | None = None,
1443
+ folder: str | None = None,
1444
+ metadata: Metadata | None = None,
1445
+ tags: Tags | None = None,
1446
+ rotation_frequency: str | None = None,
1447
+ rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
1448
+ disabled_at: datetime.datetime | None = None,
1449
+ exportable: bool = False,
1450
+ ) -> PangeaResponse[SymmetricKey]:
1451
+ """
1452
+ Store key
1453
+
1454
+ Import a symmetric FPE key.
1455
+
1456
+ Args:
1457
+ key_type: Key type.
1458
+ purpose: The purpose of this key.
1459
+ algorithm: The algorithm of the key.
1460
+ key: The key material.
1461
+ name: The name of this item.
1462
+ folder: The folder where this item is stored.
1463
+ metadata: User-provided metadata.
1464
+ tags: A list of user-defined tags.
1465
+ rotation_frequency: Period of time between item rotations.
1466
+ rotation_state: State to which the previous version should
1467
+ transition upon rotation.
1468
+ disabled_at: Timestamp indicating when the item will be disabled.
1469
+ exportable: Whether the key is exportable or not.
1470
+
1471
+ Raises:
1472
+ PangeaAPIException: If an API Error happens.
1473
+
1474
+ Examples:
1475
+ response = vault.store_key(
1476
+ key_type=ItemType.SYMMETRIC_KEY,
1477
+ purpose=SymmetricKeyPurpose.FPE,
1478
+ algorithm=SymmetricKeyFpeAlgorithm.AES_FF3_1_256_BETA,
1479
+ )
1480
+ """
1481
+
1482
+ def store_key(
1483
+ self,
1484
+ *,
1485
+ key_type: Literal[ItemType.ASYMMETRIC_KEY, ItemType.SYMMETRIC_KEY],
1486
+ purpose: SymmetricKeyPurpose | AsymmetricKeyPurpose,
1487
+ algorithm: (
1488
+ AsymmetricKeySigningAlgorithm
1489
+ | AsymmetricKeyEncryptionAlgorithm
1490
+ | AsymmetricKeyJwtAlgorithm
1491
+ | AsymmetricKeyPkiAlgorithm
1492
+ | SymmetricKeyEncryptionAlgorithm
1493
+ | SymmetricKeyJwtAlgorithm
1494
+ | SymmetricKeyFpeAlgorithm
1495
+ ),
1496
+ public_key: str | None = None,
1497
+ private_key: str | None = None,
1498
+ key: str | None = None,
1499
+ name: str | None = None,
1500
+ folder: str | None = None,
1501
+ metadata: Metadata | None = None,
1502
+ tags: Tags | None = None,
1503
+ rotation_frequency: str | None = None,
1504
+ rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
1505
+ disabled_at: datetime.datetime | None = None,
1506
+ exportable: bool = False,
1507
+ ) -> PangeaResponse[Any]:
1508
+ """
1509
+ Store key
1510
+
1511
+ Import a key.
1512
+
1513
+ Args:
1514
+ key_type: Key type.
1515
+ purpose: The purpose of this key.
1516
+ algorithm: The algorithm of the key.
1517
+ public_key: The public key (in PEM format).
1518
+ private_key: The private key (in PEM format).
1519
+ key: The key material.
1520
+ name: The name of this item.
1521
+ folder: The folder where this item is stored.
1522
+ metadata: User-provided metadata.
1523
+ tags: A list of user-defined tags.
1524
+ rotation_frequency: Period of time between item rotations.
1525
+ rotation_state: State to which the previous version should
1526
+ transition upon rotation.
1527
+ disabled_at: Timestamp indicating when the item will be disabled.
1528
+ exportable: Whether the key is exportable or not.
1529
+
1530
+ Raises:
1531
+ PangeaAPIException: If an API Error happens.
1532
+
1533
+ Examples:
1534
+ response = vault.store_key(
1535
+ key_type=ItemType.SYMMETRIC_KEY,
1536
+ purpose=SymmetricKeyPurpose.FPE,
1537
+ algorithm=SymmetricKeyFpeAlgorithm.AES_FF3_1_256_BETA,
1538
+ )
1539
+ """
1540
+
1541
+ return self.request.post(
1542
+ "v2/key/store",
1543
+ AsymmetricKey if key_type == ItemType.ASYMMETRIC_KEY else SymmetricKey,
1544
+ data=KeyStoreRequest(
1545
+ type=key_type,
1546
+ purpose=purpose,
1547
+ algorithm=algorithm,
1548
+ public_key=public_key,
1549
+ private_key=private_key,
1550
+ key=key,
1551
+ name=name,
1552
+ folder=folder,
1553
+ metadata=metadata,
1554
+ tags=tags,
1555
+ rotation_frequency=rotation_frequency,
1556
+ rotation_state=rotation_state,
1557
+ disabled_at=disabled_at,
1558
+ exportable=exportable,
1559
+ ),
1560
+ )
1561
+
1562
+ @overload
1563
+ def rotate_key(
1564
+ self,
1565
+ key_id: str,
1566
+ *,
1567
+ key_type: Literal[ItemType.ASYMMETRIC_KEY],
1568
+ rotation_state: RequestManualRotationState = RequestManualRotationState.DEACTIVATED,
1569
+ public_key: str | None = None,
1570
+ private_key: str | None = None,
1571
+ ) -> PangeaResponse[AsymmetricKey]:
1572
+ """
1573
+ Rotate key
1574
+
1575
+ Manually rotate an asymmetric key.
1576
+
1577
+ Args:
1578
+ key_id: The ID of the key.
1579
+ key_type: Key type.
1580
+ rotation_state: State to which the previous version should
1581
+ transition upon rotation.
1582
+ public_key: The public key (in PEM format).
1583
+ private_key: The private key (in PEM format).
1584
+
1585
+ Raises:
1586
+ PangeaAPIException: If an API Error happens.
1587
+
1588
+ Examples:
1589
+ response = vault.rotate_key("pvi_...", key_type=ItemType.ASYMMETRIC_KEY)
1590
+ """
1591
+
1592
+ @overload
1593
+ def rotate_key(
1594
+ self,
1595
+ key_id: str,
1596
+ *,
1597
+ key_type: Literal[ItemType.SYMMETRIC_KEY],
1598
+ rotation_state: RequestManualRotationState = RequestManualRotationState.DEACTIVATED,
1599
+ key: str | None = None,
1600
+ ) -> PangeaResponse[SymmetricKey]:
1601
+ """
1602
+ Rotate key
1603
+
1604
+ Manually rotate a symmetric key.
1605
+
1606
+ Args:
1607
+ key_id: The ID of the key.
1608
+ key_type: Key type.
1609
+ rotation_state: State to which the previous version should
1610
+ transition upon rotation.
1611
+ key: The key material.
1612
+
1613
+ Raises:
1614
+ PangeaAPIException: If an API Error happens.
1615
+
1616
+ Examples:
1617
+ response = vault.rotate_key("pvi_...", key_type=ItemType.SYMMETRIC_KEY)
1618
+ """
1619
+
1620
+ def rotate_key(
1621
+ self,
1622
+ key_id: str,
1623
+ *,
1624
+ key_type: Literal[ItemType.ASYMMETRIC_KEY, ItemType.SYMMETRIC_KEY],
1625
+ rotation_state: RequestManualRotationState = RequestManualRotationState.DEACTIVATED,
1626
+ public_key: str | None = None,
1627
+ private_key: str | None = None,
1628
+ key: str | None = None,
1629
+ ) -> PangeaResponse[Any]:
1630
+ """
1631
+ Rotate key
1632
+
1633
+ Manually rotate an asymmetric or symmetric key.
1634
+
1635
+ Args:
1636
+ key_id: The ID of the key.
1637
+ key_type: Key type.
1638
+ rotation_state: State to which the previous version should
1639
+ transition upon rotation.
1640
+ public_key: The public key (in PEM format).
1641
+ private_key: The private key (in PEM format).
1642
+ key: The key material.
1643
+
1644
+ Raises:
1645
+ PangeaAPIException: If an API Error happens.
1646
+
1647
+ Examples:
1648
+ response = vault.rotate_key("pvi_...", key_type=ItemType.SYMMETRIC_KEY)
1649
+ """
1650
+
1651
+ return self.request.post(
1652
+ "v2/key/rotate",
1653
+ AsymmetricKey if key_type == ItemType.ASYMMETRIC_KEY else SymmetricKey,
1654
+ data=KeyRotateRequest(
1655
+ id=key_id,
1656
+ public_key=public_key,
1657
+ private_key=private_key,
1658
+ key=key,
1659
+ rotation_state=rotation_state,
1660
+ ),
1661
+ )
1662
+
1663
+ def encrypt(
1664
+ self, item_id: str, plain_text: str, *, version: int | None = None, additional_data: str | None = None
1665
+ ) -> PangeaResponse[EncryptResult]:
1666
+ """
1667
+ Encrypt
1668
+
1669
+ Encrypt a message using a key.
1670
+
1671
+ OperationId: vault_post_v2_key_encrypt
1672
+
1673
+ Args:
1674
+ item_id: The item ID.
1675
+ plain_text: A message to be encrypted (in base64).
1676
+ version: The item version.
1677
+ additional_data: User provided authentication data.
1678
+
1679
+ Returns:
1680
+ A PangeaResponse where the encrypted message in base64 is returned
1681
+ in the response.result field. Available response fields can be found
1682
+ in our [API documentation](https://pangea.cloud/docs/api/vault#encrypt).
1683
+
1684
+ Raises:
1685
+ PangeaAPIException: If an API Error happens
1686
+
1687
+ Examples:
1688
+ response = vault.encrypt(
1689
+ id="pvi_p6g5i3gtbvqvc3u6zugab6qs6r63tqf5",
1690
+ plain_text="lJkk0gCLux+Q+rPNqLPEYw==",
1691
+ version=1,
1692
+ )
1693
+ """
1694
+ return self.request.post(
1695
+ "v2/encrypt",
1696
+ EncryptResult,
1697
+ data=EncryptRequest(id=item_id, plain_text=plain_text, version=version, additional_data=additional_data),
1698
+ )
1699
+
1700
+ def decrypt(
1701
+ self, item_id: str, cipher_text: str, *, version: int | None = None, additional_data: str | None = None
1702
+ ) -> PangeaResponse[DecryptResult]:
1703
+ """
1704
+ Decrypt
1705
+
1706
+ Decrypt a message using a key.
1707
+
1708
+ OperationId: vault_post_v2_key_decrypt
985
1709
 
986
1710
  Args:
987
- id (str): The item ID
988
- message (str): The message to be signed, in base64
989
- version (int, optional): The item version
1711
+ item_id: The item ID.
1712
+ cipher_text: A message encrypted by Vault (in base64).
1713
+ version: The item version.
1714
+ additional_data: User provided authentication data.
1715
+
1716
+ Returns:
1717
+ A PangeaResponse where the decrypted message in base64 is returned
1718
+ in the response.result field. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#decrypt).
990
1719
 
991
1720
  Raises:
992
1721
  PangeaAPIException: If an API Error happens
993
1722
 
1723
+ Examples:
1724
+ response = vault.decrypt(
1725
+ id="pvi_p6g5i3gtbvqvc3u6zugab6qs6r63tqf5",
1726
+ cipher_text="lJkk0gCLux+Q+rPNqLPEYw==",
1727
+ version=1,
1728
+ )
1729
+ """
1730
+ return self.request.post(
1731
+ "v2/decrypt",
1732
+ DecryptResult,
1733
+ data=DecryptRequest(id=item_id, cipher_text=cipher_text, version=version, additional_data=additional_data),
1734
+ )
1735
+
1736
+ def sign(self, item_id: str, message: str, *, version: int | None = None) -> PangeaResponse[SignResult]:
1737
+ """
1738
+ Sign
1739
+
1740
+ Sign a message using a key
1741
+
1742
+ OperationId: vault_post_v2_sign
1743
+
1744
+ Args:
1745
+ id: The item ID.
1746
+ message: The message to be signed, in base64.
1747
+ version: The item version.
1748
+
994
1749
  Returns:
995
- A PangeaResponse where the signature of the message in base64
996
- is returned in the response.result field.
997
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#sign).
1750
+ A PangeaResponse where the signature of the message in base64 is
1751
+ returned in the response.result field. Available response fields can
1752
+ be found in our [API documentation](https://pangea.cloud/docs/api/vault#sign).
1753
+
1754
+ Raises:
1755
+ PangeaAPIException: If an API Error happens
998
1756
 
999
1757
  Examples:
1000
1758
  response = vault.sign(
@@ -1003,25 +1761,23 @@ class Vault(ServiceBase):
1003
1761
  version=1,
1004
1762
  )
1005
1763
  """
1006
- input = SignRequest(id=id, message=message, version=version)
1007
- return self.request.post("v1/key/sign", SignResult, data=input.dict(exclude_none=True))
1764
+ return self.request.post("v2/sign", SignResult, data=SignRequest(id=item_id, message=message, version=version))
1008
1765
 
1009
- # Verify
1010
1766
  def verify(
1011
- self, id: str, message: str, signature: str, version: Optional[int] = None
1767
+ self, item_id: str, message: str, signature: str, *, version: int | None = None
1012
1768
  ) -> PangeaResponse[VerifyResult]:
1013
1769
  """
1014
1770
  Verify
1015
1771
 
1016
- Verify a signature using a key
1772
+ Verify a signature using a key.
1017
1773
 
1018
- OperationId: vault_post_v1_key_verify
1774
+ OperationId: vault_post_v2_key_verify
1019
1775
 
1020
1776
  Args:
1021
- id (str): The item ID
1022
- message (str): A message to be verified (in base64)
1023
- signature (str): The message signature (in base64)
1024
- version (int, optional): The item version
1777
+ id: The item ID.
1778
+ message: A message to be verified (in base64).
1779
+ signature: The message signature (in base64).
1780
+ version: The item version.
1025
1781
 
1026
1782
  Raises:
1027
1783
  PangeaAPIException: If an API Error happens
@@ -1039,24 +1795,27 @@ class Vault(ServiceBase):
1039
1795
  version=1,
1040
1796
  )
1041
1797
  """
1042
- input = VerifyRequest(
1043
- id=id,
1044
- message=message,
1045
- signature=signature,
1046
- version=version,
1798
+ return self.request.post(
1799
+ "v2/verify",
1800
+ VerifyResult,
1801
+ data=VerifyRequest(
1802
+ id=item_id,
1803
+ message=message,
1804
+ signature=signature,
1805
+ version=version,
1806
+ ),
1047
1807
  )
1048
- return self.request.post("v1/key/verify", VerifyResult, data=input.dict(exclude_none=True))
1049
1808
 
1050
1809
  def jwt_verify(self, jws: str) -> PangeaResponse[JWTVerifyResult]:
1051
1810
  """
1052
1811
  JWT Verify
1053
1812
 
1054
- Verify the signature of a JSON Web Token (JWT)
1813
+ Verify the signature of a JSON Web Token (JWT).
1055
1814
 
1056
- OperationId: vault_post_v1_key_verify_jwt
1815
+ OperationId: vault_post_v2_key_verify_jwt
1057
1816
 
1058
1817
  Args:
1059
- jws (str): The signed JSON Web Token (JWS)
1818
+ jws: The signed JSON Web Token (JWS).
1060
1819
 
1061
1820
  Raises:
1062
1821
  PangeaAPIException: If an API Error happens
@@ -1067,32 +1826,29 @@ class Vault(ServiceBase):
1067
1826
  Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#verify-jwt).
1068
1827
 
1069
1828
  Examples:
1070
- response = vault.jwt_verify(
1071
- jws="ewogICJhbGciO...",
1072
- )
1829
+ response = vault.jwt_verify(jws="ewogICJhbGciO...")
1073
1830
  """
1074
- input = JWTVerifyRequest(jws=jws)
1075
- return self.request.post("v1/key/verify/jwt", JWTVerifyResult, data=input.dict(exclude_none=True))
1831
+ return self.request.post("v2/jwt/verify", JWTVerifyResult, data=JWTVerifyRequest(jws=jws))
1076
1832
 
1077
- def jwt_sign(self, id: str, payload: str) -> PangeaResponse[JWTSignResult]:
1833
+ def jwt_sign(self, item_id: str, payload: str) -> PangeaResponse[JWTSignResult]:
1078
1834
  """
1079
1835
  JWT Sign
1080
1836
 
1081
- Sign a JSON Web Token (JWT) using a key
1837
+ Sign a JSON Web Token (JWT) using a key.
1082
1838
 
1083
- OperationId: vault_post_v1_key_sign_jwt
1839
+ OperationId: vault_post_v2_jwt_sign
1084
1840
 
1085
1841
  Args:
1086
- id (str): The item ID
1087
- payload (str): The JWT payload (in JSON)
1842
+ id: The item ID.
1843
+ payload: The JWT payload (in JSON).
1088
1844
 
1089
1845
  Raises:
1090
1846
  PangeaAPIException: If an API Error happens
1091
1847
 
1092
1848
  Returns:
1093
- A PangeaResponse where the signed JSON Web Token (JWS)
1094
- is returned in the response.result field.
1095
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#sign-a-jwt).
1849
+ A PangeaResponse where the signed JSON Web Token (JWS) is returned
1850
+ in the response.result field. Available response fields can be found
1851
+ in our [API documentation](https://pangea.cloud/docs/api/vault#sign-a-jwt).
1096
1852
 
1097
1853
  Examples:
1098
1854
  response = vault.jwt_sign(
@@ -1100,73 +1856,64 @@ class Vault(ServiceBase):
1100
1856
  payload="{\\"sub\\": \\"1234567890\\",\\"name\\": \\"John Doe\\",\\"admin\\": true}"
1101
1857
  )
1102
1858
  """
1103
- input = JWTSignRequest(id=id, payload=payload)
1104
- return self.request.post("v1/key/sign/jwt", JWTSignResult, data=input.dict(exclude_none=True))
1859
+ return self.request.post("v2/jwt/sign", JWTSignResult, data=JWTSignRequest(id=item_id, payload=payload))
1105
1860
 
1106
- # Get endpoint
1107
- def jwk_get(self, id: str, version: Optional[str] = None) -> PangeaResponse[JWKGetResult]:
1861
+ def jwk_get(self, item_id: str, *, version: str | None = None) -> PangeaResponse[JWKGetResult]:
1108
1862
  """
1109
1863
  JWT Retrieve
1110
1864
 
1111
- Retrieve a key in JWK format
1865
+ Retrieve a key in JWK format.
1112
1866
 
1113
- OperationId: vault_post_v1_get_jwk
1867
+ OperationId: vault_post_v2_jwk_get
1114
1868
 
1115
1869
  Args:
1116
- id (str): The item ID
1117
- version (str, optional): The key version(s).
1118
- - `all` for all versions
1119
- - `num` for a specific version
1120
- - `-num` for the `num` latest versions
1870
+ id: The item ID
1871
+ version: The key version(s).
1872
+ - `all` for all versions
1873
+ - `num` for a specific version
1874
+ - `-num` for the `num` latest versions
1121
1875
  Raises:
1122
1876
  PangeaAPIException: If an API Error happens
1123
1877
 
1124
1878
  Returns:
1125
- A PangeaResponse where the JSON Web Key Set (JWKS) object
1126
- is returned in the response.result field.
1127
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#retrieve-jwk).
1879
+ A PangeaResponse where the JSON Web Key Set (JWKS) object is
1880
+ returned in the response.result field. Available response fields can
1881
+ be found in our [API documentation](https://pangea.cloud/docs/api/vault#retrieve-jwk).
1128
1882
 
1129
1883
  Examples:
1130
- response = vault.jwk_get(
1131
- id="pvi_p6g5i3gtbvqvc3u6zugab6qs6r63tqf5",
1132
- )
1884
+ response = vault.jwk_get("pvi_p6g5i3gtbvqvc3u6zugab6qs6r63tqf5")
1133
1885
  """
1134
- input = JWKGetRequest(id=id, version=version)
1135
- return self.request.post("v1/get/jwk", JWKGetResult, data=input.dict(exclude_none=True))
1886
+ return self.request.post("v2/jwk/get", JWKGetResult, data=JWKGetRequest(id=item_id, version=version))
1136
1887
 
1137
- # State change
1138
1888
  def state_change(
1139
1889
  self,
1140
- id: str,
1890
+ item_id: str,
1141
1891
  state: ItemVersionState,
1142
- version: Optional[int] = None,
1143
- destroy_period: Optional[str] = None,
1144
- ) -> PangeaResponse[StateChangeResult]:
1892
+ *,
1893
+ version: int | None = None,
1894
+ destroy_period: str | None = None,
1895
+ ) -> PangeaResponse[VaultItem]:
1145
1896
  """
1146
1897
  State change
1147
1898
 
1148
- Change the state of a specific version of a secret or key
1899
+ Change the state of a specific version of a secret or key.
1149
1900
 
1150
- OperationId: vault_post_v1_state_change
1901
+ OperationId: vault_post_v2_state_change
1151
1902
 
1152
1903
  Args:
1153
- id (str): The item ID
1154
- state (ItemVersionState): The new state of the item version. Supported options:
1155
- - `active`
1156
- - `deactivated`
1157
- - `suspended`
1158
- - `compromised`
1159
- - `destroyed`
1160
- version (int, optional): the item version
1161
- destroy_period (str, optional): Period of time for the destruction of a compromised key.
1162
- Only valid if state=`compromised`
1163
- Raises:
1164
- PangeaAPIException: If an API Error happens
1904
+ item_id: The item ID.
1905
+ state: The new state of the item version.
1906
+ version: The item version.
1907
+ destroy_period: Period of time for the destruction of a compromised
1908
+ key. Only valid if state=`compromised`.
1165
1909
 
1166
1910
  Returns:
1167
- A PangeaResponse where the state change object
1168
- is returned in the response.result field.
1169
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#change-state).
1911
+ A PangeaResponse where the state change object is returned in the
1912
+ response.result field. Available response fields can be found in our
1913
+ [API documentation](https://pangea.cloud/docs/api/vault#change-state).
1914
+
1915
+ Raises:
1916
+ PangeaAPIException: If an API Error happens
1170
1917
 
1171
1918
  Examples:
1172
1919
  response = vault.state_change(
@@ -1174,77 +1921,101 @@ class Vault(ServiceBase):
1174
1921
  state=ItemVersionState.DEACTIVATED,
1175
1922
  )
1176
1923
  """
1177
- input = StateChangeRequest(id=id, state=state, version=version, destroy_period=destroy_period)
1178
- return self.request.post("v1/state/change", StateChangeResult, data=input.dict(exclude_none=True))
1924
+ response = self.request.post(
1925
+ "v2/state/change",
1926
+ PangeaResponseResult,
1927
+ data=StateChangeRequest(id=item_id, state=state, version=version, destroy_period=destroy_period),
1928
+ )
1929
+ response.result = vault_item_adapter.validate_python(response.json["result"])
1930
+ return cast(PangeaResponse[VaultItem], response)
1179
1931
 
1180
- # Folder create
1181
1932
  def folder_create(
1182
1933
  self,
1183
1934
  name: str,
1184
1935
  folder: str,
1185
- metadata: Optional[Metadata] = None,
1186
- tags: Optional[Tags] = None,
1936
+ *,
1937
+ metadata: Metadata | None = None,
1938
+ tags: Tags | None = None,
1939
+ rotation_frequency: str | None = None,
1940
+ rotation_state: RequestRotationState = RequestRotationState.INHERITED,
1941
+ rotation_grace_period: str | None = None,
1942
+ disabled_at: datetime.datetime | None = None,
1187
1943
  ) -> PangeaResponse[FolderCreateResult]:
1188
1944
  """
1189
1945
  Create
1190
1946
 
1191
- Creates a folder
1947
+ Creates a folder.
1192
1948
 
1193
- OperationId: vault_post_v1_folder_create
1949
+ OperationId: vault_post_v2_folder_create
1194
1950
 
1195
1951
  Args:
1196
- name (str): The name of this folder
1197
- folder (str): The parent folder where this folder is stored
1198
- metadata (Metadata, optional): User-provided metadata
1199
- tags (Tags, optional): A list of user-defined tags
1952
+ name: The name of this folder.
1953
+ folder: The parent folder where this folder is stored.
1954
+ metadata: User-provided metadata.
1955
+ tags: A list of user-defined tags.
1956
+ rotation_frequency: Period of time between item rotations.
1957
+ rotation_state: State to which the previous version should
1958
+ transition upon rotation.
1959
+ rotation_grace_period: Grace period for the previous version.
1960
+ disabled_at: Timestamp indicating when the item will be disabled.
1961
+
1962
+ Returns: The created folder object.
1963
+
1200
1964
  Raises:
1201
1965
  PangeaAPIException: If an API Error happens
1202
1966
 
1203
- Returns:
1204
- A PangeaResponse where the state change object
1205
- is returned in the response.result field.
1206
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#create).
1207
-
1208
1967
  Examples:
1209
1968
  response = vault.folder_create(
1210
1969
  name="folder_name",
1211
1970
  folder="parent/folder/name",
1212
1971
  )
1213
1972
  """
1214
- input = FolderCreateRequest(name=name, folder=folder, metadata=metadata, tags=tags)
1215
- return self.request.post("v1/folder/create", FolderCreateResult, data=input.dict(exclude_none=True))
1973
+ return self.request.post(
1974
+ "v2/folder/create",
1975
+ FolderCreateResult,
1976
+ data=FolderCreateRequest(
1977
+ name=name,
1978
+ folder=folder,
1979
+ metadata=metadata,
1980
+ tags=tags,
1981
+ rotation_frequency=rotation_frequency,
1982
+ rotation_state=rotation_state,
1983
+ rotation_grace_period=rotation_grace_period,
1984
+ disabled_at=disabled_at,
1985
+ ),
1986
+ )
1216
1987
 
1217
- # Encrypt structured
1218
1988
  def encrypt_structured(
1219
1989
  self,
1220
- id: str,
1990
+ key_id: str,
1221
1991
  structured_data: TDict,
1222
- filter: str,
1223
- version: Optional[int] = None,
1224
- additional_data: Optional[str] = None,
1992
+ filter_expr: str,
1993
+ *,
1994
+ version: int | None = None,
1995
+ additional_data: str | None = None,
1225
1996
  ) -> PangeaResponse[EncryptStructuredResult[TDict]]:
1226
1997
  """
1227
1998
  Encrypt structured
1228
1999
 
1229
2000
  Encrypt parts of a JSON object.
1230
2001
 
1231
- OperationId: vault_post_v1_key_encrypt_structured
2002
+ OperationId: vault_post_v2_encrypt_structured
1232
2003
 
1233
2004
  Args:
1234
- id (str): The item ID.
1235
- structured_data (dict): Structured data for applying bulk operations.
1236
- filter (str): A filter expression for applying bulk operations to the data field.
1237
- version (int, optional): The item version. Defaults to the current version.
1238
- additional_data (str, optional): User provided authentication data.
1239
-
1240
- Raises:
1241
- PangeaAPIException: If an API error happens.
2005
+ key_id: The ID of the key to use.
2006
+ structured_data: Structured data for applying bulk operations.
2007
+ filter_expr: A filter expression.
2008
+ version: The item version. Defaults to the current version.
2009
+ additional_data: User provided authentication data.
1242
2010
 
1243
2011
  Returns:
1244
2012
  A `PangeaResponse` where the encrypted object is returned in the
1245
2013
  `response.result` field. Available response fields can be found in
1246
2014
  our [API documentation](https://pangea.cloud/docs/api/vault#encrypt-structured).
1247
2015
 
2016
+ Raises:
2017
+ PangeaAPIException: If an API error happens.
2018
+
1248
2019
  Examples:
1249
2020
  data = {"field1": [1, 2, "true", "false"], "field2": "data2"}
1250
2021
  response = vault.encrypt_structured(
@@ -1254,37 +2025,41 @@ class Vault(ServiceBase):
1254
2025
  )
1255
2026
  """
1256
2027
 
1257
- input: EncryptStructuredRequest[TDict] = EncryptStructuredRequest(
1258
- id=id, structured_data=structured_data, filter=filter, version=version, additional_data=additional_data
2028
+ data: EncryptStructuredRequest[TDict] = EncryptStructuredRequest(
2029
+ id=key_id,
2030
+ structured_data=structured_data,
2031
+ filter=filter_expr,
2032
+ version=version,
2033
+ additional_data=additional_data,
1259
2034
  )
1260
2035
  return self.request.post(
1261
- "v1/key/encrypt/structured",
2036
+ "v2/encrypt_structured",
1262
2037
  EncryptStructuredResult,
1263
- data=input.dict(exclude_none=True),
2038
+ data=data.model_dump(exclude_none=True),
1264
2039
  )
1265
2040
 
1266
- # Decrypt structured
1267
2041
  def decrypt_structured(
1268
2042
  self,
1269
- id: str,
2043
+ key_id: str,
1270
2044
  structured_data: TDict,
1271
- filter: str,
1272
- version: Optional[int] = None,
1273
- additional_data: Optional[str] = None,
2045
+ filter_expr: str,
2046
+ *,
2047
+ version: int | None = None,
2048
+ additional_data: str | None = None,
1274
2049
  ) -> PangeaResponse[EncryptStructuredResult[TDict]]:
1275
2050
  """
1276
2051
  Decrypt structured
1277
2052
 
1278
2053
  Decrypt parts of a JSON object.
1279
2054
 
1280
- OperationId: vault_post_v1_key_decrypt_structured
2055
+ OperationId: vault_post_v2_decrypt_structured
1281
2056
 
1282
2057
  Args:
1283
- id (str): The item ID.
1284
- structured_data (dict): Structured data to decrypt.
1285
- filter (str): A filter expression for applying bulk operations to the data field.
1286
- version (int, optional): The item version. Defaults to the current version.
1287
- additional_data (str, optional): User provided authentication data.
2058
+ id: The ID of the key to use.
2059
+ structured_data: Structured data for applying bulk operations.
2060
+ filter: A filter expression.
2061
+ version: The item version. Defaults to the current version.
2062
+ additional_data: User provided authentication data.
1288
2063
 
1289
2064
  Raises:
1290
2065
  PangeaAPIException: If an API error happens.
@@ -1303,11 +2078,160 @@ class Vault(ServiceBase):
1303
2078
  )
1304
2079
  """
1305
2080
 
1306
- input: EncryptStructuredRequest[TDict] = EncryptStructuredRequest(
1307
- id=id, structured_data=structured_data, filter=filter, version=version, additional_data=additional_data
2081
+ data: EncryptStructuredRequest[TDict] = EncryptStructuredRequest(
2082
+ id=key_id,
2083
+ structured_data=structured_data,
2084
+ filter=filter_expr,
2085
+ version=version,
2086
+ additional_data=additional_data,
1308
2087
  )
1309
2088
  return self.request.post(
1310
- "v1/key/decrypt/structured",
2089
+ "v2/decrypt_structured",
1311
2090
  EncryptStructuredResult,
1312
- data=input.dict(exclude_none=True),
2091
+ data=data.model_dump(exclude_none=True),
2092
+ )
2093
+
2094
+ def encrypt_transform(
2095
+ self,
2096
+ item_id: str,
2097
+ plain_text: str,
2098
+ alphabet: TransformAlphabet,
2099
+ *,
2100
+ tweak: str | None = None,
2101
+ version: int | None = None,
2102
+ ) -> PangeaResponse[EncryptTransformResult]:
2103
+ """
2104
+ Encrypt transform
2105
+
2106
+ Encrypt using a format-preserving algorithm (FPE).
2107
+
2108
+ OperationId: vault_post_v2_encrypt_transform
2109
+
2110
+ Args:
2111
+ item_id: The item ID.
2112
+ plain_text: A message to be encrypted.
2113
+ alphabet: Set of characters to use for format-preserving encryption (FPE).
2114
+ tweak: User provided tweak string. If not provided, a random string
2115
+ will be generated and returned.
2116
+ version: The item version. Defaults to the current version.
2117
+
2118
+ Raises:
2119
+ PangeaAPIException: If an API error happens.
2120
+
2121
+ Returns:
2122
+ A `PangeaResponse` containing the encrypted message.
2123
+
2124
+ Examples:
2125
+ vault.encrypt_transform(
2126
+ id="pvi_[...]",
2127
+ plain_text="message to encrypt",
2128
+ alphabet=TransformAlphabet.ALPHANUMERIC,
2129
+ tweak="MTIzMTIzMT==",
2130
+ )
2131
+ """
2132
+
2133
+ return self.request.post(
2134
+ "v2/encrypt_transform",
2135
+ EncryptTransformResult,
2136
+ data=EncryptTransformRequest(
2137
+ id=item_id,
2138
+ plain_text=plain_text,
2139
+ tweak=tweak,
2140
+ alphabet=alphabet,
2141
+ version=version,
2142
+ ),
2143
+ )
2144
+
2145
+ def decrypt_transform(
2146
+ self, item_id: str, cipher_text: str, tweak: str, alphabet: TransformAlphabet, *, version: int | None = None
2147
+ ) -> PangeaResponse[DecryptTransformResult]:
2148
+ """
2149
+ Decrypt transform
2150
+
2151
+ Decrypt using a format-preserving algorithm (FPE).
2152
+
2153
+ OperationId: vault_post_v2_decrypt_transform
2154
+
2155
+ Args:
2156
+ id: The item ID.
2157
+ cipher_text: A message encrypted by Vault.
2158
+ tweak: User provided tweak string.
2159
+ alphabet: Set of characters to use for format-preserving encryption (FPE).
2160
+ version: The item version. Defaults to the current version.
2161
+
2162
+ Returns:
2163
+ A `PangeaResponse` containing the decrypted message.
2164
+
2165
+ Raises:
2166
+ PangeaAPIException: If an API error happens.
2167
+
2168
+ Examples:
2169
+ vault.decrypt_transform(
2170
+ id="pvi_[...]",
2171
+ cipher_text="encrypted message",
2172
+ tweak="MTIzMTIzMT==",
2173
+ alphabet=TransformAlphabet.ALPHANUMERIC,
2174
+ )
2175
+ """
2176
+
2177
+ return self.request.post(
2178
+ "v2/decrypt_transform",
2179
+ DecryptTransformResult,
2180
+ data=DecryptTransformRequest(
2181
+ id=item_id, cipher_text=cipher_text, tweak=tweak, alphabet=alphabet, version=version
2182
+ ),
2183
+ )
2184
+
2185
+ def export(
2186
+ self,
2187
+ item_id: str,
2188
+ *,
2189
+ version: int | None = None,
2190
+ kem_password: str | None = None,
2191
+ asymmetric_public_key: str | None = None,
2192
+ asymmetric_algorithm: ExportEncryptionAlgorithm | None = None,
2193
+ ) -> PangeaResponse[ExportResult]:
2194
+ """
2195
+ Export
2196
+
2197
+ Export a symmetric or asymmetric key.
2198
+
2199
+ OperationId: vault_post_v2_export
2200
+
2201
+ Args:
2202
+ item_id: The item ID.
2203
+ version: The item version.
2204
+ kem_password: This is the password that will be used along with a
2205
+ salt to derive the symmetric key that is used to encrypt the
2206
+ exported key material.
2207
+ asymmetric_public_key: Public key in pem format used to encrypt
2208
+ exported key(s).
2209
+ asymmetric_algorithm: The algorithm of the public key.
2210
+
2211
+ Returns:
2212
+ A `PangeaResponse` where the exported key is returned in the
2213
+ `response.result` field. Available response fields can be found in
2214
+ our [API documentation](https://pangea.cloud/docs/api/vault#export).
2215
+
2216
+ Raises:
2217
+ PangeaAPIException: If an API error happens.
2218
+
2219
+ Examples:
2220
+ exp_encrypted_resp = self.vault.export(
2221
+ id=id,
2222
+ asymmetric_public_key=rsa_pub_key_pem,
2223
+ asymmetric_algorithm=ExportEncryptionAlgorithm.RSA4096_OAEP_SHA512,
2224
+ )
2225
+ """
2226
+
2227
+ return self.request.post(
2228
+ "v2/export",
2229
+ ExportResult,
2230
+ data=ExportRequest(
2231
+ id=item_id,
2232
+ version=version,
2233
+ kem_password=kem_password,
2234
+ asymmetric_public_key=asymmetric_public_key,
2235
+ asymmetric_algorithm=asymmetric_algorithm,
2236
+ ),
1313
2237
  )