pangea-sdk 3.9.0__py3-none-any.whl → 4.1.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.
pangea/services/authz.py CHANGED
@@ -113,7 +113,7 @@ class CheckRequest(APIRequestModel):
113
113
  class DebugPath(APIResponseModel):
114
114
  type: str
115
115
  id: str
116
- action: Optional[str]
116
+ action: Optional[str] = None
117
117
 
118
118
 
119
119
  class Debug(APIResponseModel):
@@ -202,7 +202,7 @@ class AuthZ(ServiceBase):
202
202
  """
203
203
 
204
204
  input_data = TupleCreateRequest(tuples=tuples)
205
- return self.request.post("v1/tuple/create", TupleCreateResult, data=input_data.dict(exclude_none=True))
205
+ return self.request.post("v1/tuple/create", TupleCreateResult, data=input_data.model_dump(exclude_none=True))
206
206
 
207
207
  def tuple_list(
208
208
  self,
@@ -237,9 +237,9 @@ class AuthZ(ServiceBase):
237
237
  authz.tuple_list(TupleListFilter(subject_type="user", subject_id="user_1"))
238
238
  """
239
239
  input_data = TupleListRequest(
240
- filter=filter.dict(exclude_none=True), size=size, last=last, order=order, order_by=order_by
240
+ filter=filter.model_dump(exclude_none=True), size=size, last=last, order=order, order_by=order_by
241
241
  )
242
- return self.request.post("v1/tuple/list", TupleListResult, data=input_data.dict(exclude_none=True))
242
+ return self.request.post("v1/tuple/list", TupleListResult, data=input_data.model_dump(exclude_none=True))
243
243
 
244
244
  def tuple_delete(self, tuples: List[Tuple]) -> PangeaResponse[TupleDeleteResult]:
245
245
  """Delete tuples.
@@ -270,7 +270,7 @@ class AuthZ(ServiceBase):
270
270
  """
271
271
 
272
272
  input_data = TupleDeleteRequest(tuples=tuples)
273
- return self.request.post("v1/tuple/delete", TupleDeleteResult, data=input_data.dict(exclude_none=True))
273
+ return self.request.post("v1/tuple/delete", TupleDeleteResult, data=input_data.model_dump(exclude_none=True))
274
274
 
275
275
  def check(
276
276
  self,
@@ -309,7 +309,7 @@ class AuthZ(ServiceBase):
309
309
  """
310
310
 
311
311
  input_data = CheckRequest(resource=resource, action=action, subject=subject, debug=debug, attributes=attributes)
312
- return self.request.post("v1/check", CheckResult, data=input_data.dict(exclude_none=True))
312
+ return self.request.post("v1/check", CheckResult, data=input_data.model_dump(exclude_none=True))
313
313
 
314
314
  def list_resources(self, type: str, action: str, subject: Subject) -> PangeaResponse[ListResourcesResult]:
315
315
  """List resources.
@@ -339,7 +339,9 @@ class AuthZ(ServiceBase):
339
339
  """
340
340
 
341
341
  input_data = ListResourcesRequest(type=type, action=action, subject=subject)
342
- return self.request.post("v1/list-resources", ListResourcesResult, data=input_data.dict(exclude_none=True))
342
+ return self.request.post(
343
+ "v1/list-resources", ListResourcesResult, data=input_data.model_dump(exclude_none=True)
344
+ )
343
345
 
344
346
  def list_subjects(self, resource: Resource, action: str) -> PangeaResponse[ListSubjectsResult]:
345
347
  """List subjects.
@@ -367,4 +369,4 @@ class AuthZ(ServiceBase):
367
369
  """
368
370
 
369
371
  input_data = ListSubjectsRequest(resource=resource, action=action)
370
- return self.request.post("v1/list-subjects", ListSubjectsResult, data=input_data.dict(exclude_none=True))
372
+ return self.request.post("v1/list-subjects", ListSubjectsResult, data=input_data.model_dump(exclude_none=True))
@@ -103,7 +103,7 @@ class Embargo(ServiceBase):
103
103
  response = embargo.ip_check("190.6.64.94")
104
104
  """
105
105
  input = IPCheckRequest(ip=ip)
106
- return self.request.post("v1/ip/check", EmbargoResult, data=input.dict())
106
+ return self.request.post("v1/ip/check", EmbargoResult, data=input.model_dump())
107
107
 
108
108
  def iso_check(self, iso_code: str) -> PangeaResponse[EmbargoResult]:
109
109
  """
@@ -130,4 +130,4 @@ class Embargo(ServiceBase):
130
130
  response = embargo.iso_check("CU")
131
131
  """
132
132
  input = ISOCheckRequest(iso_code=iso_code)
133
- return self.request.post("v1/iso/check", result_class=EmbargoResult, data=input.dict())
133
+ return self.request.post("v1/iso/check", result_class=EmbargoResult, data=input.model_dump())
@@ -142,7 +142,7 @@ class FileScan(ServiceBase):
142
142
  transfer_method=transfer_method,
143
143
  source_url=source_url,
144
144
  )
