code wiki / _hdl_build / nx_devcap_provision.nx

nx_devcap_provision.nx source

↩ module page · 76 lines · 4744 B

1// nx_devcap_provision.nx -- provision the DEV/CI API capability chain, sovereignly (operator 2026-07-02: 2// "get this all setup as api calls ... build our nishi lang to s class exceed"). Generates the HMAC secret 3// keyfile (32 random bytes from /dev/urandom, 0600 -- the file nx_dev_api's da_authz loads in prod, and the 4// file nx_cap_mint signs with), mints a `dev_build` capability valid for ~1 year, writes it to a token file, 5// and SELF-VERIFIES the full chain (capt_verify(keyfile-secret, minted-token, "dev_build", now) == CAPT_OK) 6// plus proves ISOLATION (a token minted with the const/dev secret does NOT verify against the keyfile secret). 7// Idempotent: reuses an existing keyfile so live caps keep verifying. Run once locally, then nx_aw_send the 8// keyfile to the NAS nishihost dir (0600) and keep the token operator-side (present as X-Nishi-Cap). 9// writes: dev_cap_secret.key (secret) + dev_cap.tok (an operator dev_build capability) 10// expect_exit: 0 license_tier: ORIGINAL 11import "nx_cap_token.nx" 12const DEV_MAGIC_31536000: i64 = 31536000 13const DEV_MAGIC_2048: i64 = 2048 14 15const KEYFILE: *u8 = "dev_cap_secret.key" as *u8 16const TOKFILE: *u8 = "dev_cap.tok" as *u8 17const DEV_CONST_SECRET: *u8 = "nishi-dev-cap-hmac-secret-v1-REPLACE-FROM-VAULT" as *u8 18 19func pw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 20func pn(v: i64) -> i64 { let b: *u8=sys_mmap(24); let n: i64=capt_catn(b,0,v); sys_write(1,b,n); return 0 } 21 22// read 32 bytes from /dev/urandom into out; 0 ok 23func fill_rand(out: *u8, n: i64) -> i64 { 24 let fd: i64 = sys_openat_rd("/dev/urandom" as *u8) 25 if fd < 0 { return 0 - 1 } 26 var got: i64 = 0 27 while got < n { let r: i64 = sys_read(fd, ((out as i64)+got) as *u8, n-got); if r<=0 { sys_close(fd); return 0-1 } got=got+r } 28 sys_close(fd) 29 return 0 30} 31 32func main() -> i64 { 33 pw("=== nx_devcap_provision: dev_build capability chain (keyfile + token + self-verify) ===\n" as *u8) 34 // 1. keyfile: reuse if present (idempotent), else generate 32 random bytes 35 let ksz: *i64 = sys_mmap(16) as *i64; ksz[0]=0 36 var secret: *u8 = sys_read_file(KEYFILE, ksz) 37 var klen: i64 = 0 38 if (secret as i64) != 0 { if ksz[0] > 0 { klen = ksz[0]; pw(" keyfile: reused existing ("); pn(klen); pw(" bytes)\n" as *u8) } } 39 if klen == 0 { 40 let kb: *u8 = sys_mmap(64) 41 if fill_rand(kb, 32) != 0 { pw(" cannot read /dev/urandom -> RED\n" as *u8); return 1 } 42 let kf: i64 = sys_openat_wr(KEYFILE, 0x180) // 0600 43 if kf < 0 { pw(" cannot write keyfile -> RED\n" as *u8); return 1 } 44 sys_write(kf, kb, 32); sys_close(kf) 45 secret = kb; klen = 32 46 pw(" keyfile: GENERATED 32 random bytes -> dev_cap_secret.key (0600)\n" as *u8) 47 } 48 // 2. mint a dev_build cap valid ~1 year, unique-ish nonce from the clock 49 let now: i64 = sys_now_realtime_sec() 50 let exp: i64 = now + DEV_MAGIC_31536000 51 let nonce: i64 = now 52 let tok: *u8 = sys_mmap(DEV_MAGIC_2048) 53 let tn: i64 = capt_issue(secret, klen, "dev_build" as *u8, 9, exp, nonce, tok, DEV_MAGIC_2048) 54 if tn <= 0 { pw(" mint failed -> RED\n" as *u8); return 1 } 55 let tf: i64 = sys_openat_wr(TOKFILE, 0x180) 56 if tf >= 0 { sys_write(tf, tok, tn); sys_close(tf) } 57 pw(" minted dev_build cap ("); pn(tn); pw(" bytes) -> dev_cap.tok (exp=+1yr)\n" as *u8) 58 59 // 3. self-verify the full authorized chain 60 var pass: i64 = 0 61 let v1: i64 = capt_verify(secret, klen, tok, tn, "dev_build" as *u8, 9, now) 62 if v1 == CAPT_OK { pw(" T1 keyfile-secret verifies the minted cap for dev_build: PASS\n" as *u8); pass=pass+1 } else { pw(" T1 FAIL v="); pn(v1); pw("\n" as *u8) } 63 // wrong tool -> DENY_TOOL 64 let v2: i64 = capt_verify(secret, klen, tok, tn, "other_tool" as *u8, 10, now) 65 if v2 == CAPT_DENY_TOOL { pw(" T2 cap does NOT grant other_tool (least-authority): PASS\n" as *u8); pass=pass+1 } else { pw(" T2 FAIL v="); pn(v2); pw("\n" as *u8) } 66 // ISOLATION: a cap minted with the const/dev secret must NOT verify against the keyfile secret 67 let ctok: *u8 = sys_mmap(DEV_MAGIC_2048) 68 let ctn: i64 = capt_issue(DEV_CONST_SECRET, capt_slen(DEV_CONST_SECRET), "dev_build" as *u8, 9, exp, nonce, ctok, DEV_MAGIC_2048) 69 let v3: i64 = capt_verify(secret, klen, ctok, ctn, "dev_build" as *u8, 9, now) 70 if v3 == CAPT_DENY_MAC { pw(" T3 const-secret cap REJECTED by keyfile secret (isolation): PASS\n" as *u8); pass=pass+1 } else { pw(" T3 FAIL v="); pn(v3); pw("\n" as *u8) } 71 72 pw("DEVCAP-PROVISION pass="); pn(pass); pw("/3" as *u8) 73 if pass==3 { pw(" verdict=GREEN -- keyfile + operator cap provisioned, chain self-verified\n" as *u8); return 0 } 74 pw(" verdict=RED\n" as *u8) 75 return 1 76}