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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. pangea/__init__.py +1 -1
  2. pangea/asyncio/file_uploader.py +1 -1
  3. pangea/asyncio/request.py +49 -31
  4. pangea/asyncio/services/__init__.py +2 -0
  5. pangea/asyncio/services/audit.py +192 -31
  6. pangea/asyncio/services/authn.py +187 -109
  7. pangea/asyncio/services/authz.py +285 -0
  8. pangea/asyncio/services/base.py +21 -2
  9. pangea/asyncio/services/embargo.py +2 -2
  10. pangea/asyncio/services/file_scan.py +24 -9
  11. pangea/asyncio/services/intel.py +108 -34
  12. pangea/asyncio/services/redact.py +72 -4
  13. pangea/asyncio/services/sanitize.py +217 -0
  14. pangea/asyncio/services/share.py +246 -73
  15. pangea/asyncio/services/vault.py +1710 -750
  16. pangea/crypto/rsa.py +135 -0
  17. pangea/deep_verify.py +7 -1
  18. pangea/dump_audit.py +9 -8
  19. pangea/request.py +83 -59
  20. pangea/response.py +49 -31
  21. pangea/services/__init__.py +2 -0
  22. pangea/services/audit/audit.py +205 -42
  23. pangea/services/audit/models.py +56 -8
  24. pangea/services/audit/signing.py +6 -5
  25. pangea/services/audit/util.py +3 -3
  26. pangea/services/authn/authn.py +140 -70
  27. pangea/services/authn/models.py +167 -11
  28. pangea/services/authz.py +400 -0
  29. pangea/services/base.py +39 -8
  30. pangea/services/embargo.py +2 -2
  31. pangea/services/file_scan.py +32 -15
  32. pangea/services/intel.py +157 -32
  33. pangea/services/redact.py +152 -4
  34. pangea/services/sanitize.py +388 -0
  35. pangea/services/share/share.py +683 -107
  36. pangea/services/vault/models/asymmetric.py +120 -18
  37. pangea/services/vault/models/common.py +439 -141
  38. pangea/services/vault/models/keys.py +94 -0
  39. pangea/services/vault/models/secret.py +27 -3
  40. pangea/services/vault/models/symmetric.py +68 -22
  41. pangea/services/vault/vault.py +1690 -749
  42. pangea/tools.py +6 -7
  43. pangea/utils.py +16 -27
  44. pangea/verify_audit.py +270 -83
  45. {pangea_sdk-3.8.0b1.dist-info → pangea_sdk-5.3.0.dist-info}/METADATA +43 -35
  46. pangea_sdk-5.3.0.dist-info/RECORD +56 -0
  47. {pangea_sdk-3.8.0b1.dist-info → pangea_sdk-5.3.0.dist-info}/WHEEL +1 -1
  48. pangea_sdk-3.8.0b1.dist-info/RECORD +0 -50
@@ -1,36 +1,50 @@
1
1
  # Copyright 2022 Pangea Cyber Corporation
2
2
  # Author: Pangea Cyber Corporation
3
- import datetime
4
- from typing import Dict, Optional, Union
3
+ from __future__ import annotations
4
+
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
5
10
 
6
11
  from pangea.asyncio.services.base import ServiceBaseAsync
7
- from pangea.response import PangeaResponse
12
+ from pangea.config import PangeaConfig
13
+ from pangea.response import PangeaResponse, PangeaResponseResult
8
14
  from pangea.services.vault.models.asymmetric import (
9
- AsymmetricGenerateRequest,
10
- AsymmetricGenerateResult,
11
- AsymmetricStoreRequest,
12
- AsymmetricStoreResult,
15
+ AsymmetricKey,
16
+ AsymmetricKeyAlgorithm,
17
+ AsymmetricKeyEncryptionAlgorithm,
18
+ AsymmetricKeyJwtAlgorithm,
19
+ AsymmetricKeyPkiAlgorithm,
20
+ AsymmetricKeyPurpose,
21
+ AsymmetricKeySigningAlgorithm,
13
22
  SignRequest,
14
23
  SignResult,
15
24
  VerifyRequest,
16
25
  VerifyResult,
17
26
  )
18
27
  from pangea.services.vault.models.common import (
19
- AsymmetricAlgorithm,
28
+ ClientSecret,
29
+ ClientSecretRotateRequest,
30
+ DecryptTransformRequest,
31
+ DecryptTransformResult,
20
32
  DeleteRequest,
21
33
  DeleteResult,
22
- EncodedPrivateKey,
23
- EncodedPublicKey,
24
- EncodedSymmetricKey,
25
34
  EncryptStructuredRequest,
26
35
  EncryptStructuredResult,
36
+ EncryptTransformRequest,
37
+ EncryptTransformResult,
38
+ ExportEncryptionAlgorithm,
39
+ ExportRequest,
40
+ ExportResult,
41
+ Folder,
27
42
  FolderCreateRequest,
28
43
  FolderCreateResult,
44
+ GetBulkRequest,
29
45
  GetRequest,
30
- GetResult,
31
46
  ItemOrder,
32
47
  ItemOrderBy,
33
- ItemState,
34
48
  ItemType,
35
49
  ItemVersionState,
36
50
  JWKGetRequest,
@@ -39,37 +53,53 @@ from pangea.services.vault.models.common import (
39
53
  JWTSignResult,
40
54
  JWTVerifyRequest,
41
55
  JWTVerifyResult,
42
- KeyPurpose,
43
- KeyRotateRequest,
44
- KeyRotateResult,
45
56
  ListRequest,
46
57
  ListResult,
47
58
  Metadata,
59
+ PangeaToken,
60
+ PangeaTokenRotateRequest,
61
+ RequestManualRotationState,
62
+ RequestRotationState,
63
+ RotationState,
64
+ Secret,
48
65
  StateChangeRequest,
49
- StateChangeResult,
50
- SymmetricAlgorithm,
51
66
  Tags,
52
67
  TDict,
68
+ TransformAlphabet,
53
69
  UpdateRequest,
54
70
  UpdateResult,
55
71
  )
56
- from pangea.services.vault.models.secret import (
57
- SecretRotateRequest,
58
- SecretRotateResult,
59
- SecretStoreRequest,
60
- SecretStoreResult,
61
- )
72
+ from pangea.services.vault.models.keys import CommonGenerateRequest, KeyRotateRequest, KeyStoreRequest
73
+ from pangea.services.vault.models.secret import SecretRotateRequest, SecretStoreRequest, SecretStoreResult
62
74
  from pangea.services.vault.models.symmetric import (
63
75
  DecryptRequest,
64
76
  DecryptResult,
65
77
  EncryptRequest,
66
78
  EncryptResult,
67
- SymmetricGenerateRequest,
68
- SymmetricGenerateResult,
69
- SymmetricStoreRequest,
70
- SymmetricStoreResult,
79
+ SymmetricKey,
80
+ SymmetricKeyAlgorithm,
81
+ SymmetricKeyEncryptionAlgorithm,
82
+ SymmetricKeyFpeAlgorithm,
83
+ SymmetricKeyJwtAlgorithm,
84
+ SymmetricKeyPurpose,
71
85
  )
72
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
+
73
103
 
74
104
  class VaultAsync(ServiceBaseAsync):
75
105
  """Vault service client.
@@ -84,140 +114,182 @@ class VaultAsync(ServiceBaseAsync):
84
114
  import os
85
115
 
86
116
  # Pangea SDK
117
+ from pangea.asyncio.services import VaultAsync
87
118
  from pangea.config import PangeaConfig
88
- from pangea.services.vault import Vault
89
119
 
90
120
  PANGEA_VAULT_TOKEN = os.getenv("PANGEA_VAULT_TOKEN")
91
121
  vault_config = PangeaConfig(domain="pangea.cloud")
92
122
 
93
123
  # Setup Pangea Vault service
94
- vault = Vault(token=PANGEA_VAULT_TOKEN, config=vault_config)
124
+ vault = VaultAsync(token=PANGEA_VAULT_TOKEN, config=vault_config)
95
125
  """
96
126
 
97
127
  service_name = "vault"
98
128
 
99
129
  def __init__(
100
130
  self,
101
- token,
102
- config=None,
103
- logger_name="pangea",
104
- ):
131
+ token: str,
132
+ config: PangeaConfig | None = None,
133
+ logger_name: str = "pangea",
134
+ ) -> None:
135
+ """
136
+ Vault client
137
+
138
+ Initializes a new Vault client.
139
+
140
+ Args:
141
+ token: Pangea API token.
142
+ config: Configuration.
143
+ logger_name: Logger name.
144
+
145
+ Examples:
146
+ config = PangeaConfig(domain="pangea_domain")
147
+ vault = VaultAsync(token="pangea_token", config=config)
148
+ """
105
149
  super().__init__(token, config, logger_name)
