code wiki / _hdl_build / nx_hr_entitle.nx

nx_hr_entitle.nx source

↩ module page · 163 lines · 10073 B

1// nx_hr_entitle.nx -- SUPERUSER-BY-CONSTRUCTION entitlement resolution, now on the SOVEREIGN store (operator NO-TSV 2// doctrine [[feedback-no-3rd-party-tsv-sovereign-store]]). Entitlements no longer live in a flat .tsv -- each is a 3// CANON record (key,label,url) in a content-addressed nx_seg_store, enumerated via a count+index ("ent:count" + 4// "ent:<i>"), the proven nx_native_config pattern. Semantics unchanged: 5// * an ACTIVE SUPERADMIN (HR owner, lvl 3) is entitled to EVERY entitlement -- auto-access, zero drift; and 6// * everyone else gets the public ("*") entitlements + the ones keyed to their own handle (deny-by-default). 7// Superadmin status comes from the HR SSOT (hra_is_superadmin, now seg_store-backed). Pure resolver. 8// entitlement record fields: key (a handle, or "*" for everyone), label, url 9import "nx_hr_admin.nx" // hra_is_superadmin 10import "nx_hr.nx" // hr_cred_id / hr_puts / hr_putn (derivation + string helpers) 11import "nx_seg_store.nx" // ss_begin / ss_add / ss_commit / ss_open / ss_hget 12import "nx_canon_cid.nx" // canon_encode 13import "nx_uxf_decode.nx" // canon_decode 14import "nx_sha256.nx" // sha256_digest (segid) 15import "nx_syscalls.nx" 16const K_MAGIC_1024: i64 = 1024 17const K_MAGIC_4096: i64 = 4096 18 19func he_memeq(a: *u8, b: *u8, n: i64) -> i64 { var i: i64=0; while i<n { if a[i]!=b[i] { return 0 } i=i+1 } return 1 } 20func he_catb(dst: *u8, off: i64, src: *u8, n: i64) -> i64 { var o: i64=off; var i: i64=0; while i<n { dst[o]=src[i]; o=o+1; i=i+1 } return o } 21func he_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 22func he_streq(a: *u8, b: *u8) -> i64 { var i: i64=0; while 1==1 { let ca: i64=a[i] as i64; let cb: i64=b[i] as i64; if ca!=cb {return 0} if ca==0 {return 1} i=i+1 } return 1 } 23func he_itoa(v: i64, out: *u8) -> i64 { let t: *u8=sys_mmap(28); var m: i64=v; 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; while i<k{out[i]=t[k-1-i];i=i+1} out[k]=0 as u8; return k } 24func he_atoi_n(s: *u8, n: i64) -> i64 { var v: i64=0; var i: i64=0; while i<n { let c: i64=s[i] as i64; if c>=48 { if c<=57 { v=v*10+(c-48) } } i=i+1 } return v } 25 26// the include predicate on a KEY string: superadmin -> every entitlement; else wildcard "*" or exact-handle key. 27func he_include_key(super: i64, key: *u8, handle: *u8, hn: i64) -> i64 { 28 if super == 1 { return 1 } 29 let kl: i64 = he_slen(key) 30 if kl == 1 { if key[0] == (42 as u8) { return 1 } } // '*' 31 if kl == hn { if he_memeq(key, handle, hn) == 1 { return 1 } } 32 return 0 33} 34// resolve the SUPERADMIN bit for (realm, handle) from the HR SSOT (seg_store-backed). 0 if absent / not active owner. 35func he_super_of(hr_store: *u8, realm: *u8, realm_n: i64, handle: *u8, hn: i64) -> i64 { 36 let cid: *u8 = sys_mmap(96) 37 if hr_cred_id(realm, realm_n, handle, hn, cid) <= 0 { return 0 } 38 return hra_is_superadmin(hr_store, cid, 64) 39} 40 41// ---- the entitlement seg_store: "ent:count" + "ent:<i>" -> canon{key,label,url} ---- 42func he_idx_key(i: i64, out: *u8) -> i64 { let p: *u8="ent:" as *u8; var o: i64=0; while p[o]!=(0 as u8){out[o]=p[o];o=o+1} let k: i64=he_itoa(i, (out as i64 + o) as *u8); return o+k } 43func he_ent_count(prefix: *u8) -> i64 { 44 let h: *i64=ss_open(prefix); if (h as i64)==0 { return 0 } 45 let pp: *i64=sys_mmap(16) as *i64; let ll: *i64=sys_mmap(16) as *i64 46 if ss_hget(h, "ent:count" as *u8, pp, ll) != 1 { return 0 } 47 return he_atoi_n(pp[0] as *u8, ll[0]) 48} 49func he_ent_segid(key: *u8, label: *u8, url: *u8) -> i64 { 50 let b: *u8=sys_mmap(K_MAGIC_1024); var o: i64=0 51 var i: i64=0; while key[i]!=(0 as u8){b[o]=key[i];o=o+1;i=i+1} b[o]=124 as u8;o=o+1 52 var j: i64=0; while label[j]!=(0 as u8){b[o]=label[j];o=o+1;j=j+1} b[o]=124 as u8;o=o+1 53 var k: i64=0; while url[k]!=(0 as u8){b[o]=url[k];o=o+1;k=k+1} 54 let dig: *u8=sys_mmap(32); sha256_digest(b, o, dig) 55 var v: i64=0; var m: i64=0; while m<7 { v=(v<<8)|((dig[m] as i64)&255); m=m+1 } return v 56} 57// GRANT an entitlement (key,label,url) into the seg_store: append the record + bump the count, in one atomic commit. 58// IDEMPOTENT: a re-grant of the identical triple is a no-op (re-provisioning is safe, rule #10). 59func he_ent_put(prefix: *u8, key: *u8, label: *u8, url: *u8) -> i64 { 60 if he_ent_has(prefix, key, label, url)==1 { return 0 } 61 let n: i64=he_ent_count(prefix) 62 let keys: *i64=sys_mmap(8*4) as *i64; let vals: *i64=sys_mmap(8*4) as *i64 63 keys[0]="key" as *u8 as i64; vals[0]=key as i64 64 keys[1]="label" as *u8 as i64; vals[1]=label as i64 65 keys[2]="url" as *u8 as i64; vals[2]=url as i64 66 let buf: *u8=sys_mmap(K_MAGIC_4096); let blen: i64=canon_encode(keys, vals, 3, buf) 67 let ik: *u8=sys_mmap(32); let ikl: i64=he_idx_key(n, ik); ik[ikl]=0 as u8 68 let cv: *u8=sys_mmap(28); let cl: i64=he_itoa(n+1, cv) 69 let w: *i64=ss_begin(); ss_add(w, 1, ik, buf, blen); ss_add(w, 1, "ent:count" as *u8, cv, cl) 70 ss_commit(prefix, w, he_ent_segid(key, label, url)) 71 return 0 72} 73func he_ent_get(prefix: *u8, i: i64, ok: *i64, ov: *i64, maxf: i64) -> i64 { 74 let ik: *u8=sys_mmap(32); let ikl: i64=he_idx_key(i, ik); ik[ikl]=0 as u8 75 let h: *i64=ss_open(prefix); if (h as i64)==0 { return 0 } 76 let pp: *i64=sys_mmap(16) as *i64; let ll: *i64=sys_mmap(16) as *i64 77 if ss_hget(h, ik, pp, ll) != 1 { return 0 } 78 return canon_decode(pp[0] as *u8, ll[0], ok, ov, maxf) 79} 80func he_ent_field(ok: *i64, ov: *i64, nf: i64, name: *u8) -> *u8 { var i: i64=0; while i<nf { if he_streq(ok[i] as *u8, name)==1 { return ov[i] as *u8 } i=i+1 } return 0 as *u8 } 81// 1 iff the EXACT (key,label,url) entitlement already exists (dedup for idempotent grants). 82func he_ent_has(prefix: *u8, key: *u8, label: *u8, url: *u8) -> i64 { 83 let n: i64=he_ent_count(prefix); var i: i64=0 84 let ok: *i64=sys_mmap(16*8) as *i64; let ov: *i64=sys_mmap(16*8) as *i64 85 while i < n { 86 let nf: i64=he_ent_get(prefix, i, ok, ov, 16) 87 if nf > 0 { 88 let k: *u8=he_ent_field(ok, ov, nf, "key" as *u8); let l: *u8=he_ent_field(ok, ov, nf, "label" as *u8); let u: *u8=he_ent_field(ok, ov, nf, "url" as *u8) 89 if (k as i64)!=0 { if (l as i64)!=0 { if (u as i64)!=0 { 90 if he_streq(k, key)==1 { if he_streq(l, label)==1 { if he_streq(u, url)==1 { return 1 } } } 91 } } } 92 } 93 i=i+1 94 } 95 return 0 96} 97 98// COUNT the entitlements a user with the given SUPER bit + handle is entitled to (iterates the ent seg_store). 99func he_count_super(super: i64, handle: *u8, hn: i64, ent_prefix: *u8) -> i64 { 100 let n: i64=he_ent_count(ent_prefix); var cnt: i64=0; var i: i64=0 101 let ok: *i64=sys_mmap(16*8) as *i64; let ov: *i64=sys_mmap(16*8) as *i64 102 while i < n { 103 let nf: i64=he_ent_get(ent_prefix, i, ok, ov, 16) 104 if nf > 0 { let key: *u8=he_ent_field(ok, ov, nf, "key" as *u8); if (key as i64)!=0 { if he_include_key(super, key, handle, hn)==1 { cnt=cnt+1 } } } 105 i=i+1 106 } 107 return cnt 108} 109func he_count_access(hr_store: *u8, realm: *u8, realm_n: i64, handle: *u8, hn: i64, ent_prefix: *u8) -> i64 { 110 return he_count_super(he_super_of(hr_store, realm, realm_n, handle, hn), handle, hn, ent_prefix) 111} 112 113// 1 iff (owner/super OR an entitlement keyed "*"/this-handle) grants the SPECIFIC area `url`. The per-area authZ 114// gate for "single login + approve-by-area" (operator 2026-06-24): a user reaches /gen only if entitled to "/gen" 115// (or is the owner). Deny-by-default. Mirrors he_count_super's iteration. license_tier: ORIGINAL 116func he_has_access(super: i64, handle: *u8, hn: i64, ent_prefix: *u8, url: *u8) -> i64 { 117 if super == 1 { return 1 } 118 let n: i64=he_ent_count(ent_prefix); var i: i64=0 119 let ok: *i64=sys_mmap(16*8) as *i64; let ov: *i64=sys_mmap(16*8) as *i64 120 while i < n { 121 let nf: i64=he_ent_get(ent_prefix, i, ok, ov, 16) 122 if nf > 0 { 123 let key: *u8=he_ent_field(ok, ov, nf, "key" as *u8) 124 let u: *u8=he_ent_field(ok, ov, nf, "url" as *u8) 125 if (key as i64)!=0 { if (u as i64)!=0 { if he_include_key(super, key, handle, hn)==1 { if he_streq(u, url)==1 { return 1 } } } } 126 } 127 i=i+1 128 } 129 return 0 130} 131func he_has_access_realm(hr_store: *u8, realm: *u8, realm_n: i64, handle: *u8, hn: i64, ent_prefix: *u8, url: *u8) -> i64 { 132 return he_has_access(he_super_of(hr_store, realm, realm_n, handle, hn), handle, hn, ent_prefix, url) 133} 134 135// EMIT the user's entitled links as JSON: {"handle":"H","super":S,"links":[{"label":"L","url":"U"},...]}. 136func he_emit_super(super: i64, handle: *u8, hn: i64, ent_prefix: *u8, out: *u8, cap: i64) -> i64 { 137 var o: i64 = 0 138 o = hr_puts(out, o, "{\"handle\":\"" as *u8); o = he_catb(out, o, handle, hn) 139 o = hr_puts(out, o, "\",\"super\":" as *u8); o = hr_putn(out, o, super) 140 o = hr_puts(out, o, ",\"links\":[" as *u8) 141 let n: i64=he_ent_count(ent_prefix); var first: i64=1; var i: i64=0 142 let ok: *i64=sys_mmap(16*8) as *i64; let ov: *i64=sys_mmap(16*8) as *i64 143 while i < n { 144 let nf: i64=he_ent_get(ent_prefix, i, ok, ov, 16) 145 if nf > 0 { 146 let key: *u8=he_ent_field(ok, ov, nf, "key" as *u8) 147 if (key as i64)!=0 { if he_include_key(super, key, handle, hn)==1 { 148 let label: *u8=he_ent_field(ok, ov, nf, "label" as *u8) 149 let url: *u8=he_ent_field(ok, ov, nf, "url" as *u8) 150 if first == 0 { out[o]=44 as u8; o=o+1 } 151 o = hr_puts(out, o, "{\"label\":\"" as *u8); if (label as i64)!=0 { o=hr_puts(out, o, label) } 152 o = hr_puts(out, o, "\",\"url\":\"" as *u8); if (url as i64)!=0 { o=hr_puts(out, o, url) } 153 o = hr_puts(out, o, "\"}" as *u8); first = 0 154 } } 155 } 156 i=i+1 157 } 158 o = hr_puts(out, o, "]}" as *u8) 159 return o 160} 161func he_emit_access(hr_store: *u8, realm: *u8, realm_n: i64, handle: *u8, hn: i64, ent_prefix: *u8, out: *u8, cap: i64) -> i64 { 162 return he_emit_super(he_super_of(hr_store, realm, realm_n, handle, hn), handle, hn, ent_prefix, out, cap) 163}