scopes.py file-level

at main · View file ↗ · Intel ↗

History
1 files
1 commits
0 hotspots
0 🧊 dead
0 💥 blast risk
sha256:6 fix(ISR): default require_independent_second_reviewer to require Opera… · aaronrene · Sep 2, 2026
1 """Upstream credential scope refuse helpers (§HGD.6.2)."""
2
3 from __future__ import annotations
4
5 # Conceptual write-class scopes — refuse when advertised by host introspection.
6 REJECTED_SCOPE_TOKENS = frozenset(
7 {
8 "contents:write",
9 "administration",
10 "admin:org",
11 "admin:repo_hook",
12 "admin:org_hook",
13 "workflows",
14 "delete_repo",
15 "workflow",
16 "repo:status", # not write; keep focused on true write classes below
17 }
18 )
19
20 # Explicit write-class tokens used by tests and startup checks.
21 WRITE_SCOPE_TOKENS = frozenset(
22 {
23 "contents:write",
24 "administration",
25 "admin:org",
26 "admin:repo_hook",
27 "admin:org_hook",
28 "workflows",
29 "workflow",
30 "delete_repo",
31 "repo", # classic full-access PAT — refuse when introspected
32 }
33 )
34
35 # Narrow read-only conceptual scopes (informational).
36 READ_SCOPE_TOKENS = frozenset(
37 {
38 "contents:read",
39 "metadata:read",
40 "public_repo", # classic public read — handled carefully; prefer contents:read
41 }
42 )
43
44
45 def scopes_contain_write_class(scopes: frozenset[str] | set[str] | list[str] | None) -> bool:
46 """Return True when any advertised scope is a rejected write class.
47
48 When scopes cannot be introspected (``None``), returns False so the operator
49 runbook + tests must prove write HTTP verbs are unreachable.
50 """
51 if scopes is None:
52 return False
53 normalized = {s.strip().lower() for s in scopes if isinstance(s, str) and s.strip()}
54 write_normalized = {s.lower() for s in WRITE_SCOPE_TOKENS}
55 # ``repo`` is classic full access — refuse when present among introspected scopes
56 # unless the only intersection is empty.
57 return bool(normalized & write_normalized)
58
59
60 def refuse_write_scopes(scopes: frozenset[str] | set[str] | list[str] | None) -> str | None:
61 """Return error token ``write_scope_refused`` when write scopes are present."""
62 if scopes_contain_write_class(scopes):
63 return "write_scope_refused"
64 return None