code wiki / _hdl_build / nx_apistack_svctoken.nx

nx_apistack_svctoken.nx source

↩ module page · 48 lines · 2780 B

1// nx_apistack_svctoken.nx -- CAP-API-SVCTOKEN: scoped machine-to-machine tokens for /api (service accounts that 2// aren't a human OPAQUE login). A token store maps HASH(token) -> service + level (svctokens.conf: tokenhex TAB 3// service TAB level), so the store holds only HASHES -- a leaked store never reveals a usable token (the sovereign 4// exceed over plaintext API keys). st_resolve hashes the presented token and looks it up; deny-by-default. Scope = 5// the same DATA-driven level as the roles SSOT, so a service token is level-scoped exactly like a user. license_tier: ORIGINAL 6import "nx_syscalls.nx" 7import "nx_site_lock_lib.nx" 8const K_MAGIC_3750763034362895579: i64 = 3750763034362895579 9const K_MAGIC_1099511628211: i64 = 1099511628211 10const K_MAGIC_65536: i64 = 65536 11 12func st_read_file(path: *u8, out: *u8, cap: i64) -> i64 { 13 let fd: i64 = sys_openat_rd(path); if fd < 0 { return 0 } 14 var total: i64 = 0; var go: i64 = 1 15 while go == 1 { let tail: *u8 = (out as i64 + total) as *u8; let nr: i64 = sys_read(fd, tail, cap - total); if nr <= 0 { go = 0 } if nr > 0 { total = total + nr } if total >= cap { go = 0 } } 16 sys_close(fd); return total 17} 18func st_fnv(s: *u8, n: i64) -> i64 { 19 var h: i64 = 0 - K_MAGIC_3750763034362895579; var i: i64 = 0 20 while i < n { h = (h ^ ((s[i] as i64) & 0xff)) * K_MAGIC_1099511628211; i = i + 1 } 21 return h 22} 23func st_hex16(h: i64, out: *u8) -> i64 { 24 let hx: *u8 = "0123456789abcdef" as *u8; var k: i64 = 0 25 while k < 16 { out[k] = hx[(h >> (60 - 4 * k)) & 0xf]; k = k + 1 } 26 out[16] = 0 as u8; return 16 27} 28// resolve a presented token to (service, level) via the hashed store. 1 if found (fills out_service + out_level), 0 else. 29func st_resolve(store_path: *u8, token: *u8, token_n: i64, out_service: *u8, svc_cap: i64, out_level: *i64) -> i64 { 30 let th: *u8 = sys_mmap(24); st_hex16(st_fnv(token, token_n), th) 31 let buf: *u8 = sys_mmap(K_MAGIC_65536); let n: i64 = st_read_file(store_path, buf, K_MAGIC_65536) 32 let fs: *i64 = sys_mmap(8); let fe: *i64 = sys_mmap(8) 33 var ls: i64 = 0 34 while ls < n { 35 let le: i64 = slk_line_end(buf, n, ls) 36 if le > ls { if buf[ls] != (35 as u8) { 37 if slk_field(buf, ls, le, 0, fs, fe) == 1 { 38 if slk_eq(slk_at(buf, fs[0]), fe[0] - fs[0], th, 16) == 1 { 39 if slk_field(buf, ls, le, 1, fs, fe) == 1 { var o: i64 = 0; let sl: i64 = fe[0] - fs[0]; while o < sl { if o < svc_cap - 1 { out_service[o] = buf[fs[0] + o] } o = o + 1 } out_service[o] = 0 as u8 } 40 if slk_field(buf, ls, le, 2, fs, fe) == 1 { out_level[0] = slk_atoi(buf, fs[0], fe[0]) } 41 return 1 42 } 43 } 44 } } 45 ls = le + 1 46 } 47 out_level[0] = 0; return 0 48}