verify-rhf-kn0-deploy-proof.mjs
sha256:4215cecbbabf5591b1ff69053cc938b4b6c800f0d487be40618c1d4254d8b67b
security: npm audit fix pre-bridge 2026-09-05
Human
1 day ago
| 1 | #!/usr/bin/env node |
| 2 | /** |
| 3 | * RHF-b-KN0 hosted deploy proof — session + legacy_session grant mint denial. |
| 4 | * |
| 5 | * Uses hub-session-auth (refresh) for type:session; optional SESSION_SECRET for legacy_session. |
| 6 | * Records status + JSON code only (no JWTs). |
| 7 | * |
| 8 | * Usage: |
| 9 | * node scripts/hub-session-refresh.mjs --save-refresh '<ktn_refresh>' # once |
| 10 | * node scripts/verify-rhf-kn0-deploy-proof.mjs |
| 11 | */ |
| 12 | |
| 13 | import path from 'node:path'; |
| 14 | import { fileURLToPath } from 'node:url'; |
| 15 | import dotenv from 'dotenv'; |
| 16 | |
| 17 | import { |
| 18 | ensureHostedSessionAccessToken, |
| 19 | mintLegacySessionAccessToken, |
| 20 | } from './lib/hub-session-auth.mjs'; |
| 21 | |
| 22 | const __dirname = path.dirname(fileURLToPath(import.meta.url)); |
| 23 | dotenv.config({ path: path.join(__dirname, '..', '.env') }); |
| 24 | |
| 25 | const apiBase = (process.env.KNOWTATION_HUB_API || process.env.KNOWTATION_HUB_URL || 'https://api.knowtation.store').replace(/\/$/, ''); |
| 26 | const vaultId = process.env.KNOWTATION_HUB_VAULT_ID || 'default'; |
| 27 | |
| 28 | /** @type {{ probe: string, status: number, code: string | null, pass: boolean, note?: string }[]} */ |
| 29 | const rows = []; |
| 30 | |
| 31 | /** |
| 32 | * @param {string} probe |
| 33 | * @param {string} accessToken |
| 34 | */ |
| 35 | async function probeGrantMint(probe, accessToken) { |
| 36 | const res = await fetch(`${apiBase}/api/v1/delegation/grants`, { |
| 37 | method: 'POST', |
| 38 | headers: { |
| 39 | Accept: 'application/json', |
| 40 | 'Content-Type': 'application/json', |
| 41 | Authorization: `Bearer ${accessToken}`, |
| 42 | 'X-Vault-Id': vaultId, |
| 43 | }, |
| 44 | body: JSON.stringify({ |
| 45 | consent_id: 'deploy-proof-smoke', |
| 46 | actor_agent_id: 'agent_deploy_proof', |
| 47 | task_ref: 'kn0-deploy-proof', |
| 48 | }), |
| 49 | signal: AbortSignal.timeout(20_000), |
| 50 | }); |
| 51 | let json = {}; |
| 52 | try { |
| 53 | json = await res.json(); |
| 54 | } catch { |
| 55 | json = {}; |
| 56 | } |
| 57 | const code = typeof json.code === 'string' ? json.code : null; |
| 58 | const pass = res.status === 403 && code === 'DELEGATION_HELPER_ACTOR_DENIED'; |
| 59 | rows.push({ probe, status: res.status, code, pass }); |
| 60 | console.log(`[${pass ? 'PASS' : 'FAIL'}] ${probe} HTTP ${res.status} code=${code ?? '(none)'}`); |
| 61 | } |
| 62 | |
| 63 | const session = await ensureHostedSessionAccessToken(); |
| 64 | if (!session.ok) { |
| 65 | console.error(`session auth: ${session.code} — ${session.detail}`); |
| 66 | process.exit(1); |
| 67 | } |
| 68 | await probeGrantMint('type:session', session.accessToken); |
| 69 | |
| 70 | const legacy = mintLegacySessionAccessToken(); |
| 71 | if (legacy.ok) { |
| 72 | await probeGrantMint('legacy_session', legacy.accessToken); |
| 73 | } else { |
| 74 | rows.push({ |
| 75 | probe: 'legacy_session', |
| 76 | status: 0, |
| 77 | code: null, |
| 78 | pass: false, |
| 79 | note: legacy.detail, |
| 80 | }); |
| 81 | console.log(`[SKIP] legacy_session — ${legacy.code}: ${legacy.detail}`); |
| 82 | } |
| 83 | |
| 84 | const allRequiredPass = rows.filter((r) => r.probe !== 'legacy_session' || legacy.ok).every((r) => r.pass); |
| 85 | const verdict = allRequiredPass ? 'PASS' : 'FINDINGS'; |
| 86 | console.log(`\nVerdict: ${verdict}`); |
| 87 | process.exit(allRequiredPass ? 0 : 1); |
File History
1 commit
sha256:4215cecbbabf5591b1ff69053cc938b4b6c800f0d487be40618c1d4254d8b67b
security: npm audit fix pre-bridge 2026-09-05
Human
1 day ago