106
150
 
107
- # Delete endpoint
108
- async def delete(self, id: str) -> PangeaResponse[DeleteResult]:
151
+ async def delete(self, item_id: str, *, recursive: bool = False) -> PangeaResponse[DeleteResult]:
109
152
  """
110
153
  Delete
111
154
 
112
155
  Delete a secret or key
113
156
 
114
- OperationId: vault_post_v1_delete
157
+ OperationId: vault_post_v2_delete
115
158
 
116
159
  Args:
117
- id (str): The item ID
118
- Raises:
119
- 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.
120
163
 
121
164
  Returns:
122
165
  A PangeaResponse where the id of the deleted secret or key
123
166
  is returned in the response.result field.
124
167
  Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#delete).
125
168
 
169
+ Raises:
170
+ PangeaAPIException: If an API Error happens
171
+
126
172
  Examples:
127
- vault.delete(id="pvi_p6g5i3gtbvqvc3u6zugab6qs6r63tqf5")
173
+ await vault.delete(id="pvi_p6g5i3gtbvqvc3u6zugab6qs6r63tqf5")
128
174
  """
129
- input = DeleteRequest(
130
- id=id,
131
- )
132
- 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))
133
176
 
134
- # Get endpoint
135
177
  async def get(
136
178
  self,
137
- id: str,
138
- version: Optional[Union[str, int]] = None,
139
- version_state: Optional[ItemVersionState] = None,
140
- verbose: Optional[bool] = None,
141
- ) -> PangeaResponse[GetResult]:
179
+ item_id: str,
180
+ *,
181
+ version: Union[Literal["all"], int, None] = None,
182
+ ) -> PangeaResponse[VaultItem]:
142
183
  """
143
184
  Retrieve
144
185
 
145
- Retrieve a secret or key, and any associated information
186
+ Retrieve a secret, key or folder, and any associated information.
146
187
 
147
- OperationId: vault_post_v1_get
188
+ OperationId: vault_post_v2_get
148
189
 
149
190
  Args:
150
- id (str): The item ID
151
- version (str, int, optional): The key version(s).
152
- - `all` for all versions
153
- - `num` for a specific version
154
- - `-num` for the `num` latest versions
155
- version_state (ItemVersionState, optional): The state of the item version
156
- verbose (bool, optional): Return metadata and extra fields. Default is `False`.
157
- Raises:
158
- 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
159
196
 
160
197
  Returns:
161
198
  A PangeaResponse where the secret or key
162
199
  is returned in the response.result field.
163
200
  Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#retrieve).
164
201
 
202
+ Raises:
203
+ PangeaAPIException: If an API Error happens
204
+
165
205
  Examples:
166
- response = vault.get(
206
+ response = await vault.get(
167
207
  id="pvi_p6g5i3gtbvqvc3u6zugab6qs6r63tqf5",
168
208
  version=1,
169
- version_state=ItemVersionState.ACTIVE,
170
- verbose=True,
171
209
  )
172
210
  """
173
- input = GetRequest(
174
- id=id,
175
- version=version,
176
- verbose=verbose,
177
- 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),
178
247
  )
179
- return await self.request.post("v1/get", GetResult, data=input.dict(exclude_none=True))
180
248
 
181
- # List endpoint
182
249
  async def list(
183
250
  self,
184
- filter: Optional[Dict[str, str]] = None,
185
- last: Optional[str] = None,
251
+ *,
252
+ filter: Optional[Mapping[str, str]] = None,
253
+ size: int = 50,
186
254
  order: Optional[ItemOrder] = None,
187
- order_by: Optional[ItemOrderBy] = None,
188
- size: Optional[int] = None,
255
+ order_by: ItemOrderBy | None = None,
256
+ last: str | None = None,
189
257
  ) -> PangeaResponse[ListResult]:
190
258
  """
191
259
  List
192
260
 
193
- 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.
194
262
 
195
- OperationId: vault_post_v1_list
263
+ OperationId: vault_post_v2_list
196
264
 
197
265
  Args:
198
- filter (dict, optional): A set of filters to help you customize your search. Examples:
199
- - "folder": "/tmp"
200
- - "tags": "personal"
201
- - "name__contains": "xxx"
202
- - "created_at__gt": "2020-02-05T10:00:00Z"
203
-
204
- For metadata, use: "metadata_": "\<value\>"
205
- last (str, optional): Internal ID returned in the previous look up response. Used for pagination.
206
- order (ItemOrder, optional): Ordering direction: `asc` or `desc`
207
- 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`,
208
278
  `type`, `created_at`, `algorithm`, `purpose`, `expiration`, `last_rotated`, `next_rotation`,
209
279
  `name`, `folder`, `item_state`.
210
- size (int, optional): Maximum number of items in the response. Default is `50`.
211
- Raises:
212
- PangeaAPIException: If an API Error happens
280
+ last: Internal ID returned in the previous look up response. Used
281
+ for pagination.
213
282
 
214
283
  Returns:
215
284
  A PangeaResponse where a list of secrets or keys
216
285
  is returned in the response.result field.
217
286
  Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#list).
218
287
 
288
+ Raises:
289
+ PangeaAPIException: If an API Error happens
290
+
219
291
  Examples:
220
- response = vault.list(
292
+ response = await vault.list(
221
293
  filter={
222
294
  "folder": "/",
223
295
  "type": "asymmetric_key",
@@ -231,58 +303,55 @@ class VaultAsync(ServiceBaseAsync):
231
303
  size=20,
232
304
  )
233
305
  """
234
- input = ListRequest(filter=filter, last=last, order=order, order_by=order_by, size=size)
235
- 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
+ )
236
311
 
237
- # Update endpoint
238
312
  async def update(
239
313
  self,
240
- id: str,
241
- name: Optional[str] = None,
242
- folder: Optional[str] = None,
243
- metadata: Optional[Metadata] = None,
244
- tags: Optional[Tags] = None,
245
- rotation_frequency: Optional[str] = None,
246
- rotation_state: Optional[ItemVersionState] = None,
247
- rotation_grace_period: Optional[str] = None,
248
- expiration: Optional[datetime.datetime] = None,
249
- 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,
250
325
  ) -> PangeaResponse[UpdateResult]:
251
326
  """
252
327
  Update
253
328
 
254
- Update information associated with a secret or key.
329
+ Update information associated with a secret, key or folder.
255
330
 
256
- OperationId: vault_post_v1_update
331
+ OperationId: vault_post_v2_update
257
332
 
258
333
  Args:
259
- id (str): The item ID
260
- name (str, optional): The name of this item
261
- folder (string, optional): The folder where this item is stored
262
- metadata (dict, optional): User-provided metadata
263
- tags (list[str], optional): A list of user-defined tags
264
- rotation_frequency (str, optional): Period of time between item rotations
265
- rotation_state (ItemVersionState, optional): State to which the previous version should transition upon rotation.
266
- Supported options:
267
- - `deactivated`
268
- - `destroyed`
269
-
270
- Default is `deactivated`.
271
- rotation_grace_period (str, optional): Grace period for the previous version of the Pangea Token
272
- expiration (str, optional): Expiration timestamp
273
- item_state (ItemState, optional): The new state of the item. Supported options:
274
- - `enabled`
275
- - `disabled`
276
- Raises:
277
- 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.
278
344
 
279
345
  Returns:
280
- A PangeaResponse where the item ID
281
- is returned in the response.result field.
282
- 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
283
352
 
284
353
  Examples:
285
- response = vault.update(
354
+ response = await vault.update(
286
355
  id="pvi_p6g5i3gtbvqvc3u6zugab6qs6r63tqf5",
287
356
  name="my-very-secret-secret",
288
357
  folder="/personal",
@@ -296,703 +365,1422 @@ class VaultAsync(ServiceBaseAsync):
296
365
  ],
297
366
  rotation_frequency="10d",
298
367
  rotation_state=ItemVersionState.DEACTIVATED,
299
- rotation_grace_period="1d",
300
- expiration="2025-01-01T10:00:00Z",
301
- item_state=ItemState.DISABLED,
302
368
  )
303
369
  """
