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

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