145
- data = input.dict(exclude_none=True)
145
+ data = input.model_dump(exclude_none=True)
146
146
  return self.request.post("v1/scan", FileScanResult, data=data, files=files, poll_result=sync_call)
147
147
 
148
148
  def request_upload_url(
@@ -164,7 +164,7 @@ class FileScan(ServiceBase):
164
164
  input.sha256 = params.sha256_hex
165
165
  input.size = params.size
166
166
 
167
- data = input.dict(exclude_none=True)
167
+ data = input.model_dump(exclude_none=True)
168
168
  return self.request.request_presigned_url("v1/scan", FileScanResult, data=data)
169
169
 
170
170
 
pangea/services/intel.py CHANGED
@@ -524,7 +524,7 @@ class FileIntel(ServiceBase):
524
524
  )
525
525
  """
526
526
  input = FileReputationRequest(hash=hash, hash_type=hash_type, verbose=verbose, raw=raw, provider=provider)
527
- return self.request.post("v1/reputation", FileReputationResult, data=input.dict(exclude_none=True))
527
+ return self.request.post("v1/reputation", FileReputationResult, data=input.model_dump(exclude_none=True))
528
528
 
529
529
  def hash_reputation_bulk(
530
530
  self,
@@ -563,7 +563,7 @@ class FileIntel(ServiceBase):
563
563
  input = FileReputationBulkRequest( # type: ignore[call-arg]
564
564
  hashes=hashes, hash_type=hash_type, verbose=verbose, raw=raw, provider=provider
565
565
  )
566
- return self.request.post("v2/reputation", FileReputationBulkResult, data=input.dict(exclude_none=True))
566
+ return self.request.post("v2/reputation", FileReputationBulkResult, data=input.model_dump(exclude_none=True))
567
567
 
568
568
  def filepath_reputation(
569
569
  self,
@@ -708,7 +708,7 @@ class DomainIntel(ServiceBase):
708
708
  )
709
709
  """
710
710
  input = DomainReputationRequest(domain=domain, verbose=verbose, provider=provider, raw=raw)
711
- return self.request.post("v1/reputation", DomainReputationResult, data=input.dict(exclude_none=True))
711
+ return self.request.post("v1/reputation", DomainReputationResult, data=input.model_dump(exclude_none=True))
712
712
 
713
713
  def reputation_bulk(
714
714
  self,
@@ -744,7 +744,7 @@ class DomainIntel(ServiceBase):
744
744
  )
745
745
  """
746
746
  input = DomainReputationBulkRequest(domains=domains, verbose=verbose, provider=provider, raw=raw)
747
- return self.request.post("v2/reputation", DomainReputationBulkResult, data=input.dict(exclude_none=True))
747
+ return self.request.post("v2/reputation", DomainReputationBulkResult, data=input.model_dump(exclude_none=True))
748
748
 
749
749
  def who_is(
750
750
  self, domain: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
@@ -776,7 +776,7 @@ class DomainIntel(ServiceBase):
776
776
  )
777
777
  """
778
778
  input = DomainWhoIsRequest(domain=domain, verbose=verbose, provider=provider, raw=raw) # type: ignore[call-arg]
779
- return self.request.post("v1/whois", DomainWhoIsResult, data=input.dict(exclude_none=True))
779
+ return self.request.post("v1/whois", DomainWhoIsResult, data=input.model_dump(exclude_none=True))
780
780
 
781
781
 
782
782
  class IpIntel(ServiceBase):