304
- input = UpdateRequest(
305
- id=id,
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
+ ),
411
+ )
412
+
413
+ async def store_secret(
414
+ self,
415
+ secret: str,
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]:
423
+ """
424
+ Store secret
425
+
426
+ Store a secret.
427
+
428
+ Args:
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.
435
+
436
+ Raises:
437
+ PangeaAPIException: If an API Error happens
438
+
439
+ Examples:
440
+ response = await vault.store_secret(secret="foobar")
441
+ """
442
+
443
+ return await self._secret_store(
444
+ item_type="secret",
445
+ result_class=Secret,
446
+ secret=secret,
306
447
  name=name,
307
448
  folder=folder,
308
449
  metadata=metadata,
309
450
  tags=tags,
310
- rotation_frequency=rotation_frequency,
311
- rotation_state=rotation_state,
312
- rotation_grace_period=rotation_grace_period,
313
- expiration=expiration,
314
- item_state=item_state,
451
+ disabled_at=disabled_at,
315
452
  )
316
- return await self.request.post("v1/update", UpdateResult, data=input.dict(exclude_none=True))
317
453
 
318
- async def secret_store(
454
+ async def store_pangea_token(
319
455
  self,
320
- secret: str,
321
- name: str,
322
- folder: Optional[str] = None,
323
- metadata: Optional[Metadata] = None,
324
- tags: Optional[Tags] = None,
325
- rotation_frequency: Optional[str] = None,
326
- rotation_state: Optional[ItemVersionState] = None,
327
- expiration: Optional[datetime.datetime] = None,
328
- ) -> 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]:
329
467
  """
330
- Secret store
331
-
332
- Import a secret
468
+ Store secret
333
469
 
334
- OperationId: vault_post_v1_secret_store 1
470
+ Store a Pangea token.
335
471
 
336
472
  Args:
337
- secret (str): The secret value
338
- name (str): The name of this item
339
- folder (str, optional): The folder where this item is stored
340
- metadata (dict, optional): User-provided metadata
341
- tags (list[str], optional): A list of user-defined tags
342
- rotation_frequency (str, optional): Period of time between item rotations
343
- rotation_state (ItemVersionState, optional): State to which the previous version should transition upon rotation.
344
- Supported options:
345
- - `deactivated`
346
- - `destroyed`
347
- 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.
348
479
 
349
480
  Raises:
350
481
  PangeaAPIException: If an API Error happens
351
482
 
352
- Returns:
353
- A PangeaResponse where the secret
354
- is returned in the response.result field.
355
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#import-a-secret).
356
-
357
483
  Examples:
358
- response = vault.secret_store(
359
- secret="12sdfgs4543qv@#%$casd",
360
- name="my-very-secret-secret",
361
- folder="/personal",
362
- metadata={
363
- "created_by": "John Doe",
364
- "used_in": "Google products"
365
- },
366
- tags=[
367
- "irs_2023",
368
- "personal"
369
- ],
370
- rotation_frequency="10d",
371
- rotation_state=ItemVersionState.DEACTIVATED,
372
- expiration="2025-01-01T10:00:00Z",
373
- )
484
+ response = await vault.store_pangea_token(token="foobar")
374
485
  """
