snapkitty
developer-tools
python
File size: 2,614 Bytes
40636aa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/**
 * Sovereign Node Key β€” SnapKitty execution gate.
 * Without a valid key, model routing refuses to compute.
 * 
 * Get your key: licensing@snapkittywest.dev
 * Copyright (C) 2026 Bel Esprit D'Accord Irrevocable Trust (EIN 42-697643)
 */

import { createHmac, timingSafeEqual } from 'crypto'

const KEY_PREFIX = 'SNK-'
const KEY_HEADER = 'x-sovereign-node-key'
const KEY_ENV = 'SNAPKITTY_NODE_KEY'

const WALL = `
  ╔══════════════════════════════════════════════════╗
  β•‘     SOVEREIGN NODE KEY REQUIRED                  β•‘
  β•‘                                                  β•‘
  β•‘  This software requires a valid SnapKitty       β•‘
  β•‘  node key to activate model routing.            β•‘
  β•‘                                                  β•‘
  β•‘  Get your key:                                   β•‘
  β•‘  licensing@snapkittywest.dev                     β•‘
  β•‘  https://github.com/SNAPKITTYWEST               β•‘
  β•‘                                                  β•‘
  β•‘  Copyright (C) 2026 Bel Esprit D'Accord         β•‘
  β•‘  Irrevocable Trust (EIN 42-697643)               β•‘
  β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
`

export function verifyNodeKey(key) {
  const secret = process.env.SNAPKITTY_NODE_SECRET
  if (!key || !key.startsWith(KEY_PREFIX) || !secret) return false
  try {
    const inner = key.slice(KEY_PREFIX.length)
    const lastDash = inner.lastIndexOf('-')
    if (lastDash === -1) return false
    const payload = inner.slice(0, lastDash)
    const signature = inner.slice(lastDash + 1)
    const expected = createHmac('sha256', secret)
      .update(payload)
      .digest('hex')
      .slice(0, 32)
    const a = Buffer.from(expected)
    const b = Buffer.from(signature.padEnd(32, '0').slice(0, 32))
    return a.length === b.length && timingSafeEqual(a, b)
  } catch { return false }
}

export function requireNodeKey(key) {
  const k = key || process.env[KEY_ENV] || ''
  if (!verifyNodeKey(k)) {
    throw new Error(WALL)
  }
}

// Express / Hono middleware
export function nodeKeyMiddleware(req, res, next) {
  const key = req.headers[KEY_HEADER] || req.query?.node_key || ''
  try {
    requireNodeKey(key)
    next()
  } catch (e) {
    res.status(401).json({
      error: 'SOVEREIGN_NODE_KEY_REQUIRED',
      message: 'Valid node key required for model routing.',
      obtain: 'licensing@snapkittywest.dev'
    })
  }
}