@@ -835,7 +835,7 @@ class IpIntel(ServiceBase):
835
835
  )
836
836
  """
837
837
  input = IPReputationRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
838
- return self.request.post("v1/reputation", IPReputationResult, data=input.dict(exclude_none=True))
838
+ return self.request.post("v1/reputation", IPReputationResult, data=input.model_dump(exclude_none=True))
839
839
 
840
840
  def reputation_bulk(
841
841
  self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
@@ -867,7 +867,7 @@ class IpIntel(ServiceBase):
867
867
  )
868
868
  """
869
869
  input = IPReputationBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
870
- return self.request.post("v2/reputation", IPReputationBulkResult, data=input.dict(exclude_none=True))
870
+ return self.request.post("v2/reputation", IPReputationBulkResult, data=input.model_dump(exclude_none=True))
871
871
 
872
872
  def geolocate(
873
873
  self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
@@ -899,7 +899,7 @@ class IpIntel(ServiceBase):
899
899
  )
900
900
  """
901
901
  input = IPGeolocateRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
902
- return self.request.post("v1/geolocate", IPGeolocateResult, data=input.dict(exclude_none=True))
902
+ return self.request.post("v1/geolocate", IPGeolocateResult, data=input.model_dump(exclude_none=True))
903
903
 
904
904
  def geolocate_bulk(
905
905
  self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
@@ -931,7 +931,7 @@ class IpIntel(ServiceBase):
931
931
  )
932
932
  """
933
933
  input = IPGeolocateBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
934
- return self.request.post("v2/geolocate", IPGeolocateBulkResult, data=input.dict(exclude_none=True))
934
+ return self.request.post("v2/geolocate", IPGeolocateBulkResult, data=input.model_dump(exclude_none=True))
935
935
 
936
936
  def get_domain(
937
937
  self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
@@ -963,7 +963,7 @@ class IpIntel(ServiceBase):
963
963
  )
964
964
  """
965
965
  input = IPDomainRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
966
- return self.request.post("v1/domain", IPDomainResult, data=input.dict(exclude_none=True))
966
+ return self.request.post("v1/domain", IPDomainResult, data=input.model_dump(exclude_none=True))
967
967
 
968
968
  def get_domain_bulk(
969
969
  self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
@@ -995,7 +995,7 @@ class IpIntel(ServiceBase):
995
995
  )
996
996
  """
997
997
  input = IPDomainBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
998
- return self.request.post("v2/domain", IPDomainBulkResult, data=input.dict(exclude_none=True))
998
+ return self.request.post("v2/domain", IPDomainBulkResult, data=input.model_dump(exclude_none=True))
999
999
 
1000
1000
  def is_vpn(
1001
1001
  self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
@@ -1027,7 +1027,7 @@ class IpIntel(ServiceBase):
1027
1027
  )
1028
1028
  """
1029
1029
  input = IPVPNRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
1030
- return self.request.post("v1/vpn", IPVPNResult, data=input.dict(exclude_none=True))
1030
+ return self.request.post("v1/vpn", IPVPNResult, data=input.model_dump(exclude_none=True))
1031
1031
 
1032
1032
  def is_vpn_bulk(
1033
1033
  self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
@@ -1059,7 +1059,7 @@ class IpIntel(ServiceBase):
1059
1059
  )
1060
1060
  """
1061
1061
  input = IPVPNBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
1062
- return self.request.post("v2/vpn", IPVPNBulkResult, data=input.dict(exclude_none=True))
1062
+ return self.request.post("v2/vpn", IPVPNBulkResult, data=input.model_dump(exclude_none=True))
1063
1063
 
1064
1064
  def is_proxy(
1065
1065
  self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
@@ -1091,7 +1091,7 @@ class IpIntel(ServiceBase):
1091
1091
  )
1092
1092
  """
1093
1093
  input = IPProxyRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
1094
- return self.request.post("v1/proxy", IPProxyResult, data=input.dict(exclude_none=True))
1094
+ return self.request.post("v1/proxy", IPProxyResult, data=input.model_dump(exclude_none=True))
1095
1095
 
1096
1096
  def is_proxy_bulk(
1097
1097
  self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
@@ -1123,7 +1123,7 @@ class IpIntel(ServiceBase):
1123
1123
  )
1124
1124
  """
1125
1125
  input = IPProxyBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