375
- input = SecretStoreRequest(
376
- type=ItemType.SECRET,
377
- secret=secret,
486
+
487
+ return await self._secret_store(
488
+ item_type="pangea_token",
489
+ result_class=PangeaToken,
490
+ token=token,
378
491
  name=name,
379
492
  folder=folder,
380
493
  metadata=metadata,
381
494
  tags=tags,
495
+ disabled_at=disabled_at,
382
496
  rotation_frequency=rotation_frequency,
383
497
  rotation_state=rotation_state,
384
- expiration=expiration,
498
+ rotation_grace_period=rotation_grace_period,
385
499
  )
386
- return await self.request.post("v1/secret/store", SecretStoreResult, data=input.dict(exclude_none=True))
387
500
 
388
- async def pangea_token_store(
501
+ async def store_pangea_client_secret(
389
502
  self,
390
- pangea_token: str,
391
- name: str,
392
- folder: Optional[str] = None,
393
- metadata: Optional[Metadata] = None,
394
- tags: Optional[Tags] = None,
395
- rotation_frequency: Optional[str] = None,
396
- rotation_state: Optional[ItemVersionState] = None,
397
- expiration: Optional[datetime.datetime] = None,
398
- ) -> PangeaResponse[SecretStoreResult]:
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]:
399
516
  """
400
- Pangea token store
517
+ Store secret
401
518
 
402
- Import a secret
403
-
404
- OperationId: vault_post_v1_secret_store 2
519
+ Store a Pangea client secret.
405
520
 
406
521
  Args:
407
- pangea_token (str): The pangea token to store
408
- name (str): the name of this item
409
- folder (str, optional): The folder where this item is stored
410
- metadata (dict, optional): User-provided metadata
411
- tags (list[str], optional): A list of user-defined tags
412
- rotation_frequency (str, optional): Period of time between item rotations
413
- rotation_state (ItemVersionState, optional): State to which the previous version should
414
- transition upon rotation. Supported options:
415
- - `deactivated`
416
- - `destroyed`
417
- expiration (str, optional): Expiration timestamp
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.
418
535
 
419
536
  Raises:
420
537
  PangeaAPIException: If an API Error happens
421
538
 
422
- Returns:
423
- A PangeaResponse where the token
424
- is returned in the response.result field.
425
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#import-a-secret).
426
-
427
539
  Examples:
428
- response = vault.pangea_token_store(
429
- pangea_token="ptv_x6fdiizbon6j3bsdvnpmwxsz2aan7fqd",
430
- name="my-very-secret-secret",
431
- folder="/personal",
432
- metadata={
433
- "created_by": "John Doe",
434
- "used_in": "Google products"
435
- },
436
- tags=[
437
- "irs_2023",
438
- "personal"
439
- ],
440
- rotation_frequency="10d",
441
- rotation_state=ItemVersionState.DEACTIVATED,
442
- expiration="2025-01-01T10:00:00Z",
540
+ response = await vault.store_pangea_client_secret(
541
+ client_secret="foo",
542
+ client_id="bar",
543
+ client_secret_id="baz",
443
544
  )
444
545
  """
445
- input = SecretStoreRequest(
446
- type=ItemType.PANGEA_TOKEN,
447
- secret=pangea_token,
546
+
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,
448
553
  name=name,
449
554
  folder=folder,
450
555
  metadata=metadata,
451
556
  tags=tags,
557
+ disabled_at=disabled_at,
452
558
  rotation_frequency=rotation_frequency,
453
559
  rotation_state=rotation_state,
454
- expiration=expiration,
560
+ rotation_grace_period=rotation_grace_period,
561
+ )
562
+
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
572
+
573
+ Rotate a secret.
574
+
575
+ Args:
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.
580
+
581
+ Raises:
582
+ PangeaAPIException: If an API Error happens
583
+
584
+ Examples:
585
+ response = await vault.rotate_secret(item_id="foo", secret="bar")
586
+ """
587
+
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(
595
+ self,
596
+ item_id: str,
597
+ *,
598
+ rotation_grace_period: str | None = None,
599
+ rotation_state: RequestManualRotationState = RequestManualRotationState.DEACTIVATED,
600
+ ) -> PangeaResponse[PangeaToken]:
601
+ """
602
+ Rotate secret
603
+
604
+ Rotate a Pangea token.
605
+
606
+ Args:
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.
612
+
613
+ Raises:
614
+ PangeaAPIException: If an API Error happens.
615
+
616
+ Examples:
617
+ response = await vault.rotate_pangea_token(item_id="foo")
618
+ """
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
+ ),
455
626
  )
456
- return await self.request.post("v1/secret/store", SecretStoreResult, data=input.dict(exclude_none=True))
457
627
 
458
- # Rotate endpoint
459
- async def secret_rotate(
460
- self, id: str, secret: str, rotation_state: Optional[ItemVersionState] = None
461
- ) -> PangeaResponse[SecretRotateResult]:
628
+ async def rotate_client_secret(
629
+ self,
630
+ item_id: str,
631
+ *,
632
+ rotation_grace_period: str | None = None,
633
+ rotation_state: RequestManualRotationState = RequestManualRotationState.DEACTIVATED,
634
+ ) -> PangeaResponse[ClientSecret]:
635
+ """
636
+ Rotate secret
637
+
638
+ Rotate a client secret.
639
+
640
+ Args:
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.
646
+
647
+ Raises:
648
+ PangeaAPIException: If an API Error happens.
649
+
650
+ Examples:
651
+ response = await vault.rotate_client_secret(item_id="foo")
652
+ """
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
+ ),
660
+ )
661
+
662
+ @overload
663
+ async def generate_key(
664
+ self,
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]:
678
+ """
679
+ Generate key
680
+
681
+ Generate an asymmetric signing key.
682
+
683
+ Args:
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.
696
+
697
+ Raises:
698
+ PangeaAPIException: If an API Error happens.
699
+
700
+ Examples:
701
+ response = await vault.generate_key(
702
+ key_type=ItemType.ASYMMETRIC_KEY,
703
+ purpose=AsymmetricKeyPurpose.SIGNING,
704
+ algorithm=AsymmetricKeySigningAlgorithm.ED25519,
705
+ )
706
+ """
707
+
708
+ @overload
709
+ async def generate_key(
710
+ self,
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]:
724
+ """
725
+ Generate key
726
+
727
+ Generate an asymmetric encryption key.
728
+
729
+ Args:
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.
742
+
743
+ Raises:
744
+ PangeaAPIException: If an API Error happens.
745
+
746
+ Examples:
747
+ response = await vault.generate_key(
748
+ key_type=ItemType.ASYMMETRIC_KEY,
749
+ purpose=AsymmetricKeyPurpose.ENCRYPTION,
750
+ algorithm=AsymmetricKeyEncryptionAlgorithm.RSA_OAEP_2048_SHA1,
751
+ )
752
+ """
753
+
754
+ @overload
755
+ async def generate_key(
756
+ self,
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]:
770
+ """
771
+ Generate key
772
+
773
+ Generate an asymmetric JWT key.
774
+
775
+ Args:
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.
788
+
789
+ Raises:
790
+ PangeaAPIException: If an API Error happens.
791
+
792
+ Examples:
793
+ response = await vault.generate_key(
794
+ key_type=ItemType.ASYMMETRIC_KEY,
795
+ purpose=AsymmetricKeyPurpose.JWT,
796
+ algorithm=AsymmetricKeyJwtAlgorithm.ES512,
797
+ )
798
+ """
799
+
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]:
816
+ """
817
+ Generate key
818
+
819
+ Generate an asymmetric PKI key.
820
+
821
+ Args:
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.
834
+
835
+ Raises:
836
+ PangeaAPIException: If an API Error happens.
837
+
838
+ Examples:
839
+ response = await vault.generate_key(
840
+ key_type=ItemType.ASYMMETRIC_KEY,
841
+ purpose=AsymmetricKeyPurpose.PKI,
842
+ algorithm=AsymmetricKeyPkiAlgorithm.ED25519,
843
+ )
844
+ """
845
+
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]:
862
+ """
863
+ Generate key
864
+
865
+ Generate an asymmetric key.
866
+
867
+ Args:
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.
880
+
881
+ Raises:
882
+ PangeaAPIException: If an API Error happens.
883
+
884
+ Examples:
885
+ response = await vault.generate_key(
886
+ key_type=ItemType.ASYMMETRIC_KEY,
887
+ purpose=AsymmetricKeyPurpose.PKI,
888
+ algorithm=AsymmetricKeyPkiAlgorithm.ED25519,
889
+ )
890
+ """
891
+
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]:
908
+ """
909
+ Generate key
910
+
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
+ )
462
1237
  """
463
- Secret rotate
464
1238
 
465
- Rotate a secret
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
466
1259
 
467
- OperationId: vault_post_v1_secret_rotate 1
1260
+ Import an asymmetric JWT key.
468
1261
 
469
1262
  Args:
470
- id (str): The item ID
471
- secret (str): The secret value
472
- rotation_state (ItemVersionState, optional): State to which the previous version should transition upon rotation.
473
- Supported options:
474
- - `deactivated`
475
- - `suspended`
476
- - `destroyed`
477
-
478
- Default is `deactivated`.
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.
479
1277
 
480
1278
  Raises:
481
- PangeaAPIException: If an API Error happens
482
-
483
- Returns:
484
- A PangeaResponse where the secret
485
- is returned in the response.result field.
486
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#rotate-a-secret).
1279
+ PangeaAPIException: If an API Error happens.
487
1280
 
488
1281
  Examples:
489
- response = vault.secret_rotate(
490
- id="pvi_p6g5i3gtbvqvc3u6zugab6qs6r63tqf5",
491
- secret="12sdfgs4543qv@#%$casd",
492
- rotation_state=ItemVersionState.DEACTIVATED,
1282
+ response = await vault.store_key(
1283
+ key_type=ItemType.ASYMMETRIC_KEY,
1284
+ purpose=AsymmetricKeyPurpose.JWT,
1285
+ algorithm=AsymmetricKeyJwtAlgorithm.ES512,
493
1286
  )
494
1287
  """
495
- input = SecretRotateRequest(id=id, secret=secret, rotation_state=rotation_state)
496
- return await self.request.post("v1/secret/rotate", SecretRotateResult, data=input.dict(exclude_none=True))
497
1288
 
498
- # Rotate endpoint
499
- async def pangea_token_rotate(self, id: str) -> PangeaResponse[SecretRotateResult]:
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]:
500
1307
  """
501
- Token rotate
1308
+ Store key
502
1309
 
503
- Rotate a Pangea token
504
-
505
- OperationId: vault_post_v1_secret_rotate 2
1310
+ Import an asymmetric PKI key.
506
1311
 
507
1312
  Args:
508
- id (str): The item ID
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.
509
1327
 
510
1328
  Raises:
511
- PangeaAPIException: If an API Error happens
512
-
513
- Returns:
514
- A PangeaResponse where the token
515
- is returned in the response.result field.
516
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#rotate-a-secret).
1329
+ PangeaAPIException: If an API Error happens.
517
1330
 
518
1331
  Examples:
519
- response = vault.pangea_token_rotate(
520
- id="pvi_p6g5i3gtbvqvc3u6zugab6qs6r63tqf5",
1332
+ response = await vault.store_key(
1333
+ key_type=ItemType.ASYMMETRIC_KEY,
1334
+ purpose=AsymmetricKeyPurpose.PKI,
1335
+ algorithm=AsymmetricKeyPkiAlgorithm.ED25519,
521
1336
  )
522
1337
  """
523
- input = SecretRotateRequest(id=id) # type: ignore[call-arg]
524
- return await self.request.post("v1/secret/rotate", SecretRotateResult, data=input.dict(exclude_none=True))
525
1338
 
526
- async def symmetric_generate(
1339
+ @overload
1340
+ async def store_key(
527
1341
  self,
528
- algorithm: SymmetricAlgorithm,
529
- purpose: KeyPurpose,
530
- name: Optional[str] = None,
531
- folder: Optional[str] = None,
532
- metadata: Optional[Metadata] = None,
533
- tags: Optional[Tags] = None,
534
- rotation_frequency: Optional[str] = None,
535
- rotation_state: Optional[ItemVersionState] = None,
536
- expiration: Optional[datetime.datetime] = None,
537
- ) -> PangeaResponse[SymmetricGenerateResult]:
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]:
538
1356
  """
539
- Symmetric generate
540
-
541
- Generate a symmetric key
1357
+ Store key
542
1358
 
543
- OperationId: vault_post_v1_key_generate 1
1359
+ Import a symmetric encryption key.
544
1360
 
545
1361
  Args:
546
- algorithm (SymmetricAlgorithm): The algorithm of the key
547
- purpose (KeyPurpose): The purpose of this key
548
- name (str): The name of this item
549
- folder (str, optional): The folder where this item is stored
550
- metadata (dict, optional): User-provided metadata
551
- tags (list[str], optional): A list of user-defined tags
552
- rotation_frequency (str, optional): Period of time between item rotations, or `never` to disallow rotation
553
- rotation_state (ItemVersionState, optional): State to which the previous version should transition upon rotation.
554
- Supported options:
555
- - `deactivated`
556
- - `destroyed`
557
- expiration (str, optional): Expiration timestamp
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.
558
1375
 
559
1376
  Raises:
560
- PangeaAPIException: If an API Error happens
561
-
562
- Returns:
563
- A PangeaResponse where the ID of the key
564
- is returned in the response.result field.
565
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#generate).
1377
+ PangeaAPIException: If an API Error happens.
566
1378
 
567
1379
  Examples:
568
- response = vault.symmetric_generate(
569
- algorithm=SymmetricAlgorithm.AES,
570
- purpose=KeyPurpose.ENCRYPTION,
571
- name="my-very-secret-secret",
572
- folder="/personal",
573
- metadata={
574
- "created_by": "John Doe",
575
- "used_in": "Google products"
576
- },
577
- tags=[
578
- "irs_2023",
579
- "personal"
580
- ],
581
- rotation_frequency="10d",
582
- rotation_state=ItemVersionState.DEACTIVATED,
583
- expiration="2025-01-01T10:00:00Z",
1380
+ response = await vault.store_key(
1381
+ key_type=ItemType.SYMMETRIC_KEY,
1382
+ purpose=SymmetricKeyPurpose.ENCRYPTION,
1383
+ algorithm=SymmetricKeyEncryptionAlgorithm.AES_CFB_128,
584
1384
  )
585
1385
  """
