pangea-sdk 6.1.1__py3-none-any.whl → 6.2.0b2__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 (54) hide show
  1. pangea/__init__.py +9 -1
  2. pangea/asyncio/__init__.py +1 -0
  3. pangea/asyncio/file_uploader.py +4 -2
  4. pangea/asyncio/request.py +199 -35
  5. pangea/asyncio/services/__init__.py +3 -0
  6. pangea/asyncio/services/ai_guard.py +91 -2
  7. pangea/asyncio/services/audit.py +307 -2
  8. pangea/asyncio/services/authn.py +12 -2
  9. pangea/asyncio/services/base.py +4 -0
  10. pangea/asyncio/services/file_scan.py +7 -1
  11. pangea/asyncio/services/intel.py +6 -2
  12. pangea/asyncio/services/management.py +576 -0
  13. pangea/asyncio/services/prompt_guard.py +112 -2
  14. pangea/asyncio/services/redact.py +269 -4
  15. pangea/asyncio/services/sanitize.py +5 -1
  16. pangea/asyncio/services/share.py +5 -1
  17. pangea/asyncio/services/vault.py +4 -0
  18. pangea/audit_logger.py +3 -1
  19. pangea/deep_verify.py +13 -13
  20. pangea/deprecated.py +1 -1
  21. pangea/dump_audit.py +2 -3
  22. pangea/exceptions.py +8 -5
  23. pangea/file_uploader.py +4 -0
  24. pangea/request.py +205 -52
  25. pangea/response.py +15 -12
  26. pangea/services/__init__.py +3 -0
  27. pangea/services/ai_guard.py +497 -16
  28. pangea/services/audit/audit.py +310 -8
  29. pangea/services/audit/models.py +279 -0
  30. pangea/services/audit/signing.py +1 -1
  31. pangea/services/audit/util.py +10 -10
  32. pangea/services/authn/authn.py +12 -2
  33. pangea/services/authn/models.py +3 -0
  34. pangea/services/authz.py +4 -0
  35. pangea/services/base.py +5 -1
  36. pangea/services/embargo.py +6 -0
  37. pangea/services/file_scan.py +7 -1
  38. pangea/services/intel.py +4 -0
  39. pangea/services/management.py +720 -0
  40. pangea/services/prompt_guard.py +193 -2
  41. pangea/services/redact.py +477 -7
  42. pangea/services/sanitize.py +5 -1
  43. pangea/services/share/share.py +13 -7
  44. pangea/services/vault/models/asymmetric.py +4 -0
  45. pangea/services/vault/models/common.py +4 -0
  46. pangea/services/vault/models/symmetric.py +4 -0
  47. pangea/services/vault/vault.py +2 -4
  48. pangea/tools.py +13 -9
  49. pangea/utils.py +3 -5
  50. pangea/verify_audit.py +23 -27
  51. {pangea_sdk-6.1.1.dist-info → pangea_sdk-6.2.0b2.dist-info}/METADATA +4 -4
  52. pangea_sdk-6.2.0b2.dist-info/RECORD +62 -0
  53. pangea_sdk-6.1.1.dist-info/RECORD +0 -60
  54. {pangea_sdk-6.1.1.dist-info → pangea_sdk-6.2.0b2.dist-info}/WHEEL +0 -0
@@ -1,16 +1,25 @@
1
1
  # Copyright 2022 Pangea Cyber Corporation
2
2
  # Author: Pangea Cyber Corporation
3
+
4
+ # TODO: Modernize.
5
+ # ruff: noqa: UP006, UP035
6
+
3
7
  from __future__ import annotations
4
8
 
5
9
  import datetime
6
10
  import json
7
- from typing import Any, Dict, Iterable, List, Optional, Sequence, Set, Tuple, Union
11
+ from collections.abc import Mapping
12
+ from typing import Any, Dict, Iterable, List, Optional, Sequence, Set, Tuple, Union, cast, overload
13
+
14
+ from pydantic import TypeAdapter
15
+ from typing_extensions import Literal
8
16
 
9
17
  import pangea.exceptions as pexc
