forked from BasedHardware/omi
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathredaction.py
More file actions
179 lines (156 loc) · 5.67 KB
/
Copy pathredaction.py
File metadata and controls
179 lines (156 loc) · 5.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
"""Canonical local-only memory-V3-F6 strict evidence redaction/output contract."""
from __future__ import annotations
import json
import re
from typing import Any
from testing.memory.v3_f6._validation import require_exact_fields
from testing.memory.v3_f6.fingerprints import (
FINGERPRINT_RE,
HMAC_KEY,
FingerprintContractError,
RedactionContractError,
fingerprint,
)
TOP_LEVEL_FIELDS = frozenset(
{
"artifact_version",
"status",
"target",
"project_fingerprint",
"principal_fingerprint",
"run_fingerprint",
"approved_metadata_paths",
"read_bounds",
"index_expectations",
"audit",
"observations",
"non_claims",
}
)
OBSERVATION_FIELDS = frozenset({"name", "status", "metadata"})
READ_BOUNDS_FIELDS = frozenset({"max_documents_per_path", "max_paths", "allow_collection_scans"})
AUDIT_FIELDS = frozenset({"enabled", "zero_write_methods"})
FORBIDDEN_FIELD_FRAGMENTS = (
"raw_memory",
"memory_content",
"secret",
"cursor",
"token",
"authorization",
"auth_header",
"url",
"uri",
"user_id",
"uid",
"query",
"credential",
"password",
"request_body",
"response_body",
"body",
"payload",
"headers",
)
FORBIDDEN_VALUE_PATTERNS = (
re.compile(r"https?://", re.IGNORECASE),
re.compile(r"\bAuthorization\s*:", re.IGNORECASE),
re.compile(r"\bBearer\s+[A-Za-z0-9._\-]+", re.IGNORECASE),
re.compile(r"\b(cursor|access|refresh|id)[-_ ]?token\b", re.IGNORECASE),
re.compile(r"\b(password|credential|secret)\s*=", re.IGNORECASE),
re.compile(r"\buid[_:-]?[A-Za-z0-9]{6,}\b", re.IGNORECASE),
re.compile(r"\buser[_-]?id\b", re.IGNORECASE),
re.compile(r"raw query value", re.IGNORECASE),
re.compile(r"raw memory content", re.IGNORECASE),
)
def validate_redacted_evidence(report: dict[str, Any]) -> None:
if not isinstance(report, dict):
raise RedactionContractError("report must be a mapping")
_require_exact_top_level(report)
if report["artifact_version"] != "memory-V3-F6F":
raise RedactionContractError("artifact_version must be memory-V3-F6F")
for field in ("project_fingerprint", "principal_fingerprint", "run_fingerprint"):
if not isinstance(report[field], str) or not FINGERPRINT_RE.fullmatch(report[field]):
raise RedactionContractError(f"{field} must be a keyed HMAC fingerprint")
_validate_read_bounds(report["read_bounds"])
_validate_audit(report["audit"])
_walk(report, path=())
def render_redacted_evidence_json(report: dict[str, Any]) -> str:
validate_redacted_evidence(report)
return json.dumps(report, sort_keys=True, indent=2)
def _require_exact_top_level(report: dict[str, Any]) -> None:
require_exact_fields(
report,
TOP_LEVEL_FIELDS,
label="report",
error_type=RedactionContractError,
missing_message_prefix="missing fields",
unknown_message_prefix="unknown fields",
)
def _validate_read_bounds(raw: Any) -> None:
if not isinstance(raw, dict):
raise RedactionContractError("read_bounds must be a mapping")
require_exact_fields(
raw,
READ_BOUNDS_FIELDS,
label="read_bounds",
error_type=RedactionContractError,
check_order=("unknown", "missing"),
)
if raw["allow_collection_scans"] is not False:
raise RedactionContractError("collection scans are not redacted evidence")
def _validate_audit(raw: Any) -> None:
if not isinstance(raw, dict):
raise RedactionContractError("audit must be a mapping")
require_exact_fields(
raw, AUDIT_FIELDS, label="audit", error_type=RedactionContractError, check_order=("unknown", "missing")
)
def _walk(value: Any, *, path: tuple[str, ...]) -> None:
if isinstance(value, dict):
for key, item in value.items():
if not isinstance(key, str):
raise RedactionContractError("non-string field names are forbidden")
_check_field_name(key, path)
if path == ("observations",) and key not in OBSERVATION_FIELDS:
raise RedactionContractError(f"observation unknown fields: {key}")
_walk(item, path=path + (key,))
return
if isinstance(value, list):
for item in value:
_walk(item, path=path)
return
if isinstance(value, str):
if path == ("non_claims",):
return
_check_string_value(value)
def _check_field_name(key: str, path: tuple[str, ...]) -> None:
if len(path) == 0:
return
if path == ("index_expectations",):
# Firestore index identifiers are approved metadata names in this
# contract; they may legitimately contain field-name fragments such as
# ``uid`` without revealing arbitrary user IDs.
return
# Metadata is intentionally strict: unknown/sensitive evidence names fail closed
# instead of being partially redacted after the fact.
lower = key.lower()
if any(fragment in lower for fragment in FORBIDDEN_FIELD_FRAGMENTS):
raise RedactionContractError(f"forbidden field name: {'.'.join(path + (key,))}")
def _check_string_value(value: str) -> None:
for pattern in FORBIDDEN_VALUE_PATTERNS:
if pattern.search(value):
raise RedactionContractError("forbidden sensitive value")
__all__ = [
"AUDIT_FIELDS",
"FINGERPRINT_RE",
"FORBIDDEN_FIELD_FRAGMENTS",
"FORBIDDEN_VALUE_PATTERNS",
"FingerprintContractError",
"HMAC_KEY",
"OBSERVATION_FIELDS",
"READ_BOUNDS_FIELDS",
"RedactionContractError",
"TOP_LEVEL_FIELDS",
"fingerprint",
"render_redacted_evidence_json",
"validate_redacted_evidence",
]