586
- input = SymmetricGenerateRequest(
587
- type=ItemType.SYMMETRIC_KEY,
588
- algorithm=algorithm,
589
- purpose=purpose,
590
- name=name, # type: ignore[arg-type]
591
- folder=folder,
592
- metadata=metadata,
593
- tags=tags,
594
- rotation_frequency=rotation_frequency,
595
- rotation_state=rotation_state,
596
- expiration=expiration,
597
- )
598
- return await self.request.post("v1/key/generate", SymmetricGenerateResult, data=input.dict(exclude_none=True))
599
1386
 
600
- async def asymmetric_generate(
1387
+ @overload
1388
+ async def store_key(
601
1389
  self,
602
- algorithm: AsymmetricAlgorithm,
603
- purpose: KeyPurpose,
604
- name: Optional[str] = None,
605
- folder: Optional[str] = None,
606
- metadata: Optional[Metadata] = None,
607
- tags: Optional[Tags] = None,
608
- rotation_frequency: Optional[str] = None,
609
- rotation_state: Optional[ItemVersionState] = None,
610
- expiration: Optional[datetime.datetime] = None,
611
- ) -> PangeaResponse[AsymmetricGenerateResult]:
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]:
612
1404
  """
613
- Asymmetric generate
614
-
615
- Generate an asymmetric key
1405
+ Store key
616
1406
 
617
- OperationId: vault_post_v1_key_generate 2
1407
+ Import a symmetric JWT key.
618
1408
 
619
1409
  Args:
620
- algorithm (AsymmetricAlgorithm): The algorithm of the key
621
- purpose (KeyPurpose): The purpose of this key
622
- name (str): The name of this item
623
- folder (str, optional): The folder where this item is stored
624
- metadata (dict, optional): User-provided metadata
625
- tags (list[str], optional): A list of user-defined tags
626
- rotation_frequency (str, optional): Period of time between item rotations, or `never` to disallow rotation
627
- rotation_state (ItemVersionState, optional): State to which the previous version should transition upon rotation.
628
- Supported options:
629
- - `deactivated`
630
- - `destroyed`
631
- expiration (str, optional): Expiration timestamp
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.
632
1423
 
633
1424
  Raises:
634
- PangeaAPIException: If an API Error happens
635
-
636
- Returns:
637
- A PangeaResponse where the ID of the key
638
- is returned in the response.result field.
639
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#generate).
1425
+ PangeaAPIException: If an API Error happens.
640
1426
 
641
1427
  Examples:
642
- response = vault.asymmetric_generate(
643
- algorithm=AsymmetricAlgorithm.RSA,
644
- purpose=KeyPurpose.SIGNING,
645
- name="my-very-secret-secret",
646
- folder="/personal",
647
- metadata={
648
- "created_by": "John Doe",
649
- "used_in": "Google products"
650
- },
651
- tags=[
652
- "irs_2023",
653
- "personal"
654
- ],
655
- rotation_frequency="10d",
656
- rotation_state=ItemVersionState.DEACTIVATED,
657
- expiration="2025-01-01T10:00:00Z",
1428
+ response = await vault.store_key(
1429
+ key_type=ItemType.SYMMETRIC_KEY,
1430
+ purpose=SymmetricKeyPurpose.JWT,
1431
+ algorithm=SymmetricKeyJwtAlgorithm.HS512,
658
1432
  )
659
1433
  """
660
- input = AsymmetricGenerateRequest(
661
- type=ItemType.ASYMMETRIC_KEY,
662
- algorithm=algorithm,
663
- purpose=purpose,
664
- name=name, # type: ignore[arg-type]
665
- folder=folder,
666
- metadata=metadata,
667
- tags=tags,
668
- rotation_frequency=rotation_frequency,
669
- rotation_state=rotation_state,
670
- expiration=expiration,
671
- )
672
- return await self.request.post("v1/key/generate", AsymmetricGenerateResult, data=input.dict(exclude_none=True))
673
1434
 
674
- # Store endpoints
675
- async def asymmetric_store(
1435
+ @overload
1436
+ async def store_key(
676
1437
  self,
677
- private_key: EncodedPrivateKey,
678
- public_key: EncodedPublicKey,
679
- algorithm: AsymmetricAlgorithm,
680
- purpose: KeyPurpose,
681
- name: str,
682
- folder: Optional[str] = None,
683
- metadata: Optional[Metadata] = None,
684
- tags: Optional[Tags] = None,
685
- rotation_frequency: Optional[str] = None,
686
- rotation_state: Optional[ItemVersionState] = None,
687
- expiration: Optional[datetime.datetime] = None,
688
- ) -> PangeaResponse[AsymmetricStoreResult]:
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]:
689
1452
  """
690
- Asymmetric store
1453
+ Store key
691
1454
 
692
- Import an asymmetric key
693
-
694
- OperationId: vault_post_v1_key_store 1
1455
+ Import a symmetric FPE key.
695
1456
 
696
1457
  Args:
697
- private_key (EncodedPrivateKey): The private key in PEM format
698
- public_key (EncodedPublicKey): The public key in PEM format
699
- algorithm (AsymmetricAlgorithm): The algorithm of the key
700
- purpose (KeyPurpose): The purpose of this key. `signing`, `encryption`, or `jwt`.
701
- name (str): The name of this item
702
- folder (str, optional): The folder where this item is stored
703
- metadata (dict, optional): User-provided metadata
704
- tags (list[str], optional): A list of user-defined tags
705
- rotation_frequency (str, optional): Period of time between item rotations, or `never` to disallow rotation
706
- rotation_state (ItemVersionState, optional): State to which the previous version should transition upon rotation.
707
- Supported options:
708
- - `deactivated`
709
- - `destroyed`
710
- expiration (str, optional): Expiration timestamp
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.
711
1471
 
712
1472
  Raises:
713
- PangeaAPIException: If an API Error happens
714
-
715
- Returns:
716
- A PangeaResponse where the ID and public key
717
- is returned in the response.result field.
718
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#import-a-key).
1473
+ PangeaAPIException: If an API Error happens.
719
1474
 
720
1475
  Examples:
721
- response = vault.asymmetric_store(
722
- private_key="private key example",
723
- public_key="-----BEGIN PUBLIC KEY-----\\nMCowBQYDK2VwAyEA8s5JopbEPGBylPBcMK+L5PqHMqPJW/5KYPgBHzZGncc=\\n-----END PUBLIC KEY-----",
724
- algorithm=AsymmetricAlgorithm.RSA,
725
- purpose=KeyPurpose.SIGNING,
726
- name="my-very-secret-secret",
727
- folder="/personal",
728
- metadata={
729
- "created_by": "John Doe",
730
- "used_in": "Google products"
731
- },
732
- tags=[
733
- "irs_2023",
734
- "personal"
735
- ],
736
- rotation_frequency="10d",
737
- rotation_state=ItemVersionState.DEACTIVATED,
738
- expiration="2025-01-01T10:00:00Z",
1476
+ response = await vault.store_key(
1477
+ key_type=ItemType.SYMMETRIC_KEY,
1478
+ purpose=SymmetricKeyPurpose.FPE,
1479
+ algorithm=SymmetricKeyFpeAlgorithm.AES_FF3_1_256_BETA,
739
1480
  )
740
1481
  """
