pangea-sdk 3.8.0b1__py3-none-any.whl → 5.4.0b1__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- pangea/__init__.py +1 -1
- pangea/asyncio/file_uploader.py +1 -1
- pangea/asyncio/request.py +56 -34
- pangea/asyncio/services/__init__.py +4 -0
- pangea/asyncio/services/ai_guard.py +75 -0
- pangea/asyncio/services/audit.py +192 -31
- pangea/asyncio/services/authn.py +187 -109
- pangea/asyncio/services/authz.py +285 -0
- pangea/asyncio/services/base.py +21 -2
- pangea/asyncio/services/embargo.py +2 -2
- pangea/asyncio/services/file_scan.py +24 -9
- pangea/asyncio/services/intel.py +108 -34
- pangea/asyncio/services/prompt_guard.py +73 -0
- pangea/asyncio/services/redact.py +72 -4
- pangea/asyncio/services/sanitize.py +217 -0
- pangea/asyncio/services/share.py +246 -73
- pangea/asyncio/services/vault.py +1710 -750
- pangea/crypto/rsa.py +135 -0
- pangea/deep_verify.py +7 -1
- pangea/dump_audit.py +9 -8
- pangea/request.py +87 -59
- pangea/response.py +49 -31
- pangea/services/__init__.py +4 -0
- pangea/services/ai_guard.py +128 -0
- pangea/services/audit/audit.py +205 -42
- pangea/services/audit/models.py +56 -8
- pangea/services/audit/signing.py +6 -5
- pangea/services/audit/util.py +3 -3
- pangea/services/authn/authn.py +140 -70
- pangea/services/authn/models.py +167 -11
- pangea/services/authz.py +400 -0
- pangea/services/base.py +39 -8
- pangea/services/embargo.py +2 -2
- pangea/services/file_scan.py +32 -15
- pangea/services/intel.py +157 -32
- pangea/services/prompt_guard.py +83 -0
- pangea/services/redact.py +152 -4
- pangea/services/sanitize.py +371 -0
- pangea/services/share/share.py +683 -107
- pangea/services/vault/models/asymmetric.py +120 -18
- pangea/services/vault/models/common.py +439 -141
- pangea/services/vault/models/keys.py +94 -0
- pangea/services/vault/models/secret.py +27 -3
- pangea/services/vault/models/symmetric.py +68 -22
- pangea/services/vault/vault.py +1690 -749
- pangea/tools.py +6 -7
- pangea/utils.py +16 -27
- pangea/verify_audit.py +270 -83
- {pangea_sdk-3.8.0b1.dist-info → pangea_sdk-5.4.0b1.dist-info}/METADATA +43 -35
- pangea_sdk-5.4.0b1.dist-info/RECORD +60 -0
- {pangea_sdk-3.8.0b1.dist-info → pangea_sdk-5.4.0b1.dist-info}/WHEEL +1 -1
- pangea_sdk-3.8.0b1.dist-info/RECORD +0 -50
pangea/services/audit/models.py
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
# Copyright 2022 Pangea Cyber Corporation
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
|
+
from __future__ import annotations
|
4
|
+
|
3
5
|
import datetime
|
4
6
|
import enum
|
5
|
-
from typing import Any, Dict, List, Optional, Union
|
7
|
+
from typing import Any, Dict, List, Optional, Sequence, Union
|
6
8
|
|
7
|
-
from pangea.response import APIRequestModel, APIResponseModel, PangeaResponseResult
|
9
|
+
from pangea.response import APIRequestModel, APIResponseModel, PangeaDateTime, PangeaResponseResult
|
8
10
|
|
9
11
|
|
10
12
|
class EventVerification(str, enum.Enum):
|
@@ -19,14 +21,14 @@ class EventVerification(str, enum.Enum):
|
|
19
21
|
return str(self.value)
|
20
22
|
|
21
23
|
|
22
|
-
class Event(
|
24
|
+
class Event(Dict[str, Any]):
|
23
25
|
"""
|
24
26
|
Event to perform an auditable activity
|
25
27
|
|
26
28
|
Auxiliary class to be compatible with older SDKs
|
27
29
|
"""
|
28
30
|
|
29
|
-
def __init__(self, **data):
|
31
|
+
def __init__(self, **data) -> None:
|
30
32
|
super().__init__(**data)
|
31
33
|
|
32
34
|
@property
|
@@ -124,7 +126,7 @@ class EventEnvelope(APIResponseModel):
|
|
124
126
|
event: Dict[str, Any]
|
125
127
|
signature: Optional[str] = None
|
126
128
|
public_key: Optional[str] = None
|
127
|
-
received_at:
|
129
|
+
received_at: PangeaDateTime
|
128
130
|
|
129
131
|
|
130
132
|
class LogRequest(APIRequestModel):
|
@@ -269,6 +271,7 @@ class SearchRequest(APIRequestModel):
|
|
269
271
|
max_results -- Maximum number of results to return.
|
270
272
|
search_restriction -- A list of keys to restrict the search results to. Useful for partitioning data available to the query string.
|
271
273
|
verbose -- If true, include root, membership and consistency proofs in response.
|
274
|
+
return_context -- Return the context data needed to decrypt secure audit events that have been redacted with format preserving encryption.
|
272
275
|
"""
|
273
276
|
|
274
277
|
query: str
|
@@ -279,8 +282,9 @@ class SearchRequest(APIRequestModel):
|
|
279
282
|
end: Optional[str] = None
|
280
283
|
limit: Optional[int] = None
|
281
284
|
max_results: Optional[int] = None
|
282
|
-
search_restriction: Optional[
|
285
|
+
search_restriction: Optional[Dict[str, Sequence[str]]] = None
|
283
286
|
verbose: Optional[bool] = None
|
287
|
+
return_context: Optional[bool] = None
|
284
288
|
|
285
289
|
|
286
290
|
class RootRequest(APIRequestModel):
|
@@ -361,6 +365,7 @@ class SearchEvent(APIResponseModel):
|
|
361
365
|
consistency_verification -- Consistency verification calculated if required.
|
362
366
|
membership_verification -- Membership verification calculated if required.
|
363
367
|
signature_verification -- Signature verification calculated if required.
|
368
|
+
fpe_context -- The context data needed to decrypt secure audit events that have been redacted with format preserving encryption.
|
364
369
|
"""
|
365
370
|
|
366
371
|
envelope: EventEnvelope
|
@@ -371,6 +376,7 @@ class SearchEvent(APIResponseModel):
|
|
371
376
|
consistency_verification: EventVerification = EventVerification.NONE
|
372
377
|
membership_verification: EventVerification = EventVerification.NONE
|
373
378
|
signature_verification: EventVerification = EventVerification.NONE
|
379
|
+
fpe_context: Optional[str] = None
|
374
380
|
|
375
381
|
|
376
382
|
class SearchResultOutput(PangeaResponseResult):
|
@@ -404,7 +410,7 @@ class SearchOutput(SearchResultOutput):
|
|
404
410
|
"""
|
405
411
|
|
406
412
|
id: str
|
407
|
-
expires_at:
|
413
|
+
expires_at: PangeaDateTime
|
408
414
|
|
409
415
|
|
410
416
|
class SearchResultRequest(APIRequestModel):
|
@@ -415,11 +421,15 @@ class SearchResultRequest(APIRequestModel):
|
|
415
421
|
id -- A search results identifier returned by the search call.
|
416
422
|
limit -- Number of audit records to include from the first page of the results.
|
417
423
|
offset -- Offset from the start of the result set to start returning results from.
|
424
|
+
assert_search_restriction -- Assert the requested search results were queried with the exact same search restrictions, to ensure the results comply to the expected restrictions.
|
425
|
+
return_context -- Return the context data needed to decrypt secure audit events that have been redacted with format preserving encryption.
|
418
426
|
"""
|
419
427
|
|
420
428
|
id: str
|
421
429
|
limit: Optional[int] = 20
|
422
430
|
offset: Optional[int] = 0
|
431
|
+
assert_search_restriction: Optional[Dict[str, Sequence[str]]] = None
|
432
|
+
return_context: Optional[bool] = None
|
423
433
|
|
424
434
|
|
425
435
|
class DownloadFormat(str, enum.Enum):
|
@@ -437,13 +447,51 @@ class DownloadFormat(str, enum.Enum):
|
|
437
447
|
|
438
448
|
|
439
449
|
class DownloadRequest(APIRequestModel):
|
440
|
-
|
450
|
+
request_id: Optional[str] = None
|
451
|
+
"""ID returned by the export API."""
|
452
|
+
|
453
|
+
result_id: Optional[str] = None
|
441
454
|
"""ID returned by the search API."""
|
442
455
|
|
443
456
|
format: Optional[str] = None
|
444
457
|
"""Format for the records."""
|
445
458
|
|
459
|
+
return_context: Optional[bool] = None
|
460
|
+
"""Return the context data needed to decrypt secure audit events that have been redacted with format preserving encryption."""
|
461
|
+
|
446
462
|
|
447
463
|
class DownloadResult(PangeaResponseResult):
|
448
464
|
dest_url: str
|
449
465
|
"""URL where search results can be downloaded."""
|
466
|
+
|
467
|
+
expires_at: str
|
468
|
+
"""
|
469
|
+
The time when the results will no longer be available to page through via
|
470
|
+
the results API.
|
471
|
+
"""
|
472
|
+
|
473
|
+
|
474
|
+
class ExportRequest(APIRequestModel):
|
475
|
+
format: DownloadFormat = DownloadFormat.CSV
|
476
|
+
"""Format for the records."""
|
477
|
+
|
478
|
+
start: Optional[datetime.datetime] = None
|
479
|
+
"""The start of the time range to perform the search on."""
|
480
|
+
|
481
|
+
end: Optional[datetime.datetime] = None
|
482
|
+
"""
|
483
|
+
The end of the time range to perform the search on. If omitted, then all
|
484
|
+
records up to the latest will be searched.
|
485
|
+
"""
|
486
|
+
|
487
|
+
order_by: Optional[str] = None
|
488
|
+
"""Name of column to sort the results by."""
|
489
|
+
|
490
|
+
order: Optional[SearchOrder] = None
|
491
|
+
"""Specify the sort order of the response."""
|
492
|
+
|
493
|
+
verbose: bool = True
|
494
|
+
"""
|
495
|
+
Whether or not to include the root hash of the tree and the membership proof
|
496
|
+
for each record.
|
497
|
+
"""
|
pangea/services/audit/signing.py
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# Copyright 2022 Pangea Cyber Corporation
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
|
+
from __future__ import annotations
|
4
|
+
|
3
5
|
from abc import ABC, abstractmethod
|
4
6
|
from typing import Optional
|
5
7
|
|
@@ -10,7 +12,7 @@ from cryptography.hazmat.primitives.asymmetric.types import PrivateKeyTypes, Pub
|
|
10
12
|
|
11
13
|
from pangea.exceptions import PangeaException
|
12
14
|
from pangea.services.audit.util import b64decode, b64decode_ascii, b64encode_ascii
|
13
|
-
from pangea.services.vault.models.
|
15
|
+
from pangea.services.vault.models.asymmetric import AsymmetricKeySigningAlgorithm
|
14
16
|
|
15
17
|
|
16
18
|
class AlgorithmSigner(ABC):
|
@@ -43,7 +45,7 @@ class ED25519Signer(AlgorithmSigner):
|
|
43
45
|
)
|
44
46
|
|
45
47
|
def get_algorithm(self) -> str:
|
46
|
-
return
|
48
|
+
return AsymmetricKeySigningAlgorithm.ED25519.value
|
47
49
|
|
48
50
|
|
49
51
|
signers = {
|
@@ -96,7 +98,7 @@ class Signer:
|
|
96
98
|
|
97
99
|
for func in (serialization.load_pem_private_key, serialization.load_ssh_private_key):
|
98
100
|
try:
|
99
|
-
return func(private_key, None)
|
101
|
+
return func(private_key, None)
|
100
102
|
except exceptions.UnsupportedAlgorithm as e:
|
101
103
|
raise e
|
102
104
|
except ValueError:
|
@@ -144,8 +146,7 @@ class Verifier:
|
|
144
146
|
for cls, verifier in verifiers.items():
|
145
147
|
if isinstance(pubkey, cls):
|
146
148
|
return verifier(pubkey).verify(message_bytes, signature_bytes)
|
147
|
-
|
148
|
-
raise PangeaException(f"Not supported public key type: {type(pubkey)}")
|
149
|
+
raise PangeaException(f"Not supported public key type: {type(pubkey)}")
|
149
150
|
|
150
151
|
def _decode_public_key(self, public_key: bytes):
|
151
152
|
"""Parse a public key in PEM or ssh format"""
|
pangea/services/audit/util.py
CHANGED
@@ -7,7 +7,7 @@ from binascii import hexlify, unhexlify
|
|
7
7
|
from dataclasses import dataclass
|
8
8
|
from datetime import datetime
|
9
9
|
from hashlib import sha256
|
10
|
-
from typing import Dict, List, Optional
|
10
|
+
from typing import Collection, Dict, List, Optional
|
11
11
|
|
12
12
|
import requests
|
13
13
|
|
@@ -61,7 +61,7 @@ def verify_hash(hash1: str, hash2: str) -> bool:
|
|
61
61
|
|
62
62
|
|
63
63
|
def verify_envelope_hash(envelope: EventEnvelope, hash: str):
|
64
|
-
return verify_hash(hash_dict(normalize_log(envelope.
|
64
|
+
return verify_hash(hash_dict(normalize_log(envelope.model_dump(exclude_none=True))), hash)
|
65
65
|
|
66
66
|
|
67
67
|
def canonicalize_event(event: Event) -> bytes:
|
@@ -192,7 +192,7 @@ def arweave_graphql_url():
|
|
192
192
|
return f"{ARWEAVE_BASE_URL}/graphql"
|
193
193
|
|
194
194
|
|
195
|
-
def get_arweave_published_roots(tree_name: str, tree_sizes:
|
195
|
+
def get_arweave_published_roots(tree_name: str, tree_sizes: Collection[int]) -> Dict[int, PublishedRoot]:
|
196
196
|
if len(tree_sizes) == 0:
|
197
197
|
return {}
|
198
198
|
|