1126
- return self.request.post("v2/proxy", IPProxyBulkResult, data=input.dict(exclude_none=True))
1126
+ return self.request.post("v2/proxy", IPProxyBulkResult, data=input.model_dump(exclude_none=True))
1127
1127
 
1128
1128
 
1129
1129
  class UrlIntel(ServiceBase):
@@ -1187,7 +1187,7 @@ class UrlIntel(ServiceBase):
1187
1187
  """
1188
1188
 
1189
1189
  input = URLReputationRequest(url=url, provider=provider, verbose=verbose, raw=raw)
1190
- return self.request.post("v1/reputation", URLReputationResult, data=input.dict(exclude_none=True))
1190
+ return self.request.post("v1/reputation", URLReputationResult, data=input.model_dump(exclude_none=True))
1191
1191
 
1192
1192
  def reputation_bulk(
1193
1193
  self,
@@ -1224,7 +1224,7 @@ class UrlIntel(ServiceBase):
1224
1224
  """
1225
1225
 
1226
1226
  input = URLReputationBulkRequest(urls=urls, provider=provider, verbose=verbose, raw=raw)
1227
- return self.request.post("v2/reputation", URLReputationBulkResult, data=input.dict(exclude_none=True))
1227
+ return self.request.post("v2/reputation", URLReputationBulkResult, data=input.model_dump(exclude_none=True))
1228
1228
 
1229
1229
 
1230
1230
  class UserBreachedRequest(IntelCommonRequest):
@@ -1431,7 +1431,7 @@ class UserIntel(ServiceBase):
1431
1431
  verbose=verbose,
1432
1432
  raw=raw,
1433
1433
  )
1434
- return self.request.post("v1/user/breached", UserBreachedResult, data=input.dict(exclude_none=True))
1434
+ return self.request.post("v1/user/breached", UserBreachedResult, data=input.model_dump(exclude_none=True))
1435
1435
 
1436
1436
  def user_breached_bulk(
1437
1437
  self,
@@ -1490,7 +1490,7 @@ class UserIntel(ServiceBase):
1490
1490
  verbose=verbose,
1491
1491
  raw=raw,
1492
1492
  )
1493
- return self.request.post("v2/user/breached", UserBreachedBulkResult, data=input.dict(exclude_none=True))
1493
+ return self.request.post("v2/user/breached", UserBreachedBulkResult, data=input.model_dump(exclude_none=True))
1494
1494
 
1495
1495
  def password_breached(
1496
1496
  self,
@@ -1532,7 +1532,9 @@ class UserIntel(ServiceBase):
1532
1532
  input = UserPasswordBreachedRequest(
1533
1533
  hash_type=hash_type, hash_prefix=hash_prefix, provider=provider, verbose=verbose, raw=raw
1534
1534
  )
1535
- return self.request.post("v1/password/breached", UserPasswordBreachedResult, data=input.dict(exclude_none=True))
1535
+ return self.request.post(
1536
+ "v1/password/breached", UserPasswordBreachedResult, data=input.model_dump(exclude_none=True)
1537
+ )
1536
1538
 
1537
1539
  def password_breached_bulk(
1538
1540
  self,
@@ -1575,7 +1577,7 @@ class UserIntel(ServiceBase):
1575
1577
  hash_type=hash_type, hash_prefixes=hash_prefixes, provider=provider, verbose=verbose, raw=raw
1576
1578
  )
1577
1579
  return self.request.post(
1578
- "v2/password/breached", UserPasswordBreachedBulkResult, data=input.dict(exclude_none=True)
1580
+ "v2/password/breached", UserPasswordBreachedBulkResult, data=input.model_dump(exclude_none=True)
1579
1581
  )
1580
1582
 
1581
1583
  class PasswordStatus(enum.Enum):
pangea/services/redact.py CHANGED
@@ -265,7 +265,7 @@ class Redact(ServiceBase):
265
265
  return_result=return_result,
266
266
  redaction_method_overrides=redaction_method_overrides,
267
267
  )
268
- return self.request.post("v1/redact", RedactResult, data=input.dict(exclude_none=True))
268
+ return self.request.post("v1/redact", RedactResult, data=input.model_dump(exclude_none=True))
269
269
 
