pangea-sdk 3.8.0b1__py3-none-any.whl → 5.4.0b1__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. pangea/__init__.py +1 -1
  2. pangea/asyncio/file_uploader.py +1 -1
  3. pangea/asyncio/request.py +56 -34
  4. pangea/asyncio/services/__init__.py +4 -0
  5. pangea/asyncio/services/ai_guard.py +75 -0
  6. pangea/asyncio/services/audit.py +192 -31
  7. pangea/asyncio/services/authn.py +187 -109
  8. pangea/asyncio/services/authz.py +285 -0
  9. pangea/asyncio/services/base.py +21 -2
  10. pangea/asyncio/services/embargo.py +2 -2
  11. pangea/asyncio/services/file_scan.py +24 -9
  12. pangea/asyncio/services/intel.py +108 -34
  13. pangea/asyncio/services/prompt_guard.py +73 -0
  14. pangea/asyncio/services/redact.py +72 -4
  15. pangea/asyncio/services/sanitize.py +217 -0
  16. pangea/asyncio/services/share.py +246 -73
  17. pangea/asyncio/services/vault.py +1710 -750
  18. pangea/crypto/rsa.py +135 -0
  19. pangea/deep_verify.py +7 -1
  20. pangea/dump_audit.py +9 -8
  21. pangea/request.py +87 -59
  22. pangea/response.py +49 -31
  23. pangea/services/__init__.py +4 -0
  24. pangea/services/ai_guard.py +128 -0
  25. pangea/services/audit/audit.py +205 -42
  26. pangea/services/audit/models.py +56 -8
  27. pangea/services/audit/signing.py +6 -5
  28. pangea/services/audit/util.py +3 -3
  29. pangea/services/authn/authn.py +140 -70
  30. pangea/services/authn/models.py +167 -11
  31. pangea/services/authz.py +400 -0
  32. pangea/services/base.py +39 -8
  33. pangea/services/embargo.py +2 -2
  34. pangea/services/file_scan.py +32 -15
  35. pangea/services/intel.py +157 -32
  36. pangea/services/prompt_guard.py +83 -0
  37. pangea/services/redact.py +152 -4
  38. pangea/services/sanitize.py +371 -0
  39. pangea/services/share/share.py +683 -107
  40. pangea/services/vault/models/asymmetric.py +120 -18
  41. pangea/services/vault/models/common.py +439 -141
  42. pangea/services/vault/models/keys.py +94 -0
  43. pangea/services/vault/models/secret.py +27 -3
  44. pangea/services/vault/models/symmetric.py +68 -22
  45. pangea/services/vault/vault.py +1690 -749
  46. pangea/tools.py +6 -7
  47. pangea/utils.py +16 -27
  48. pangea/verify_audit.py +270 -83
  49. {pangea_sdk-3.8.0b1.dist-info → pangea_sdk-5.4.0b1.dist-info}/METADATA +43 -35
  50. pangea_sdk-5.4.0b1.dist-info/RECORD +60 -0
  51. {pangea_sdk-3.8.0b1.dist-info → pangea_sdk-5.4.0b1.dist-info}/WHEEL +1 -1
  52. 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
  )