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}