270
270
  def redact_structured(
271
271
  self,
@@ -325,7 +325,7 @@ class Redact(ServiceBase):
325
325
  return_result=return_result,
326
326
  redaction_method_overrides=redaction_method_overrides,
327
327
  )
328
- return self.request.post("v1/redact_structured", StructuredResult, data=input.dict(exclude_none=True))
328
+ return self.request.post("v1/redact_structured", StructuredResult, data=input.model_dump(exclude_none=True))
329
329
 
330
330
  def unredact(self, redacted_data: RedactedData, fpe_context: str) -> PangeaResponse[UnredactResult]:
331
331
  """
@@ -348,4 +348,4 @@ class Redact(ServiceBase):
348
348
  [API Documentation](https://pangea.cloud/docs/api/redact#unredact)
349
349
  """
350
350
  input = UnredactRequest(redacted_data=redacted_data, fpe_context=fpe_context)
351
- return self.request.post("v1/unredact", UnredactResult, data=input.dict(exclude_none=True))
351
+ return self.request.post("v1/unredact", UnredactResult, data=input.model_dump(exclude_none=True))
@@ -18,6 +18,7 @@ from pangea.services.vault.models.common import (
18
18
  class AsymmetricGenerateRequest(CommonGenerateRequest):
19
19
  algorithm: AsymmetricAlgorithm
20
20
  purpose: KeyPurpose
21
+ exportable: Optional[bool] = None
21
22
 
22
23
 
23
24
  class AsymmetricGenerateResult(CommonGenerateResult):
@@ -31,6 +32,7 @@ class AsymmetricStoreRequest(CommonStoreRequest):
31
32
  public_key: EncodedPublicKey
32
33
  private_key: EncodedPrivateKey
33
34
  purpose: KeyPurpose
35
+ exportable: Optional[bool] = None
34
36
 
35
37
 
36
38
  class AsymmetricStoreResult(CommonStoreResult):
@@ -1,10 +1,10 @@
1
1
  # Copyright 2022 Pangea Cyber Corporation
2
2
  # Author: Pangea Cyber Corporation
3
- import datetime
3
+
4
4
  import enum
5
5
  from typing import Dict, Generic, List, NewType, Optional, TypeVar, Union
6
6
 
7
- from pangea.response import APIRequestModel, PangeaResponseResult
7
+ from pangea.response import APIRequestModel, PangeaDateTime, PangeaResponseResult
8
8
 
9
9
  # EncodedPublicKey is a PEM public key, with no further encoding (i.e. no base64)
10
10
  # It may be used for example in openssh with no further processing
@@ -173,6 +173,19 @@ class ItemState(str, enum.Enum):
173
173
  return str(self.value)
174
174
 
175
175
 
176
+ class ExportEncryptionAlgorithm(str, enum.Enum):
177
+ """Algorithm of an exported public key."""
178
+
179
+ RSA4096_OAEP_SHA512 = "RSA-OAEP-4096-SHA512"
180
+ """RSA 4096-bit key, OAEP padding, SHA512 digest."""
181
+
182
+ def __str__(self):
183
+ return str(self.value)
184
+
185
+ def __repr__(self):
186
+ return str(self.value)
187
+
188
+
176
189
  class CommonStoreRequest(APIRequestModel):
177
190
  type: ItemType
178
191
  name: str
@@ -181,7 +194,7 @@ class CommonStoreRequest(APIRequestModel):
181
194
  tags: Optional[Tags] = None
182
195
  rotation_frequency: Optional[str] = None
183
196
  rotation_state: Optional[ItemVersionState] = None
184
- expiration: Optional[datetime.datetime] = None
197
+ expiration: Optional[PangeaDateTime] = None
185
198
 
186
199
 
187
200
  class CommonStoreResult(PangeaResponseResult):
@@ -198,7 +211,7 @@ class CommonGenerateRequest(APIRequestModel):
198
211
  tags: Optional[Tags] = None
199
212
  rotation_frequency: Optional[str] = None
200
213
  rotation_state: Optional[ItemVersionState] = None
201
- expiration: Optional[datetime.datetime] = None
214
+ expiration: Optional[PangeaDateTime] = None
202
215
 
203
216
 
204
217
  class CommonGenerateResult(PangeaResponseResult):
@@ -240,6 +253,8 @@ class ItemData(PangeaResponseResult):
240
253
  created_at: Optional[str] = None
241
254
  algorithm: Optional[str] = None
242
255
  purpose: Optional[str] = None
256
+ exportable: Optional[bool] = None
257
+ """Whether the key is exportable or not."""
243
258
 
244
259
 
245
260
  class InheritedSettings(PangeaResponseResult):
@@ -261,7 +276,7 @@ class ListItemData(ItemData):
261
276
  class ListResult(PangeaResponseResult):
262
277
  items: List[ListItemData] = []
263
278
  count: int
264
- last: Optional[str]
279
+ last: Optional[str] = None
265
280
 
266
281
 
267
282
  class ListRequest(APIRequestModel):
@@ -312,7 +327,7 @@ class UpdateRequest(APIRequestModel):
312
327
  rotation_frequency: Optional[str] = None
313
328
  rotation_state: Optional[ItemVersionState] = None
314
329
  rotation_grace_period: Optional[str] = None
315
- expiration: Optional[datetime.datetime] = None
330
+ expiration: Optional[PangeaDateTime] = None
316
331
  item_state: Optional[ItemState] = None
317
332
 
318
333
 
@@ -542,3 +557,49 @@ class DecryptTransformResult(PangeaResponseResult):
542
557
 
543
558
  plain_text: str
544
559
  """Decrypted message."""
560
+
561
+
562
+ class ExportRequest(APIRequestModel):
563
+ id: str
564
+ """The ID of the item."""
565
+
566
+ version: Optional[int] = None
567
+ """The item version."""
568
+
569
+ encryption_key: Optional[str] = None
570
+ """Public key in pem format used to encrypt exported key(s)."""
571
+
572
+ encryption_algorithm: Optional[ExportEncryptionAlgorithm] = None
573
+ """The algorithm of the public key."""
574
+
575
+
576
+ class ExportResult(PangeaResponseResult):
577
+ id: str
578
+ """The ID of the item."""
579
+
580
+ version: int
581
+ """The item version."""
582
+
583
+ type: str
584
+ """The type of the key."""
585
+
586
+ item_state: str
587
+ """The state of the item."""
588
+
589
+ algorithm: str
590
+ """The algorithm of the key."""
591
+
592
+ public_key: Optional[str] = None
593
+ """The public key (in PEM format)."""
594
+
595
+ private_key: Optional[str] = None
596
+ """The private key (in PEM format)."""
597
+
598
+ key: Optional[str] = None
599
+ """The key material."""
600
+
601
+ encrypted: bool
602
+ """
603
+ Whether exported key(s) are encrypted with encryption_key sent on the request or not.
604
+ If encrypted, the result is sent in base64, any other case they are in PEM format plain text.
605
+ """
@@ -18,6 +18,8 @@ class SymmetricStoreRequest(CommonStoreRequest):
18
18
  key: EncodedSymmetricKey
19
19
  algorithm: SymmetricAlgorithm
20
20
  purpose: KeyPurpose
21
+ exportable: Optional[bool] = None
22
+ """Whether the key is exportable or not."""
21
23
 
22
24
 
23
25
  class SymmetricStoreResult(CommonStoreResult):
@@ -28,6 +30,8 @@ class SymmetricStoreResult(CommonStoreResult):
28
30
  class SymmetricGenerateRequest(CommonGenerateRequest):
29
31
  algorithm: SymmetricAlgorithm
30
32
  purpose: KeyPurpose
33
+ exportable: Optional[bool] = None
34
+ """Whether the key is exportable or not."""
31
35
 
32
36
 
33
37
  class SymmetricGenerateResult(CommonGenerateResult):
@@ -39,7 +43,7 @@ class EncryptRequest(APIRequestModel):
39
43
  id: str
40
44
  plain_text: str
41
45
  version: Optional[int] = None
42
- additional_data: Optional[str]
46
+ additional_data: Optional[str] = None
43
47
 
44
48
 
45
49
  class EncryptResult(PangeaResponseResult):
@@ -53,7 +57,7 @@ class DecryptRequest(APIRequestModel):
53
57
  id: str
54
58
  cipher_text: str
55
59
  version: Optional[int] = None
56
- additional_data: Optional[str]
60
+ additional_data: Optional[str] = None
57
61
 
58
62
 
59
63
  class DecryptResult(PangeaResponseResult):