741
- input = AsymmetricStoreRequest(
742
- type=ItemType.ASYMMETRIC_KEY,
743
- algorithm=algorithm,
744
- purpose=purpose,
745
- public_key=public_key,
746
- private_key=private_key,
747
- name=name,
748
- folder=folder,
749
- metadata=metadata,
750
- tags=tags,
751
- rotation_frequency=rotation_frequency,
752
- rotation_state=rotation_state,
753
- expiration=expiration,
754
- )
755
- return await self.request.post("v1/key/store", AsymmetricStoreResult, data=input.dict(exclude_none=True))
756
1482
 
757
- async def symmetric_store(
1483
+ async def store_key(
758
1484
  self,
759
- key: str,
760
- algorithm: SymmetricAlgorithm,
761
- purpose: KeyPurpose,
762
- name: str,
763
- folder: Optional[str] = None,
764
- metadata: Optional[Metadata] = None,
765
- tags: Optional[Tags] = None,
766
- rotation_frequency: Optional[str] = None,
767
- rotation_state: Optional[ItemVersionState] = None,
768
- expiration: Optional[datetime.datetime] = None,
769
- ) -> PangeaResponse[SymmetricStoreResult]:
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]:
770
1509
  """
771
- Symmetric store
1510
+ Store key
772
1511
 
773
- Import a symmetric key
774
-
775
- OperationId: vault_post_v1_key_store 2
1512
+ Import a key.
776
1513
 
777
1514
  Args:
778
- key (str): The key material (in base64)
779
- algorithm (SymmetricAlgorithm): The algorithm of the key
780
- purpose (KeyPurpose): The purpose of this key. `encryption` or `jwt`
781
- name (str): The name of this item
782
- folder (str, optional): The folder where this item is stored
783
- metadata (dict, optional): User-provided metadata
784
- tags (list[str], optional): A list of user-defined tags
785
- rotation_frequency (str, optional): Period of time between item rotations, or `never` to disallow rotation
786
- rotation_state (ItemVersionState, optional): State to which the previous version should transition upon rotation.
787
- Supported options:
788
- - `deactivated`
789
- - `destroyed`
790
- expiration (str, optional): Expiration timestamp
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.
791
1530
 
792
1531
  Raises:
793
- PangeaAPIException: If an API Error happens
794
-
795
- Returns:
796
- A PangeaResponse where the ID
797
- is returned in the response.result field.
798
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#import-a-key).
1532
+ PangeaAPIException: If an API Error happens.
799
1533
 
800
1534
  Examples:
801
- response = vault.symmetric_store(
802
- key="lJkk0gCLux+Q+rPNqLPEYw==",
803
- algorithm=SymmetricAlgorithm.AES,
804
- purpose=KeyPurpose.ENCRYPTION,
805
- name="my-very-secret-secret",
806
- folder="/personal",
807
- metadata={
808
- "created_by": "John Doe",
809
- "used_in": "Google products"
810
- },
811
- tags=[
812
- "irs_2023",
813
- "personal"
814
- ],
815
- rotation_frequency="10d",
816
- rotation_state=ItemVersionState.DEACTIVATED,
817
- expiration="2025-01-01T10:00:00Z",
1535
+ response = await vault.store_key(
1536
+ key_type=ItemType.SYMMETRIC_KEY,
1537
+ purpose=SymmetricKeyPurpose.FPE,
1538
+ algorithm=SymmetricKeyFpeAlgorithm.AES_FF3_1_256_BETA,
818
1539
  )
819
1540
  """
820
- input = SymmetricStoreRequest(
821
- type=ItemType.SYMMETRIC_KEY,
822
- algorithm=algorithm,
823
- purpose=purpose,
824
- key=key, # type: ignore[arg-type]
825
- name=name,
826
- folder=folder,
827
- metadata=metadata,
828
- tags=tags,
829
- rotation_frequency=rotation_frequency,
830
- rotation_state=rotation_state,
831
- expiration=expiration,
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
+ ),
832
1561
  )
833
- return await self.request.post("v1/key/store", SymmetricStoreResult, data=input.dict(exclude_none=True))
834
1562
 
835
- # Rotate endpoint
836
- async def key_rotate(
1563
+ @overload
1564
+ async def rotate_key(
837
1565
  self,
838
- id: str,
839
- rotation_state: ItemVersionState,
840
- public_key: Optional[EncodedPublicKey] = None,
841
- private_key: Optional[EncodedPrivateKey] = None,
842
- key: Optional[EncodedSymmetricKey] = None,
843
- ) -> PangeaResponse[KeyRotateResult]:
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).
1585
+
1586
+ Raises:
1587
+ PangeaAPIException: If an API Error happens.
1588
+
1589
+ Examples:
1590
+ response = await vault.rotate_key("pvi_...", key_type=ItemType.ASYMMETRIC_KEY)
844
1591
  """
845
- Key rotate
846
1592
 
847
- Manually rotate a symmetric or asymmetric key
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
848
1604
 
849
- OperationId: vault_post_v1_key_rotate
1605
+ Manually rotate a symmetric key.
850
1606
 
851
1607
  Args:
852
- id (str): The ID of the item
853
- rotation_state (ItemVersionState, optional): State to which the previous version should transition upon rotation.
854
- Supported options:
855
- - `deactivated`
856
- - `suspended`
857
- - `destroyed`
858
-
859
- Default is `deactivated`.
860
- public_key (EncodedPublicKey, optional): The public key (in PEM format)
861
- private_key (EncodedPrivateKey, optional): The private key (in PEM format)
862
- key (EncodedSymmetricKey, optional): The key material (in base64)
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.
863
1613
 
864
1614
  Raises:
865
- PangeaAPIException: If an API Error happens
1615
+ PangeaAPIException: If an API Error happens.
866
1616
 
867
- Returns:
868
- A PangeaResponse where the ID
869
- is returned in the response.result field.
870
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#rotate).
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.
871
1647
 
872
1648
  Examples:
873
- response = vault.key_rotate(
874
- id="pvi_p6g5i3gtbvqvc3u6zugab6qs6r63tqf5",
875
- rotation_state=ItemVersionState.DEACTIVATED,
876
- key="lJkk0gCLux+Q+rPNqLPEYw==",
877
- )
1649
+ response = await vault.rotate_key("pvi_...", key_type=ItemType.SYMMETRIC_KEY)
878
1650
  """
879
- input = KeyRotateRequest(
880
- id=id, public_key=public_key, private_key=private_key, key=key, rotation_state=rotation_state
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
+ ),
881
1662
  )
882
- return await self.request.post("v1/key/rotate", KeyRotateResult, data=input.dict(exclude_none=True))
883
1663
 
884
- # Encrypt
885
- async def encrypt(self, id: str, plain_text: str, version: Optional[int] = None) -> PangeaResponse[EncryptResult]:
1664
+ async def encrypt(
1665
+ self, item_id: str, plain_text: str, *, version: int | None = None, additional_data: str | None = None
1666
+ ) -> PangeaResponse[EncryptResult]:
886
1667
  """
887
1668
  Encrypt
888
1669
 
889
- Encrypt a message using a key
1670
+ Encrypt a message using a key.
890
1671
 
891
- OperationId: vault_post_v1_key_encrypt
1672
+ OperationId: vault_post_v2_key_encrypt
892
1673
 
893
1674
  Args:
894
- id (str): The item ID
895
- plain_text (str): A message to be in encrypted (in base64)
896
- version (int, optional): The item version
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).
897
1684
 
898
1685
  Raises:
899
1686
  PangeaAPIException: If an API Error happens
900
1687
 
901
- Returns:
902
- A PangeaResponse where the encrypted message in base64
903
- is returned in the response.result field.
904
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#encrypt).
905
-
906
1688
  Examples:
907
- response = vault.encrypt(
1689
+ response = await vault.encrypt(
908
1690
  id="pvi_p6g5i3gtbvqvc3u6zugab6qs6r63tqf5",
909
1691
  plain_text="lJkk0gCLux+Q+rPNqLPEYw==",
910
1692
  version=1,
911
1693
  )
912
1694
  """
