htl-verify 1.0.0__tar.gz

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.
@@ -0,0 +1,49 @@
1
+ Metadata-Version: 2.4
2
+ Name: htl-verify
3
+ Version: 1.0.0
4
+ Summary: Verify X-Trust signed human-presence headers. Standard library only.
5
+ Author-email: Dieng <diengamine.htl@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/htl-syterme/htl-core
8
+ Project-URL: Repository, https://github.com/htl-syterme/htl-core
9
+ Project-URL: Spec, https://github.com/htl-syterme/htl-core/blob/main/SPEC.md
10
+ Keywords: trust,human-proof,anti-bot,x-trust,llm,ai-infrastructure
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
14
+ Classifier: Topic :: Security
15
+ Requires-Python: >=3.10
16
+ Description-Content-Type: text/markdown
17
+
18
+ # htl-verify
19
+
20
+ Verify X-Trust signed human-presence headers in Python. Standard library only.
21
+
22
+ ## Install
23
+
24
+ pip install htl-verify
25
+
26
+ ## Use
27
+
28
+ from htl_verify import verify, Untrusted
29
+
30
+ try:
31
+ claims = verify(header, key=secret_bytes)
32
+ score = claims["score"]
33
+ if score >= 0.5:
34
+ pass # annotated as likely-human
35
+ except Untrusted:
36
+ pass # treat as unverified; never blocks by default
37
+
38
+ ## What it is not
39
+
40
+ Not a CAPTCHA, not identity, not bot authentication. The score is a signal,
41
+ not a proof. A determined client can raise its own score; that is a property
42
+ of any client-side signal and is documented in the project SPEC.
43
+
44
+ ## Wire format
45
+
46
+ X-Trust: v1.<payload_b64url>.<sig_b64url>
47
+
48
+ Payload JSON: `{sub, score, iat, exp, nonce?}`. HMAC-SHA256 over the
49
+ base64url payload. TTL 120s. Score 0..1.
@@ -0,0 +1,32 @@
1
+ # htl-verify
2
+
3
+ Verify X-Trust signed human-presence headers in Python. Standard library only.
4
+
5
+ ## Install
6
+
7
+ pip install htl-verify
8
+
9
+ ## Use
10
+
11
+ from htl_verify import verify, Untrusted
12
+
13
+ try:
14
+ claims = verify(header, key=secret_bytes)
15
+ score = claims["score"]
16
+ if score >= 0.5:
17
+ pass # annotated as likely-human
18
+ except Untrusted:
19
+ pass # treat as unverified; never blocks by default
20
+
21
+ ## What it is not
22
+
23
+ Not a CAPTCHA, not identity, not bot authentication. The score is a signal,
24
+ not a proof. A determined client can raise its own score; that is a property
25
+ of any client-side signal and is documented in the project SPEC.
26
+
27
+ ## Wire format
28
+
29
+ X-Trust: v1.<payload_b64url>.<sig_b64url>
30
+
31
+ Payload JSON: `{sub, score, iat, exp, nonce?}`. HMAC-SHA256 over the
32
+ base64url payload. TTL 120s. Score 0..1.
@@ -0,0 +1,67 @@
1
+ """htl-verify - X-Trust header verifier. Standard library only, zero dependencies."""
2
+ import base64
3
+ import hashlib
4
+ import hmac
5
+ import json
6
+ import time
7
+ from typing import Any
8
+
9
+ __version__ = "1.0.0"
10
+ __all__ = ["verify", "Untrusted"]
11
+
12
+
13
+ class Untrusted(Exception):
14
+ """Raised when an X-Trust header fails verification."""
15
+
16
+
17
+ def _b64d(s: str) -> bytes:
18
+ pad = "=" * (-len(s) % 4)
19
+ return base64.urlsafe_b64decode(s + pad)
20
+
21
+
22
+ def verify(
23
+ header: str,
24
+ key: bytes,
25
+ *,
26
+ now: float | None = None,
27
+ max_age: int = 120,
28
+ ) -> dict[str, Any]:
29
+ """
30
+ Verify an X-Trust header and return its claims.
31
+
32
+ Raises Untrusted on any failure. Never returns a payload whose
33
+ signature has not been verified first.
34
+ """
35
+ if not header:
36
+ raise Untrusted("empty header")
37
+ parts = header.split(".")
38
+ if len(parts) != 3:
39
+ raise Untrusted("malformed")
40
+ version, payload_b64, sig_b64 = parts
41
+ if version != "v1":
42
+ raise Untrusted(f"unsupported version: {version}")
43
+
44
+ payload = _b64d(payload_b64)
45
+ expected = hmac.new(key, payload_b64.encode("ascii"), hashlib.sha256).digest()
46
+ provided = _b64d(sig_b64)
47
+ if not hmac.compare_digest(expected, provided):
48
+ raise Untrusted("bad signature")
49
+
50
+ claims = json.loads(payload) # only trusted bytes reach the parser
51
+
52
+ score = claims.get("score")
53
+ if not isinstance(score, (int, float)) or score < 0 or score > 1:
54
+ raise Untrusted("invalid score")
55
+
56
+ iat = claims.get("iat")
57
+ exp = claims.get("exp")
58
+ if not isinstance(iat, (int, float)) or not isinstance(exp, (int, float)):
59
+ raise Untrusted("invalid timestamps")
60
+
61
+ n = now if now is not None else time.time()
62
+ if n > exp:
63
+ raise Untrusted("expired")
64
+ if n - iat > max_age:
65
+ raise Untrusted("stale")
66
+
67
+ return claims
@@ -0,0 +1,49 @@
1
+ Metadata-Version: 2.4
2
+ Name: htl-verify
3
+ Version: 1.0.0
4
+ Summary: Verify X-Trust signed human-presence headers. Standard library only.
5
+ Author-email: Dieng <diengamine.htl@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/htl-syterme/htl-core
8
+ Project-URL: Repository, https://github.com/htl-syterme/htl-core
9
+ Project-URL: Spec, https://github.com/htl-syterme/htl-core/blob/main/SPEC.md
10
+ Keywords: trust,human-proof,anti-bot,x-trust,llm,ai-infrastructure
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
14
+ Classifier: Topic :: Security
15
+ Requires-Python: >=3.10
16
+ Description-Content-Type: text/markdown
17
+
18
+ # htl-verify
19
+
20
+ Verify X-Trust signed human-presence headers in Python. Standard library only.
21
+
22
+ ## Install
23
+
24
+ pip install htl-verify
25
+
26
+ ## Use
27
+
28
+ from htl_verify import verify, Untrusted
29
+
30
+ try:
31
+ claims = verify(header, key=secret_bytes)
32
+ score = claims["score"]
33
+ if score >= 0.5:
34
+ pass # annotated as likely-human
35
+ except Untrusted:
36
+ pass # treat as unverified; never blocks by default
37
+
38
+ ## What it is not
39
+
40
+ Not a CAPTCHA, not identity, not bot authentication. The score is a signal,
41
+ not a proof. A determined client can raise its own score; that is a property
42
+ of any client-side signal and is documented in the project SPEC.
43
+
44
+ ## Wire format
45
+
46
+ X-Trust: v1.<payload_b64url>.<sig_b64url>
47
+
48
+ Payload JSON: `{sub, score, iat, exp, nonce?}`. HMAC-SHA256 over the
49
+ base64url payload. TTL 120s. Score 0..1.
@@ -0,0 +1,7 @@
1
+ README.md
2
+ pyproject.toml
3
+ htl_verify/__init__.py
4
+ htl_verify.egg-info/PKG-INFO
5
+ htl_verify.egg-info/SOURCES.txt
6
+ htl_verify.egg-info/dependency_links.txt
7
+ htl_verify.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ htl_verify
@@ -0,0 +1,24 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "htl-verify"
7
+ version = "1.0.0"
8
+ description = "Verify X-Trust signed human-presence headers. Standard library only."
9
+ readme = "README.md"
10
+ license = { text = "MIT" }
11
+ requires-python = ">=3.10"
12
+ authors = [{ name = "Dieng", email = "diengamine.htl@gmail.com" }]
13
+ keywords = ["trust", "human-proof", "anti-bot", "x-trust", "llm", "ai-infrastructure"]
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Topic :: Internet :: WWW/HTTP :: HTTP Servers",
18
+ "Topic :: Security",
19
+ ]
20
+
21
+ [project.urls]
22
+ Homepage = "https://github.com/htl-syterme/htl-core"
23
+ Repository = "https://github.com/htl-syterme/htl-core"
24
+ Spec = "https://github.com/htl-syterme/htl-core/blob/main/SPEC.md"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+