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

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. pangea/__init__.py +2 -1
  2. pangea/asyncio/__init__.py +1 -0
  3. pangea/asyncio/file_uploader.py +39 -0
  4. pangea/asyncio/request.py +46 -23
  5. pangea/asyncio/services/__init__.py +2 -0
  6. pangea/asyncio/services/audit.py +46 -20
  7. pangea/asyncio/services/authn.py +123 -61
  8. pangea/asyncio/services/authz.py +57 -31
  9. pangea/asyncio/services/base.py +21 -2
  10. pangea/asyncio/services/embargo.py +2 -2
  11. pangea/asyncio/services/file_scan.py +24 -9
  12. pangea/asyncio/services/intel.py +104 -30
  13. pangea/asyncio/services/redact.py +52 -3
  14. pangea/asyncio/services/sanitize.py +217 -0
  15. pangea/asyncio/services/share.py +733 -0
  16. pangea/asyncio/services/vault.py +1709 -766
  17. pangea/crypto/rsa.py +135 -0
  18. pangea/deep_verify.py +7 -1
  19. pangea/dump_audit.py +9 -8
  20. pangea/file_uploader.py +35 -0
  21. pangea/request.py +70 -49
  22. pangea/response.py +36 -17
  23. pangea/services/__init__.py +2 -0
  24. pangea/services/audit/audit.py +57 -29
  25. pangea/services/audit/models.py +12 -3
  26. pangea/services/audit/signing.py +6 -5
  27. pangea/services/audit/util.py +3 -3
  28. pangea/services/authn/authn.py +120 -66
  29. pangea/services/authn/models.py +167 -11
  30. pangea/services/authz.py +53 -30
  31. pangea/services/base.py +16 -2
  32. pangea/services/embargo.py +2 -2
  33. pangea/services/file_scan.py +32 -15
  34. pangea/services/intel.py +155 -30
  35. pangea/services/redact.py +132 -3
  36. pangea/services/sanitize.py +388 -0
  37. pangea/services/share/file_format.py +170 -0
  38. pangea/services/share/share.py +1440 -0
  39. pangea/services/vault/models/asymmetric.py +120 -18
  40. pangea/services/vault/models/common.py +439 -141
  41. pangea/services/vault/models/keys.py +94 -0
  42. pangea/services/vault/models/secret.py +27 -3
  43. pangea/services/vault/models/symmetric.py +68 -22
  44. pangea/services/vault/vault.py +1690 -766
  45. pangea/tools.py +6 -7
  46. pangea/utils.py +94 -33
  47. pangea/verify_audit.py +270 -83
  48. {pangea_sdk-3.8.0.dist-info → pangea_sdk-5.3.0.dist-info}/METADATA +21 -29
  49. pangea_sdk-5.3.0.dist-info/RECORD +56 -0
  50. {pangea_sdk-3.8.0.dist-info → pangea_sdk-5.3.0.dist-info}/WHEEL +1 -1
  51. pangea_sdk-3.8.0.dist-info/RECORD +0 -46
@@ -2,38 +2,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
  )