(staged as /lib/init/init-main.js); point bundle-kernel-init and verify scripts at the new path. Wire curl, wget, openssl, ssh-keygen, and tar through coreutils and booter host delegates with booter-side CLI helpers; refresh related bins, bare manifest, shell completion, and man DB (kernel + seeder). Add booter support modules for ACL evaluation, audit chain, secret handles, peer admission, replication priority, process table, swarm lifecycle, boot-graph proc, metrics, monotonic time, protomux alias registry, and swarm peer policy; extend extension resolver, VFS, swarm connection managers, IPC, identity-account, and initd. Harden bare-os-bare-libs build on esbuild failure; add verify scripts for extension manifest schema and runtime incomplete markers; extend ctx API typings, gen-ctx-client-stub, and verify-ctx-dts. Update boot hook fragment, bundled init.js, handbook and reference docs (incl. kernel security and VFS path classes).
121 lines
3.2 KiB
JavaScript
121 lines
3.2 KiB
JavaScript
/**
|
|
* Opaque key-handle registry: TTL, optional max uses, revocation (no key material).
|
|
*/
|
|
|
|
/** @typedef {{ id: string, purpose: string, algorithm: string, atMs: number, expiresAtMs: number | null, maxUses: number, uses: number, scopes: string[], revoked: boolean }} BareOsSecretHandleRow */
|
|
|
|
/** @type {Map<string, BareOsSecretHandleRow>} */
|
|
const handles = new Map()
|
|
let seq = 0
|
|
|
|
const MAX_HANDLES = 4096
|
|
|
|
/**
|
|
* @param {{ purpose?: string, algorithm?: string, ttlMs?: number | null, maxUses?: number, scopes?: string[] }} opts
|
|
*/
|
|
export function bareOsSecretHandleAcquire(opts = {}) {
|
|
if (handles.size >= MAX_HANDLES) {
|
|
for (const [id, h] of handles) {
|
|
if (h.revoked || bareOsSecretHandleIsExpired(h)) {
|
|
handles.delete(id)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
const purpose = String(opts.purpose || 'default').trim().slice(0, 64) || 'default'
|
|
const algorithm = String(opts.algorithm || 'opaque').trim().slice(0, 32) || 'opaque'
|
|
const ttlRaw =
|
|
opts.ttlMs != null
|
|
? Number.parseInt(String(opts.ttlMs), 10)
|
|
: Number.NaN
|
|
const ttlMs =
|
|
Number.isFinite(ttlRaw) && ttlRaw > 0
|
|
? Math.min(ttlRaw, 86400000)
|
|
: null
|
|
const maxUses =
|
|
opts.maxUses != null && Number.isFinite(Number(opts.maxUses)) && Number(opts.maxUses) > 0
|
|
? Math.min(1e6, Math.floor(Number(opts.maxUses)))
|
|
: 1e9
|
|
const scopes = Array.isArray(opts.scopes)
|
|
? opts.scopes
|
|
.map((s) => String(s).trim().slice(0, 48))
|
|
.filter(Boolean)
|
|
.slice(0, 8)
|
|
: []
|
|
const atMs = Date.now()
|
|
const id = `kh_${++seq}_${atMs.toString(36)}`
|
|
const row = {
|
|
id,
|
|
purpose,
|
|
algorithm,
|
|
atMs,
|
|
expiresAtMs: ttlMs != null ? atMs + ttlMs : null,
|
|
maxUses,
|
|
uses: 0,
|
|
scopes: scopes.length ? scopes : ['default'],
|
|
revoked: false
|
|
}
|
|
handles.set(id, row)
|
|
return {
|
|
handle: id,
|
|
algorithm,
|
|
atMs,
|
|
ttlMs,
|
|
scopes: row.scopes,
|
|
zeroizeAfterMs: ttlMs
|
|
}
|
|
}
|
|
|
|
/** @param {BareOsSecretHandleRow} h */
|
|
function bareOsSecretHandleIsExpired(h) {
|
|
if (h.revoked) return true
|
|
if (h.expiresAtMs != null && Date.now() > h.expiresAtMs) return true
|
|
if (h.uses >= h.maxUses) return true
|
|
return false
|
|
}
|
|
|
|
/**
|
|
* @param {string} id
|
|
* @returns {boolean}
|
|
*/
|
|
export function bareOsSecretHandleTouch(id) {
|
|
const h = handles.get(String(id || ''))
|
|
if (!h || bareOsSecretHandleIsExpired(h)) return false
|
|
h.uses++
|
|
if (h.uses >= h.maxUses) h.revoked = true
|
|
return !h.revoked
|
|
}
|
|
|
|
/**
|
|
* @param {string} id
|
|
*/
|
|
export function bareOsSecretHandleRelease(id) {
|
|
const h = handles.get(String(id || ''))
|
|
if (h) h.revoked = true
|
|
handles.delete(String(id || ''))
|
|
}
|
|
|
|
export function bareOsSecretHandlePruneExpired() {
|
|
const now = Date.now()
|
|
for (const [id, h] of handles) {
|
|
if (h.revoked || (h.expiresAtMs != null && now > h.expiresAtMs) || h.uses >= h.maxUses)
|
|
handles.delete(id)
|
|
}
|
|
}
|
|
|
|
/** Non-secret snapshot for `/proc` / posture. */
|
|
export function bareOsSecretHandleSnapshot() {
|
|
bareOsSecretHandlePruneExpired()
|
|
let active = 0
|
|
for (const h of handles.values()) {
|
|
if (!bareOsSecretHandleIsExpired(h)) active++
|
|
}
|
|
return {
|
|
schema: 1,
|
|
totalRegistered: handles.size,
|
|
activeHandles: active,
|
|
cap: MAX_HANDLES,
|
|
atMs: Date.now()
|
|
}
|
|
}
|