pangea-sdk 3.8.0b1__py3-none-any.whl → 5.4.0b1__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/__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
|
|