10
18
  from pangea.config import PangeaConfig
11
19
  from pangea.response import PangeaResponse, PangeaResponseResult
12
20
  from pangea.services.audit.exceptions import AuditException, EventCorruption
13
21
  from pangea.services.audit.models import (
22
+ AuditSchema,
14
23
  DownloadFormat,
15
24
  DownloadRequest,
16
25
  DownloadResult,
@@ -18,6 +27,7 @@ from pangea.services.audit.models import (
18
27
  EventEnvelope,
19
28
  EventVerification,
20
29
  ExportRequest,
30
+ ForwardingConfiguration,
21
31
  LogBulkRequest,
22
32
  LogBulkResult,
23
33
  LogEvent,
@@ -35,6 +45,9 @@ from pangea.services.audit.models import (
35
45
  SearchRequest,
36
46
  SearchResultOutput,
37
47
  SearchResultRequest,
48
+ ServiceConfig,
49
+ ServiceConfigFilter,
50
+ ServiceConfigListResult,
38
51
  )
39
52
  from pangea.services.audit.signing import Signer, Verifier
40
53
  from pangea.services.audit.util import (
@@ -55,7 +68,7 @@ from pangea.utils import canonicalize_nested_json
55
68
 
56
69
  class AuditBase:
57
70
  def __init__(
58
- self, private_key_file: str = "", public_key_info: dict[str, str] = {}, tenant_id: str | None = None
71
+ self, private_key_file: str = "", public_key_info: Mapping[str, str] = {}, tenant_id: str | None = None
59
72
  ) -> None:
60
73
  self.pub_roots: Dict[int, PublishedRoot] = {}
61
74
  self.buffer_data: Optional[str] = None
@@ -90,7 +103,7 @@ class AuditBase:
90
103
  return input # type: ignore[return-value]
91
104
 
92
105
  def _process_log(self, event: dict, sign_local: bool) -> LogEvent:
93
- if event.get("tenant_id", None) is None and self.tenant_id:
106
+ if event.get("tenant_id") is None and self.tenant_id:
94
107
  event["tenant_id"] = self.tenant_id
95
108
 
96
109
  event = {k: v for k, v in event.items() if v is not None}
@@ -221,10 +234,7 @@ class AuditBase:
221
234
  tree_sizes.add(result.root.size)
222
235
  tree_sizes.difference_update(self.pub_roots.keys())
223
236
 
224
- if tree_sizes:
225
- arweave_roots = get_arweave_published_roots(result.root.tree_name, tree_sizes)
226
- else:
227
- arweave_roots = {}
237
+ arweave_roots = get_arweave_published_roots(result.root.tree_name, tree_sizes) if tree_sizes else {}
228
238
 
229
239
  return tree_sizes, arweave_roots
230
240
 
@@ -385,7 +395,7 @@ class Audit(ServiceBase, AuditBase):
385
395
  token: str,
386
396
  config: PangeaConfig | None = None,
387
397
  private_key_file: str = "",
388
- public_key_info: dict[str, str] = {},
398
+ public_key_info: Mapping[str, str] = {},
389
399
  tenant_id: str | None = None,
390
400
  logger_name: str = "pangea",
391
401
  config_id: str | None = None,
@@ -919,6 +929,298 @@ class Audit(ServiceBase, AuditBase):
919
929
  )
920
930
  return self.request.post("v1/download_results", DownloadResult, data=input.model_dump(exclude_none=True))
921
931
 
932
+ def get_service_config(self, config_id: str) -> PangeaResponse[ServiceConfig]:
933
+ """
934
+ Get a service config.
935
+
936
+ OperationId: audit_post_v1beta_config
937
+
938
+ Args:
939
+ id: The config ID
940
+ """
941
+
942
+ response = self.request.post("v1beta/config", PangeaResponseResult, data={"id": config_id})
943
+ response.result = TypeAdapter(ServiceConfig).validate_python(response.json["result"])
944
+ return cast(PangeaResponse[ServiceConfig], response)
945
+
946
+ @overload
947
+ def create_service_config(
948
+ self,
949
+ version: Literal[1],
950
+ name: str,
951
+ *,
952
+ cold_query_result_retention: str | None = None,
953
+ hot_storage: str | None = None,
954
+ query_result_retention: str | None = None,
955
+ redact_service_config_id: str | None = None,
956
+ redaction_fields: Sequence[str] | None = None,
957
+ retention: str | None = None,
958
+ vault_key_id: str | None = None,
959
+ vault_service_config_id: str | None = None,
960
+ vault_sign: bool | None = None,
961
+ ) -> PangeaResponse[ServiceConfig]:
962
+ """
963
+ Create a v1 service config.
964
+
965
+ OperationId: audit_post_v1beta_config_create
966
+
967
+ Args:
968
+ name: Configuration name
969
+ cold_query_result_retention: Retention window for cold query result / state information.
970
+ hot_storage: Retention window to keep audit logs in hot storage.
971
+ query_result_retention: Length of time to preserve server-side query result caching.
972
+ redact_service_config_id: A redact service config that will be used to redact PII from logs.
973
+ redaction_fields: Fields to perform redaction against.
974
+ retention: Retention window to store audit logs.
975
+ vault_key_id: ID of the Vault key used for signing. If missing, use a default Audit key.
976
+ vault_service_config_id: A vault service config that will be used to sign logs.
977
+ vault_sign: Enable/disable event signing.
978
+ """
979
+
980
+ @overload
981
+ def create_service_config(
982
+ self,
983
+ version: Literal[2],
984
+ name: str,
985
+ *,
986
+ schema: AuditSchema,
987
+ cold_query_result_retention: str | None = None,
988
+ forwarding_configuration: ForwardingConfiguration | None = None,
989
+ hot_storage: str | None = None,
990
+ query_result_retention: str | None = None,
991
+ redact_service_config_id: str | None = None,
992
+ retention: str | None = None,
993
+ vault_key_id: str | None = None,
994
+ vault_service_config_id: str | None = None,
995
+ vault_sign: bool | None = None,
996
+ ) -> PangeaResponse[ServiceConfig]:
997
+ """
998
+ Create a v2 service config.
999
+
1000
+ OperationId: audit_post_v1beta_config_create
1001
+
1002
+ Args:
1003
+ name: Configuration name
1004
+ schema: Audit log field configuration. Only settable at create time.
1005
+ cold_query_result_retention: Retention window for cold query result / state information.
1006
+ forwarding_configuration: Configuration for forwarding audit logs to external systems.
1007
+ hot_storage: Retention window to keep audit logs in hot storage.
1008
+ query_result_retention: Length of time to preserve server-side query result caching.
1009
+ redact_service_config_id: A redact service config that will be used to redact PII from logs.
1010
+ retention: Retention window to store audit logs.
1011
+ vault_key_id: ID of the Vault key used for signing. If missing, use a default Audit key.
1012
+ vault_service_config_id: A vault service config that will be used to sign logs.
1013
+ vault_sign: Enable/disable event signing.
1014
+ """
1015
+
1016
+ @overload
1017
+ def create_service_config(
1018
+ self,
1019
+ version: Literal[3],
1020
+ name: str,
1021
+ *,
1022
+ schema: AuditSchema,
1023
+ cold_storage: str | None = None,
1024
+ hot_storage: str | None = None,
1025
+ warm_storage: str | None = None,
1026
+ redact_service_config_id: str | None = None,
1027
+ vault_service_config_id: str | None = None,
1028
+ vault_key_id: str | None = None,
1029
+ vault_sign: bool | None = None,
1030
+ forwarding_configuration: ForwardingConfiguration | None = None,
1031
+ ) -> PangeaResponse[ServiceConfig]:
1032
+ """
1033
+ Create a v3 service config.
1034
+
1035
+ OperationId: audit_post_v1beta_config_create
1036
+
1037
+ Args:
1038
+ name: Configuration name
1039
+ schema: Audit log field configuration. Only settable at create time.
1040
+ cold_storage: Retention window for logs in cold storage. Deleted afterwards.
1041
+ hot_storage: Retention window for logs in hot storage. Migrated to warm, cold, or deleted afterwards.
1042
+ warm_storage: Retention window for logs in warm storage. Migrated to cold or deleted afterwards.
1043
+ redact_service_config_id: A redact service config that will be used to redact PII from logs.
1044
+ vault_service_config_id: A vault service config that will be used to sign logs.
1045
+ vault_key_id: ID of the Vault key used for signing. If missing, use a default Audit key.
1046
+ vault_sign: Enable/disable event signing.
1047
+ forwarding_configuration: Configuration for forwarding audit logs to external systems.
1048
+ """
1049
+
1050
+ def create_service_config(
1051
+ self,
1052
+ version: Literal[1, 2, 3],
1053
+ name: str,
1054
+ *,
1055
+ cold_query_result_retention: str | None = None,
1056
+ cold_storage: str | None = None,
1057
+ forwarding_configuration: ForwardingConfiguration | None = None,
1058
+ hot_storage: str | None = None,
1059
+ query_result_retention: str | None = None,
1060
+ redact_service_config_id: str | None = None,
1061
+ redaction_fields: Sequence[str] | None = None,
1062
+ retention: str | None = None,
1063
+ schema: AuditSchema | None = None,
1064
+ vault_key_id: str | None = None,
1065
+ vault_service_config_id: str | None = None,
1066
+ vault_sign: bool | None = None,
1067
+ warm_storage: str | None = None,
1068
+ ) -> PangeaResponse[ServiceConfig]:
1069
+ """
1070
+ Create a service config.
1071
+
1072
+ OperationId: audit_post_v1beta_config_create
1073
+
1074
+ Args:
1075
+ name: Configuration name
1076
+ cold_query_result_retention: Retention window for cold query result / state information.
1077
+ cold_storage: Retention window for logs in cold storage. Deleted afterwards.
1078
+ forwarding_configuration: Configuration for forwarding audit logs to external systems.
1079
+ hot_storage: Retention window to keep audit logs in hot storage.
1080
+ query_result_retention: Length of time to preserve server-side query result caching.
1081
+ redact_service_config_id: A redact service config that will be used to redact PII from logs.
1082
+ redaction_fields: Fields to perform redaction against.
1083
+ retention: Retention window to store audit logs.
1084
+ schema: Audit log field configuration. Only settable at create time.
1085
+ vault_key_id: ID of the Vault key used for signing. If missing, use a default Audit key.
1086
+ vault_service_config_id: A vault service config that will be used to sign logs.
1087
+ vault_sign: Enable/disable event signing.
1088
+ warm_storage: Retention window for logs in warm storage. Migrated to cold or deleted afterwards.
1089
+ """
1090
+
1091
+ response = self.request.post(
1092
+ "v1beta/config/create",
1093
+ PangeaResponseResult,
1094
+ data={
1095
+ "cold_query_result_retention": cold_query_result_retention,
1096
+ "cold_storage": cold_storage,
1097
+ "forwarding_configuration": forwarding_configuration,
1098
+ "hot_storage": hot_storage,
1099
+ "name": name,
1100
+ "query_result_retention": query_result_retention,
1101
+ "redact_service_config_id": redact_service_config_id,
1102
+ "redaction_fields": redaction_fields,
1103
+ "retention": retention,
1104
+ "schema": schema,
1105
+ "vault_key_id": vault_key_id,
1106
+ "vault_service_config_id": vault_service_config_id,
1107
+ "vault_sign": vault_sign,
1108
+ "warm_storage": warm_storage,
1109
+ "version": version,
1110
+ },
1111
+ )
1112
+ response.result = TypeAdapter(ServiceConfig).validate_python(response.json["result"])
1113
+ return cast(PangeaResponse[ServiceConfig], response)
1114
+
1115
+ def update_service_config(
1116
+ self,
1117
+ config_id: str,
1118
+ *,
1119
+ name: str,
1120
+ updated_at: datetime.datetime,
1121
+ # Optionals.
1122
+ cold_query_result_retention: str | None = None,
1123
+ cold_storage: str | None = None,
1124
+ forwarding_configuration: ForwardingConfiguration | None = None,
1125
+ hot_storage: str | None = None,
1126
+ query_result_retention: str | None = None,
1127
+ redact_service_config_id: str | None = None,
1128
+ retention: str | None = None,
1129
+ schema: AuditSchema | None = None,
1130
+ vault_key_id: str | None = None,
1131
+ vault_service_config_id: str | None = None,
1132
+ vault_sign: bool | None = None,
1133
+ warm_storage: str | None = None,
1134
+ ) -> PangeaResponse[ServiceConfig]:
1135
+ """
1136
+ Update a service config.
1137
+
1138
+ OperationId: audit_post_v1beta_config_update
1139
+
1140
+ Args:
1141
+ id: The config ID
1142
+ name: Configuration name
1143
+ updated_at: The DB timestamp when this config was last updated at
1144
+ cold_query_result_retention: Retention window for cold query result / state information.
1145
+ cold_storage: Retention window for logs in cold storage. Deleted afterwards.
1146
+ forwarding_configuration: Configuration for forwarding audit logs to external systems
1147
+ hot_storage: Retention window to keep audit logs in hot storage
1148
+ query_result_retention: Length of time to preserve server-side query result caching
1149
+ redact_service_config_id: A redact service config that will be used to redact PII from logs
1150
+ retention: Retention window to store audit logs
1151
+ schema: Audit log field configuration
1152
+ vault_key_id: ID of the Vault key used for signing. If missing, use a default Audit key.
1153
+ vault_service_config_id: A vault service config that will be used to sign logs
1154
+ vault_sign: Enable/disable event signing
1155
+ warm_storage: Retention window for logs in warm storage. Migrated to cold or deleted afterwards.
1156
+ """
1157
+
1158
+ response = self.request.post(
1159
+ "v1beta/config/update",
1160
+ PangeaResponseResult,
1161
+ data={
1162
+ "id": config_id,
1163
+ "name": name,
1164
+ "updated_at": updated_at,
1165
+ # Optionals.
1166
+ "cold_query_result_retention": cold_query_result_retention,
1167
+ "cold_storage": cold_storage,
1168
+ "forwarding_configuration": forwarding_configuration,
1169
+ "hot_storage": hot_storage,
1170
+ "query_result_retention": query_result_retention,
1171
+ "redact_service_config_id": redact_service_config_id,
1172
+ "retention": retention,
1173
+ "schema": schema,
1174
+ "vault_key_id": vault_key_id,
1175
+ "vault_service_config_id": vault_service_config_id,
1176
+ "vault_sign": vault_sign,
1177
+ "warm_storage": warm_storage,
1178
+ },
1179
+ )
1180
+ response.result = TypeAdapter(ServiceConfig).validate_python(response.json["result"])
1181
+ return cast(PangeaResponse[ServiceConfig], response)
1182
+
1183
+ def delete_service_config(self, config_id: str) -> PangeaResponse[ServiceConfig]:
1184
+ """
1185
+ Delete a service config.
1186
+
1187
+ OperationId: audit_post_v1beta_config_delete
1188
+
1189
+ Args:
1190
+ id: The config ID
1191
+ """
1192
+
1193
+ response = self.request.post("v1beta/config/delete", PangeaResponseResult, data={"id": config_id})
1194
+ response.result = TypeAdapter(ServiceConfig).validate_python(response.json["result"])
1195
+ return cast(PangeaResponse[ServiceConfig], response)
1196
+
1197
+ def list_service_configs(
1198
+ self,
1199
+ *,
1200
+ filter: ServiceConfigFilter | None = None,
1201
+ last: str | None = None,
1202
+ order: Literal["asc", "desc"] | None = None,
1203
+ order_by: Literal["id", "created_at", "updated_at"] | None = None,
1204
+ size: int | None = None,
1205
+ ) -> PangeaResponse[ServiceConfigListResult]:
1206
+ """
1207
+ List service configs.
1208
+
1209
+ OperationId: audit_post_v1beta_config_list
1210
+
1211
+ Args:
1212
+ last: Reflected value from a previous response to obtain the next page of results.
1213
+ order: Order results asc(ending) or desc(ending).
1214
+ order_by: Which field to order results by.
1215
+ size: Maximum results to include in the response.
1216
+ """
1217
+
1218
+ return self.request.post(
1219
+ "v1beta/config/list",
1220
+ ServiceConfigListResult,
1221
+ data={"filter": filter, "last": last, "order": order, "order_by": order_by, "size": size},
1222
+ )
1223
+
922
1224
  def update_published_roots(self, result: SearchResultOutput):
923
1225
  """Fetches series of published root hashes from Arweave
924
1226
 
@@ -1,11 +1,18 @@
1
1
  # Copyright 2022 Pangea Cyber Corporation
2
2
  # Author: Pangea Cyber Corporation
3
+
4
+ # TODO: Modernize.
5
+ # ruff: noqa: UP006, UP035
6
+
3
7
  from __future__ import annotations
4
8
 
5
9
  import datetime
6
10
  import enum
7
11
  from typing import Any, Dict, List, Optional, Sequence, Union
8
12
 
13
+ from pydantic import Field
14
+ from typing_extensions import Annotated, Literal
15
+
9
16
  from pangea.response import APIRequestModel, APIResponseModel, PangeaDateTime, PangeaResponseResult
10
17
 
11
18
 
@@ -495,3 +502,275 @@ class ExportRequest(APIRequestModel):
495
502
  Whether or not to include the root hash of the tree and the membership proof
496
503
  for each record.
497
504
  """
505
+
506
+
507
+ class AuditSchemaField(APIResponseModel):
508
+ """A description of a field in an audit log."""
509
+
510
+ id: str
511
+ """Prefix name / identity for the field."""
512
+
513
+ type: Literal["boolean", "datetime", "integer", "string", "string-unindexed", "text"]
514
+ """The data type for the field."""
515
+
516
+ description: Optional[str] = None
517
+ """Human display description of the field."""
518
+
519
+ name: Optional[str] = None
520
+ """Human display name/title of the field."""
521
+
522
+ redact: Optional[bool] = None
523
+ """If true, redaction is performed against this field (if configured.) Only valid for string type."""
524
+
525
+ required: Optional[bool] = None
526
+ """If true, this field is required to exist in all logged events."""
527
+
528
+ size: Optional[int] = None
529
+ """The maximum size of the field. Only valid for strings, which limits number of UTF-8 characters."""
530
+
531
+ ui_default_visible: Optional[bool] = None
532
+ """If true, this field is visible by default in audit UIs."""
533
+
534
+
535
+ class AuditSchema(APIResponseModel):
536
+ """A description of acceptable fields for an audit log."""
537
+
538
+ client_signable: Optional[bool] = None
539
+ """If true, records contain fields to support client/vault signing."""
540
+
541
+ save_malformed: Optional[str] = None
542
+ """Save (or reject) malformed AuditEvents."""
543
+
544
+ tamper_proofing: Optional[bool] = None
545
+ """If true, records contain fields to support tamper-proofing."""
546
+
547
+ fields: Optional[List[AuditSchemaField]] = None
548
+ """List of field definitions."""
549
+
550
+
551
+ class ForwardingConfiguration(APIResponseModel):
552
+ """Configuration for forwarding audit logs to external systems."""
553
+
554
+ type: str
555
+ """Type of forwarding configuration."""
556
+
557
+ forwarding_enabled: Optional[bool] = False
558
+ """Whether forwarding is enabled."""
559
+
560
+ event_url: Optional[str] = None
561
+ """URL where events will be written to. Must use HTTPS."""
562
+
563
+ ack_url: Optional[str] = None
564
+ """If indexer acknowledgement is required, this must be provided along with a 'channel_id'."""
565
+
566
+ channel_id: Optional[str] = None
567
+ """An optional splunk channel included in each request if indexer acknowledgement is required."""
568
+
569
+ public_cert: Optional[str] = None
570
+ """Public certificate if a self signed TLS cert is being used."""
571
+
572
+ index: Optional[str] = None
573
+ """Optional splunk index passed in the record bodies."""
574
+
575
+ vault_config_id: Optional[str] = None
576
+ """The vault config used to store the HEC token."""
577
+
578
+ vault_secret_id: Optional[str] = None
579
+ """The secret ID where the HEC token is stored in vault."""
580
+
581
+
582
+ class ServiceConfigV1(PangeaResponseResult):
583
+ """Configuration options available for audit service"""
584
+
585
+ id: Optional[str] = None
586
+ """The config ID"""
587
+
588
+ version: Literal[1] = 1
589
+
590
+ created_at: Optional[str] = None
591
+ """The DB timestamp when this config was created. Ignored when submitted."""
592
+
593
+ updated_at: Optional[str] = None
594
+ """The DB timestamp when this config was last updated at"""
595
+
596
+ name: Optional[str] = None
597
+ """Configuration name"""
598
+
599
+ retention: Optional[str] = None
600
+ """Retention window to store audit logs."""
601
+
602
+ cold_query_result_retention: Optional[str] = None
603
+ """Retention window for cold query result / state information."""
604
+
605
+ hot_storage: Optional[str] = None
606
+ """Retention window to keep audit logs in hot storage."""
607
+
608
+ query_result_retention: Optional[str] = None
609
+ """Length of time to preserve server-side query result caching."""
610
+
611
+ redact_service_config_id: Optional[str] = None
612
+ """A redact service config that will be used to redact PII from logs."""
613
+
614
+ redaction_fields: Optional[List[str]] = None
615
+ """Fields to perform redaction against."""
616
+
617
+ vault_service_config_id: Optional[str] = None
618
+ """A vault service config that will be used to sign logs."""
619
+
620
+ vault_key_id: Optional[str] = None
621
+ """ID of the Vault key used for signing. If missing, use a default Audit key"""
622
+
623
+ vault_sign: Optional[bool] = None
624
+ """Enable/disable event signing"""
625
+
626
+
627
+ class ServiceConfigV2(PangeaResponseResult):
628
+ """Configuration options available for audit service"""
629
+
630
+ audit_schema: AuditSchema = Field(alias="schema")
631
+ """Audit log field configuration. Only settable at create time."""
632
+
633
+ version: Literal[2] = 2
634
+
635
+ cold_query_result_retention: Optional[str] = None
636
+ """Retention window for cold query result / state information."""
637
+
638
+ created_at: Optional[str] = None
639
+ """The DB timestamp when this config was created. Ignored when submitted."""
640
+
641
+ hot_storage: Optional[str] = None
642
+ """Retention window to keep audit logs in hot storage."""
643
+
644
+ id: Optional[str] = None
645
+ """The config ID"""
646
+
647
+ name: Optional[str] = None
648
+ """Configuration name"""
649
+
650
+ query_result_retention: Optional[str] = None
651
+ """Length of time to preserve server-side query result caching."""
652
+
653
+ redact_service_config_id: Optional[str] = None
654
+ """A redact service config that will be used to redact PII from logs."""
655
+
656
+ retention: Optional[str] = None
657
+ """Retention window to store audit logs."""
658
+
659
+ updated_at: Optional[str] = None
660
+ """The DB timestamp when this config was last updated at"""
661
+
662
+ vault_key_id: Optional[str] = None
663
+ """ID of the Vault key used for signing. If missing, use a default Audit key"""
664
+
665
+ vault_service_config_id: Optional[str] = None
666
+ """A vault service config that will be used to sign logs."""
667
+
668
+ vault_sign: Optional[bool] = None
669
+ """Enable/disable event signing"""
670
+
671
+ forwarding_configuration: Optional[ForwardingConfiguration] = None
672
+ """Configuration for forwarding audit logs to external systems."""
673
+
674
+
675
+ class ServiceConfigV3(PangeaResponseResult):
676
+ """Configuration options available for audit service"""
677
+
678
+ audit_schema: AuditSchema = Field(alias="schema")
679
+ """Audit log field configuration. Only settable at create time."""
680
+
681
+ version: Literal[3] = 3
682
+ """Version of the service config."""
683
+
684
+ cold_storage: Optional[str] = None
685
+ """Retention window for logs in cold storage. Deleted afterwards."""
686
+
687
+ created_at: Optional[str] = None
688
+ """The DB timestamp when this config was created. Ignored when submitted."""
689
+
690
+ forwarding_configuration: Optional[ForwardingConfiguration] = None
691
+ """Configuration for forwarding audit logs to external systems."""
692
+
693
+ hot_storage: Optional[str] = None
694
+ """Retention window for logs in hot storage. Migrated to warm, cold, or deleted afterwards."""
695
+
696
+ id: Optional[str] = None
697
+ """The config ID"""
698
+
699
+ name: Optional[str] = None
700
+ """Configuration name"""
701
+
702
+ redact_service_config_id: Optional[str] = None
703
+ """A redact service config that will be used to redact PII from logs."""
704
+
705
+ updated_at: Optional[str] = None
706
+ """The DB timestamp when this config was last updated at"""
707
+
708
+ vault_key_id: Optional[str] = None
709
+ """ID of the Vault key used for signing. If missing, use a default Audit key"""
710
+
711
+ vault_service_config_id: Optional[str] = None
712
+ """A vault service config that will be used to sign logs."""
713
+
714
+ vault_sign: Optional[bool] = None
715
+ """Enable/disable event signing"""
716
+
717
+ warm_storage: Optional[str] = None
718
+ """Retention window for logs in warm storage. Migrated to cold or deleted afterwards."""
719
+
720
+
721
+ ServiceConfig = Annotated[
722
+ Union[ServiceConfigV1, ServiceConfigV2, ServiceConfigV3],
723
+ Field(discriminator="version"),
724
+ ]
725
+ """Configuration options available for audit service"""
726
+
727
+
728
+ class ServiceConfigFilter(APIRequestModel):
729
+ id: Optional[str] = None
730
+ """Only records where id equals this value."""
731
+
732
+ id__contains: Optional[Sequence[str]] = None
733
+ """Only records where id includes each substring."""
734
+
735
+ id__in: Optional[Sequence[str]] = None
736
+ """Only records where id equals one of the provided substrings."""
737
+
738
+ created_at: Optional[str] = None
739
+ """Only records where created_at equals this value."""
740
+
741
+ created_at__gt: Optional[str] = None
742
+ """Only records where created_at is greater than this value."""
743
+
744
+ created_at__gte: Optional[str] = None
745
+ """Only records where created_at is greater than or equal to this value."""
746
+
747
+ created_at__lt: Optional[str] = None
748
+ """Only records where created_at is less than this value."""
749
+
750
+ created_at__lte: Optional[str] = None
751
+ """Only records where created_at is less than or equal to this value."""
752
+
753
+ updated_at: Optional[str] = None
754
+ """Only records where updated_at equals this value."""
755
+
756
+ updated_at__gt: Optional[str] = None
757
+ """Only records where updated_at is greater than this value."""
758
+
759
+ updated_at__gte: Optional[str] = None
760
+ """Only records where updated_at is greater than or equal to this value."""
761
+
762
+ updated_at__lt: Optional[str] = None
763
+ """Only records where updated_at is less than this value."""
764
+
765
+ updated_at__lte: Optional[str] = None
766
+ """Only records where updated_at is less than or equal to this value."""
767
+
768
+
769
+ class ServiceConfigListResult(PangeaResponseResult):
770
+ count: int
771
+ """The total number of service configs matched by the list request."""
772
+
773
+ last: str
774
+ """Used to fetch the next page of the current listing when provided in a repeated request's last parameter."""
775
+
776
+ items: Sequence[ServiceConfig]
@@ -81,7 +81,7 @@ class Signer:
81
81
  with open(self.private_key_file, "rb") as file:
82
82
  file_bytes = file.read()
83
83
  except FileNotFoundError:
84
- raise Exception(f"Error: Failed opening private key file {self.private_key_file}")
84
+ raise Exception(f"Error: Failed opening private key file {self.private_key_file}") from None
85
85
 
86
86
  privkey = self._decode_private_key(file_bytes)
87
87
  for cls, signer in signers.items():