913
- input = EncryptRequest(id=id, plain_text=plain_text, version=version) # type: ignore[call-arg]
914
- return await self.request.post("v1/key/encrypt", EncryptResult, data=input.dict(exclude_none=True))
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
+ )
915
1700
 
916
- # Decrypt
917
- async def decrypt(self, id: str, cipher_text: str, version: Optional[int] = None) -> PangeaResponse[DecryptResult]:
1701
+ async def decrypt(
1702
+ self, item_id: str, cipher_text: str, *, version: int | None = None, additional_data: str | None = None
1703
+ ) -> PangeaResponse[DecryptResult]:
918
1704
  """
919
1705
  Decrypt
920
1706
 
921
- Decrypt a message using a key
1707
+ Decrypt a message using a key.
922
1708
 
923
- OperationId: vault_post_v1_key_decrypt
1709
+ OperationId: vault_post_v2_key_decrypt
924
1710
 
925
1711
  Args:
926
- id (str): The item ID
927
- cipher_text (str): A message encrypted by Vault (in base64)
928
- 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).
929
1720
 
930
1721
  Raises:
931
1722
  PangeaAPIException: If an API Error happens
932
1723
 
933
- Returns:
934
- A PangeaResponse where the decrypted message in base64
935
- is returned in the response.result field.
936
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#decrypt).
937
-
938
1724
  Examples:
939
- response = vault.decrypt(
1725
+ response = await vault.decrypt(
940
1726
  id="pvi_p6g5i3gtbvqvc3u6zugab6qs6r63tqf5",
941
1727
  cipher_text="lJkk0gCLux+Q+rPNqLPEYw==",
942
1728
  version=1,
943
1729
  )
944
1730
  """
945
- input = DecryptRequest(id=id, cipher_text=cipher_text, version=version) # type: ignore[call-arg]
946
- return await self.request.post("v1/key/decrypt", DecryptResult, data=input.dict(exclude_none=True))
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
+ )
947
1736
 
948
- # Sign
949
- async def sign(self, id: str, message: str, version: Optional[int] = None) -> PangeaResponse[SignResult]:
1737
+ async def sign(self, item_id: str, message: str, *, version: int | None = None) -> PangeaResponse[SignResult]:
950
1738
  """
951
1739
  Sign
952
1740
 
953
1741
  Sign a message using a key
954
1742
 
955
- OperationId: vault_post_v1_key_sign
1743
+ OperationId: vault_post_v2_sign
956
1744
 
957
1745
  Args:
958
- id (str): The item ID
959
- message (str): The message to be signed, in base64
960
- version (int, optional): The item version
1746
+ id: The item ID.
1747
+ message: The message to be signed, in base64.
1748
+ version: The item version.
1749
+
1750
+ Returns:
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).
961
1754
 
962
1755
  Raises:
963
1756
  PangeaAPIException: If an API Error happens
964
1757
 
965
- Returns:
966
- A PangeaResponse where the signature of the message in base64
967
- is returned in the response.result field.
968
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#sign).
969
-
970
1758
  Examples:
971
- response = vault.sign(
1759
+ response = await vault.sign(
972
1760
  id="pvi_p6g5i3gtbvqvc3u6zugab6qs6r63tqf5",
973
1761
  message="lJkk0gCLux+Q+rPNqLPEYw==",
974
1762
  version=1,
975
1763
  )
976
1764
  """
977
- input = SignRequest(id=id, message=message, version=version)
978
- 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
+ )
979
1768
 
980
- # Verify
981
1769
  async def verify(
982
- self, id: str, message: str, signature: str, version: Optional[int] = None
1770
+ self, item_id: str, message: str, signature: str, *, version: int | None = None
983
1771
  ) -> PangeaResponse[VerifyResult]:
984
1772
  """
985
1773
  Verify
986
1774
 
987
- Verify a signature using a key
1775
+ Verify a signature using a key.
988
1776
 
989
- OperationId: vault_post_v1_key_verify
1777
+ OperationId: vault_post_v2_key_verify
990
1778
 
991
1779
  Args:
992
- id (str): The item ID
993
- message (str): A message to be verified (in base64)
994
- signature (str): The message signature (in base64)
995
- 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.
996
1784
 
997
1785
  Raises:
998
1786
  PangeaAPIException: If an API Error happens
@@ -1003,31 +1791,34 @@ class VaultAsync(ServiceBaseAsync):
1003
1791
  Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#verify).
1004
1792
 
1005
1793
  Examples:
1006
- response = vault.verify(
1794
+ response = await vault.verify(
1007
1795
  id="pvi_p6g5i3gtbvqvc3u6zugab6qs6r63tqf5",
1008
1796
  message="lJkk0gCLux+Q+rPNqLPEYw==",
1009
1797
  signature="FfWuT2Mq/+cxa7wIugfhzi7ktZxVf926idJNgBDCysF/knY9B7M6wxqHMMPDEBs86D8OsEGuED21y3J7IGOpCQ==",
1010
1798
  version=1,
1011
1799
  )
1012
1800
  """
1013
- input = VerifyRequest(
1014
- id=id,
1015
- message=message,
1016
- signature=signature,
1017
- 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
+ ),
1018
1810
  )
1019
- return await self.request.post("v1/key/verify", VerifyResult, data=input.dict(exclude_none=True))
1020
1811
 
1021
1812
  async def jwt_verify(self, jws: str) -> PangeaResponse[JWTVerifyResult]:
1022
1813
  """
1023
1814
  JWT Verify
1024
1815
 
1025
- Verify the signature of a JSON Web Token (JWT)
1816
+ Verify the signature of a JSON Web Token (JWT).
1026
1817
 
1027
- OperationId: vault_post_v1_key_verify_jwt
1818
+ OperationId: vault_post_v2_key_verify_jwt
1028
1819
 
1029
1820
  Args:
1030
- jws (str): The signed JSON Web Token (JWS)
1821
+ jws: The signed JSON Web Token (JWS).
1031
1822
 
1032
1823
  Raises:
1033
1824
  PangeaAPIException: If an API Error happens
@@ -1038,180 +1829,196 @@ class VaultAsync(ServiceBaseAsync):
1038
1829
  Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#verify-jwt).
1039
1830
 
1040
1831
  Examples:
1041
- response = vault.jwt_verify(
1042
- jws="ewogICJhbGciO...",
1043
- )
1832
+ response = await vault.jwt_verify(jws="ewogICJhbGciO...")
1044
1833
  """
1045
- input = JWTVerifyRequest(jws=jws)
1046
- 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))
1047
1835
 
1048
- async def jwt_sign(self, id: str, payload: str) -> PangeaResponse[JWTSignResult]:
1836
+ async def jwt_sign(self, item_id: str, payload: str) -> PangeaResponse[JWTSignResult]:
1049
1837
  """
1050
1838
  JWT Sign
1051
1839
 
1052
- Sign a JSON Web Token (JWT) using a key
1840
+ Sign a JSON Web Token (JWT) using a key.
1053
1841
 
1054
- OperationId: vault_post_v1_key_sign_jwt
1842
+ OperationId: vault_post_v2_jwt_sign
1055
1843
 
1056
1844
  Args:
1057
- id (str): The item ID
1058
- payload (str): The JWT payload (in JSON)
1845
+ id: The item ID.
1846
+ payload: The JWT payload (in JSON).
1059
1847
 
1060
1848
  Raises:
1061
1849
  PangeaAPIException: If an API Error happens
1062
1850
 
1063
1851
  Returns:
1064
- A PangeaResponse where the signed JSON Web Token (JWS)
1065
- is returned in the response.result field.
1066
- 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).
1067
1855
 
1068
1856
  Examples:
1069
- response = vault.jwt_sign(
1857
+ response = await vault.jwt_sign(
1070
1858
  id="pvi_p6g5i3gtbvqvc3u6zugab6qs6r63tqf5",
1071
1859
  payload="{\\"sub\\": \\"1234567890\\",\\"name\\": \\"John Doe\\",\\"admin\\": true}"
1072
1860
  )
1073
1861
  """
1074
- input = JWTSignRequest(id=id, payload=payload)
1075
- 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))
1076
1863
 
