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

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