code wiki / _hdl_build / nx_promote_deny_gate.nx
nx_promote_deny_gate.nx source
↩ module page · 72 lines · 4131 B
1// nx_promote_deny_gate.nx -- the safety proof for narrowing md_promote_deny_hard
2// from a raw SUBSTRING to a TOKEN-BOUNDARY match plus an oracle exemption
3// (debt 1785511766, 2026-07-31).
4//
5// This guard is NON-OVERRIDABLE by design: no conf row may make a credential
6// organ promotable, or the role registry becomes a privilege-escalation surface.
7// So the burden of proof for touching it is one-directional --
8// EVERY REAL CREDENTIAL ORGAN MUST STILL DENY (T1-T8).
9// The false positives it removes (T9-T12) are only worth anything if that holds.
10// A change to a security guard that only tests the newly-allowed cases is how a
11// hole ships.
12// license_tier: ORIGINAL
13import "nx_mgmt_data.nx"
14import "nx_gate.nx"
15import "nx_gate_verdict.nx" // D001: inherit the canonical verdict lib
16
17func pd_deny(g: *u8, nm: *u8, want: i64, pass: *i64, tot: *i64) -> i64 {
18 // Compose the full label (including the observed DENY/allow) into a buffer
19 // and emit ONE gv_check, so the base class does the counting and the PASS/FAIL
20 // shape while the diagnostic detail survives -- a retrofit should not cost
21 // readability at the moment a check fails.
22 let got: i64 = md_promote_deny_hard(nm)
23 let lb: *u8 = sys_mmap(512)
24 var o: i64 = gv_cat(lb, 0, g)
25 o = gv_cat(lb, o, " (" as *u8)
26 o = gv_cat(lb, o, nm)
27 o = gv_cat(lb, o, " -> " as *u8)
28 if got == 1 { o = gv_cat(lb, o, "DENY" as *u8) } else { o = gv_cat(lb, o, "allow" as *u8) }
29 o = gv_cat(lb, o, ")" as *u8)
30 lb[o] = 0 as u8
31 var ok: i64 = 0
32 if got == want { ok = 1 }
33 gv_check(lb, ok, pass)
34 return 0
35}
36
37func main() -> i64 {
38 gw("=== nx_promote_deny_gate: credential custody survives the substring fix ===\n" as *u8)
39 // base-class counter pair: [0]=pass [1]=total. tot stays only so the 15
40 // existing pd_deny call sites need no edit.
41 let pass: *i64 = gv_ctr()
42 let tot: *i64 = sys_mmap(16) as *i64
43
44 gw("-- the property that must NOT regress: real credential organs still deny\n" as *u8)
45 pd_deny("T1 the cap minter" as *u8, "nx_cap_mint" as *u8, 1, pass, tot)
46 pd_deny("T2 the session minter" as *u8, "nx_session_mint" as *u8, 1, pass, tot)
47 pd_deny("T3 the mgmt session minter" as *u8, "nx_mgmt_session_mint" as *u8, 1, pass, tot)
48 pd_deny("T4 the key generator" as *u8, "nx_cap_keygen" as *u8, 1, pass, tot)
49 pd_deny("T5 the login organ" as *u8, "nx_opaque_login" as *u8, 1, pass, tot)
50 pd_deny("T6 a secret holder" as *u8, "nx_cap_secret" as *u8, 1, pass, tot)
51 // GLUED-TAIL CONTROL: the token check anchors at the START of a token, so a
52 // run-together credential name must still be caught.
53 pd_deny("T7 GLUED a run-together secret name" as *u8, "nx_secretstore" as *u8, 1, pass, tot)
54 // "vault" as an actual WORD is still credential custody and still denies.
55 pd_deny("T8 vault as a real token" as *u8, "nx_vault_gateway" as *u8, 1, pass, tot)
56
57 gw("-- the false positives being removed: the MEDIA vault family\n" as *u8)
58 pd_deny("T9 the media vault organ" as *u8, "nx_mvault" as *u8, 0, pass, tot)
59 pd_deny("T10 the collection axis" as *u8, "nx_mvault_coll" as *u8, 0, pass, tot)
60 pd_deny("T11 the migration walker" as *u8, "nx_mvault_walk" as *u8, 0, pass, tot)
61 pd_deny("T12 the album fetcher" as *u8, "nx_mvault_fetch" as *u8, 0, pass, tot)
62
63 gw("-- the oracle exemption: a verifier cannot be the organ it verifies\n" as *u8)
64 // Promoting this installs nx_cap_mint_gate.elf; it CANNOT swap nx_cap_mint.elf.
65 pd_deny("T13 a gate FOR a credential organ" as *u8, "nx_cap_mint_gate" as *u8, 0, pass, tot)
66 pd_deny("T14 a vault gateway gate" as *u8, "nx_vault_gateway_gate" as *u8, 0, pass, tot)
67 pd_deny("T15 an unrelated organ is untouched" as *u8, "nx_media_inventory" as *u8, 0, pass, tot)
68
69 let rc: i64 = gv_verdict("PROMOTE-DENY" as *u8, pass, "credential custody intact; only the media-vault false positives are gone" as *u8)
70 sys_exit(rc)
71 return rc
72}