1077
- # Get endpoint
1078
- 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]:
1079
1865
  """
1080
1866
  JWT Retrieve
1081
1867
 
1082
- Retrieve a key in JWK format
1868
+ Retrieve a key in JWK format.
1083
1869
 
1084
- OperationId: vault_post_v1_get_jwk
1870
+ OperationId: vault_post_v2_jwk_get
1085
1871
 
1086
1872
  Args:
1087
- id (str): The item ID
1088
- version (str, optional): The key version(s).
1089
- - `all` for all versions
1090
- - `num` for a specific version
1091
- - `-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
1092
1878
  Raises:
1093
1879
  PangeaAPIException: If an API Error happens
1094
1880
 
1095
1881
  Returns:
1096
- A PangeaResponse where the JSON Web Key Set (JWKS) object
1097
- is returned in the response.result field.
1098
- 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).
1099
1885
 
1100
1886
  Examples:
1101
- response = vault.jwk_get(
1102
- id="pvi_p6g5i3gtbvqvc3u6zugab6qs6r63tqf5",
1103
- )
1887
+ response = await vault.jwk_get("pvi_p6g5i3gtbvqvc3u6zugab6qs6r63tqf5")
1104
1888
  """
1105
- input = JWKGetRequest(id=id, version=version)
1106
- 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))
1107
1890
 
1108
- # State change
1109
1891
  async def state_change(
1110
- self, id: str, state: ItemVersionState, version: Optional[int] = None, destroy_period: Optional[str] = None
1111
- ) -> 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]:
1112
1899
  """
1113
1900
  State change
1114
1901
 
1115
- 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.
1116
1903
 
1117
- OperationId: vault_post_v1_state_change
1904
+ OperationId: vault_post_v2_state_change
1118
1905
 
1119
1906
  Args:
1120
- id (str): The item ID
1121
- state (ItemVersionState): The new state of the item version. Supported options:
1122
- - `active`
1123
- - `deactivated`
1124
- - `suspended`
1125
- - `compromised`
1126
- - `destroyed`
1127
- version (int, optional): the item version
1128
- destroy_period (str, optional): Period of time for the destruction of a compromised key.
1129
- Only valid if state=`compromised`
1130
- Raises:
1131
- 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`.
1132
1912
 
1133
1913
  Returns:
1134
- A PangeaResponse where the state change object
1135
- is returned in the response.result field.
1136
- 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
1137
1920
 
1138
1921
  Examples:
1139
- response = vault.state_change(
1922
+ response = await vault.state_change(
1140
1923
  id="pvi_p6g5i3gtbvqvc3u6zugab6qs6r63tqf5",
1141
1924
  state=ItemVersionState.DEACTIVATED,
1142
1925
  )
1143
1926
  """
1144
- input = StateChangeRequest(id=id, state=state, version=version, destroy_period=destroy_period)
1145
- 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)
1146
1934
 
1147
- # Folder create
1148
1935
  async def folder_create(
1149
1936
  self,
1150
1937
  name: str,
1151
1938
  folder: str,
1152
- metadata: Optional[Metadata] = None,
1153
- 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,
1154
1946
  ) -> PangeaResponse[FolderCreateResult]:
1155
1947
  """
1156
1948
  Create
1157
1949
 
1158
- Creates a folder
1950
+ Creates a folder.
1159
1951
 
1160
- OperationId: vault_post_v1_folder_create
1952
+ OperationId: vault_post_v2_folder_create
1161
1953
 
1162
1954
  Args:
1163
- name (str): The name of this folder
1164
- folder (str): The parent folder where this folder is stored
1165
- metadata (Metadata, optional): User-provided metadata
1166
- 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
+
1167
1967
  Raises:
1168
1968
  PangeaAPIException: If an API Error happens
1169
1969
 
1170
- Returns:
1171
- A PangeaResponse where the state change object
1172
- is returned in the response.result field.
1173
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault#create).
1174
-
1175
1970
  Examples:
1176
- response = vault.folder_create(
1971
+ response = await vault.folder_create(
1177
1972
  name="folder_name",
1178
1973
  folder="parent/folder/name",
1179
1974
  )
1180
1975
  """
1181
- input = FolderCreateRequest(name=name, folder=folder, metadata=metadata, tags=tags)
1182
- 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
+ )
1183
1990
 
1184
- # Encrypt structured
1185
1991
  async def encrypt_structured(
1186
1992
  self,
1187
- id: str,
1993
+ key_id: str,
1188
1994
  structured_data: TDict,
1189
- filter: str,
1190
- version: Optional[int] = None,
1191
- additional_data: Optional[str] = None,
1995
+ filter_expr: str,
1996
+ *,
1997
+ version: int | None = None,
1998
+ additional_data: str | None = None,
1192
1999
  ) -> PangeaResponse[EncryptStructuredResult[TDict]]:
1193
2000
  """
1194
2001
  Encrypt structured
1195
2002
 
1196
2003
  Encrypt parts of a JSON object.
1197
2004
 
1198
- OperationId: vault_post_v1_key_encrypt_structured
2005
+ OperationId: vault_post_v2_encrypt_structured
1199
2006
 
1200
2007
  Args:
1201
- id (str): The item ID.
1202
- structured_data (dict): Structured data for applying bulk operations.
1203
- filter (str, optional): A filter expression for applying bulk operations to the data field.
1204
- version (int, optional): The item version. Defaults to the current version.
1205
- additional_data (str, optional): User provided authentication data.
1206
-
1207
- Raises:
1208
- 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.
1209
2013
 
1210
2014
  Returns:
1211
2015
  A `PangeaResponse` where the encrypted object is returned in the
1212
2016
  `response.result` field. Available response fields can be found in
1213
2017
  our [API documentation](https://pangea.cloud/docs/api/vault#encrypt-structured).
1214
2018
 
2019
+ Raises:
2020
+ PangeaAPIException: If an API error happens.
2021
+
1215
2022
  Examples:
1216
2023
  data = {"field1": [1, 2, "true", "false"], "field2": "data2"}
1217
2024
  response = await vault.encrypt_structured(
@@ -1221,37 +2028,41 @@ class VaultAsync(ServiceBaseAsync):
1221
2028
  )
1222
2029
  """
1223
2030
 
1224
- input: EncryptStructuredRequest[TDict] = EncryptStructuredRequest(
1225
- 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,
1226
2037
  )
1227
2038
  return await self.request.post(
1228
- "v1/key/encrypt/structured",
2039
+ "v2/encrypt_structured",
1229
2040
  EncryptStructuredResult,
1230
- data=input.dict(exclude_none=True),
2041
+ data=data.model_dump(exclude_none=True),
1231
2042
  )
1232
2043
 
1233
- # Decrypt structured
1234
2044
  async def decrypt_structured(
1235
2045
  self,
1236
- id: str,
2046
+ key_id: str,
1237
2047
  structured_data: TDict,
1238
- filter: str,
1239
- version: Optional[int] = None,
1240
- additional_data: Optional[str] = None,
2048
+ filter_expr: str,
2049
+ *,
2050
+ version: int | None = None,
2051
+ additional_data: str | None = None,
1241
2052
  ) -> PangeaResponse[EncryptStructuredResult[TDict]]:
1242
2053
  """
1243
2054
  Decrypt structured
1244
2055
 
1245
2056
  Decrypt parts of a JSON object.
1246
2057
 
1247
- OperationId: vault_post_v1_key_decrypt_structured
2058
+ OperationId: vault_post_v2_decrypt_structured
1248
2059
 
1249
2060
  Args:
1250
- id (str): The item ID.
1251
- structured_data (dict): Structured data to decrypt.
1252
- filter (str, optional): A filter expression for applying bulk operations to the data field.
1253
- version (int, optional): The item version. Defaults to the current version.
1254
- 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.
1255
2066
 
1256
2067
  Raises:
1257
2068
  PangeaAPIException: If an API error happens.
@@ -1270,11 +2081,160 @@ class VaultAsync(ServiceBaseAsync):
1270
2081
  )
1271
2082
  """
1272
2083
 
1273
- input: EncryptStructuredRequest[TDict] = EncryptStructuredRequest(
1274
- 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,
1275
2090
  )
1276
2091
  return await self.request.post(
1277
- "v1/key/decrypt/structured",
2092
+ "v2/decrypt_structured",
1278
2093
  EncryptStructuredResult,
1279
- 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
+ ),
1280
2240
  )