code wiki / _hdl_build / nx_hr_access_gate.nx
nx_hr_access_gate.nx source
↩ module page · 77 lines · 5911 B
1// nx_hr_access_gate.nx -- referee for the shared access adapter (nx_hr_access). Registers + logs in real OPAQUE
2// sessions, then PROVES the session->HR-level resolution that gallery/hub would gate on:
3// owner session -> level 3, is_super=1, gate(required=3) serves ; member -> level 1, gate(3) DENIED, gate(1) serves ;
4// ★ a VALID session for a user NOT enrolled in HR -> level 0, gate(1) DENIED (authentication != authorization) ;
5// ★ SUSPEND the member in HR -> the same valid token now resolves to 0 (HR is consulted per request) ;
6// garbage token -> 0 ; hac_allows threshold math. GREEN iff every row matches. -> knowledge/status/hr_access_gate.log.
7import "nx_hr_access.nx"
8import "nx_opaque_login.nx"
9import "nx_hr.nx"
10import "nx_hr_admin.nx"
11import "nx_syscalls.nx"
12
13func g_w(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
14func g_n(v: i64) -> i64 { var m: i64=v; if m<0{g_w("-" as *u8);m=0-m} let t:*u8=sys_mmap(24); var k:i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var i:i64=0; let o:*u8=sys_mmap(24); while i<k{o[i]=t[k-1-i];i=i+1} sys_write(1,o,k); return 0 }
15func g_row(id: *u8, got: i64, want: i64, pass: *i64) -> i64 { g_w(" " as *u8); g_w(id); g_w(" got="); g_n(got); g_w(" want="); g_n(want); if got==want { g_w(" OK\n" as *u8); pass[0]=pass[0]+1 } else { g_w(" FAIL\n" as *u8) } return 0 }
16func gw(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return 0 }
17func gtrunc(path: *u8) -> i64 { let fd: i64 = sys_openat_wr(path, 0x1a4); if fd>=0 { sys_close(fd) } return 0 }
18func g_mkpfx(base: *u8, ms: i64, out: *u8) -> i64 { var o: i64=0; while base[o]!=(0 as u8){out[o]=base[o];o=o+1} let t: *u8=sys_mmap(28); var m: i64=ms; var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var z: i64=k-1; while z>=0{out[o]=t[z];o=o+1;z=z-1} out[o]=0 as u8; return o }
19
20func main() -> i64 {
21 let pass: *i64 = sys_mmap(8) as *i64; pass[0]=0
22 g_w("=== NISHI HR ACCESS GATE (session->HR level, the one access SSOT for every gated surface) ===\n" as *u8)
23 let keys: *u8 = "/tmp/nx_hac_keys.bin" as *u8
24 let store: *u8 = "/tmp/nx_hac_store.log" as *u8
25 let hr: *u8 = sys_mmap(96); g_mkpfx("/tmp/nx_hac_hr_" as *u8, sys_now_ms(), hr) // seg_store prefix (cutover)
26 let R: *u8 = "nishi_site_admin" as *u8; let RN: i64 = 16
27 let fam: *u8 = "andelin" as *u8
28 gtrunc(keys); gtrunc(store)
29 let ctx: *NxAuthContext = sys_mmap(256) as *NxAuthContext
30 if olg_ctx_setup(ctx, keys, store, R, RN, "access test" as *u8, 11, 512, 3, 1) != 0 { g_w("CTX-FAIL\n" as *u8); sys_exit(1); return 1 }
31
32 let mn: *u8 = sys_mmap(512); let mnn: *i64 = sys_mmap(16) as *i64
33 let cid: *u8 = sys_mmap(96)
34 // OPAQUE accounts + HR enrollment (owner+member enrolled; stranger registered but NOT enrolled)
35 olg_register(ctx, "owner" as *u8, 5, "ownerpass1" as *u8, 10, mn, 512, mnn)
36 hra_enroll(hr, R, RN, "owner" as *u8, 5, HRA_LVL_OWNER, fam, 1000, "system" as *u8, cid)
37 olg_register(ctx, "member" as *u8, 6, "memberpass1" as *u8, 11, mn, 512, mnn)
38 hra_enroll(hr, R, RN, "member" as *u8, 6, HRA_LVL_MEMBER, fam, 1000, "elderwesto" as *u8, cid)
39 olg_register(ctx, "stranger" as *u8, 8, "strangerpw1" as *u8, 11, mn, 512, mnn) // NOT enrolled in HR
40
41 // login -> session tokens
42 let to: *u8 = sys_mmap(512); let ton: *i64 = sys_mmap(16) as *i64
43 let tm: *u8 = sys_mmap(512); let tmn: *i64 = sys_mmap(16) as *i64
44 let ts: *u8 = sys_mmap(512); let tsn: *i64 = sys_mmap(16) as *i64
45 olg_login(ctx, "owner" as *u8, 5, "ownerpass1" as *u8, 10, to, 512, ton)
46 olg_login(ctx, "member" as *u8, 6, "memberpass1" as *u8, 11, tm, 512, tmn)
47 olg_login(ctx, "stranger" as *u8, 8, "strangerpw1" as *u8, 11, ts, 512, tsn)
48 let now: i64 = sys_now_realtime_sec()
49
50 g_row("owner session -> level 3" as *u8, hac_session_level(ctx, to, ton[0], now, hr), 3, pass)
51 g_row("owner session is_super=1" as *u8, hac_session_is_super(ctx, to, ton[0], now, hr), 1, pass)
52 g_row("owner gate(required=3) serves" as *u8, hac_gate(ctx, to, ton[0], now, hr, 3), 1, pass)
53 g_row("member session -> level 1" as *u8, hac_session_level(ctx, tm, tmn[0], now, hr), 1, pass)
54 g_row("member is_super=0 (leak-check)" as *u8, hac_session_is_super(ctx, tm, tmn[0], now, hr), 0, pass)
55 g_row("member gate(required=3) DENIED" as *u8, hac_gate(ctx, tm, tmn[0], now, hr, 3), 0, pass)
56 g_row("member gate(required=1) serves" as *u8, hac_gate(ctx, tm, tmn[0], now, hr, 1), 1, pass)
57 // ★ the SSOT property: authenticated but NOT authorized
58 g_row("VALID session, NOT HR-enrolled -> level 0" as *u8, hac_session_level(ctx, ts, tsn[0], now, hr), 0, pass)
59 g_row("stranger gate(required=1) DENIED (auth != authz)" as *u8, hac_gate(ctx, ts, tsn[0], now, hr, 1), 0, pass)
60 // garbage token
61 let gtok: *u8 = "not-a-real-token-AAAA" as *u8
62 g_row("garbage token -> level 0" as *u8, hac_session_level(ctx, gtok, 21, now, hr), 0, pass)
63 // ★ live suspension takes effect on an existing session
64 hra_suspend(hr, R, RN, "member" as *u8, 6, fam, 2000, "elderwesto" as *u8)
65 g_row("after SUSPEND, member's valid token -> level 0" as *u8, hac_session_level(ctx, tm, tmn[0], now, hr), 0, pass)
66 // threshold math
67 g_row("hac_allows(3,1)=1" as *u8, hac_allows(3,1), 1, pass)
68 g_row("hac_allows(1,3)=0" as *u8, hac_allows(1,3), 0, pass)
69 g_row("hac_allows(0,1)=0" as *u8, hac_allows(0,1), 0, pass)
70
71 g_w("HR-ACCESS-GATE rows=14 pass="); g_n(pass[0])
72 if pass[0]==14 { g_w(" verdict=GREEN\n" as *u8)
73 let lg: i64=sys_openat_append("knowledge/status/hr_access_gate.log" as *u8, 0x1a4)
74 if lg>=0 { gw(lg, "NISHI-HR-ACCESS-GATE pass=14/14 verdict=GREEN\n" as *u8); sys_close(lg) }
75 sys_exit(0); return 0 }
76 g_w(" verdict=RED\n" as *u8); sys_exit(1); return 1
77}