---
title: "Cubie · AI Gateway Integration Kits"
subtitle: "LiteLLM + Portkey + Kong AI Gateway middleware bundles"
date: "2026-05-30"
status: "wire-tested against cubie-edge-attest.nick-9a6.workers.dev"
---

# Cubie AI Gateway Integration Kits

**Purpose.** Drop-in middleware for the three most-deployed open-source
AI gateway stacks. Each kit gates inference calls through Cubie's admit
endpoint **before** the upstream model provider is invoked, with
identical wire-contract semantics across all three.

| Kit | Hook surface | Language | Files | Target customer |
|---|---|---|---|---|
| **LiteLLM** | `CustomLogger.async_pre_call_hook` | Python | `litellm/{cubie_callback.py, litellm_config.yaml, README.md}` | Self-hosted LiteLLM proxy |
| **Portkey** | `before_request_hooks` guardrail | JavaScript (ESM) | `portkey/{cubie_guardrail.js, portkey_config.json, README.md}` | Portkey Gateway (self-host or SaaS) |
| **Kong AI Gateway** | Custom Lua plugin, `access` phase, PRIORITY=2000 | Lua | `kong/kong-plugin-cubie-admit/{handler.lua, schema.lua}` + `kong/{kong.yml, README.md}` | Kong AI Gateway 3.x |

---

## Wire contract (identical across all three)

```json
POST /admit
{
  "request_hash":   "0x<sha256(request_id)[:16]>",
  "payload_hash":   "0x<sha256(model || messages)[:16]>",
  "adapter_id":     <u32>,
  "sequence_id":    <u32>,
  "capability_hmac":"<optional; required for PASS in enforce mode>"
}

200 OK
{
  "verdict":              "PASS" | "DENY",
  "denial_class":         null | "LOCK" | "JAM" | "SHATTER" | "DEFLECT" | "DENY" | "TAMPER",
  "decision_id":          "cf-edge-<hex>",
  "cube_object_hash":     "<sha256 of envelope>",
  "latency_ns_canonical": 1657,
  "note":                 "..."
}
```

The hash format uses `0x` + first 16 hex chars of SHA-256, with `\x1e`
(ASCII record-separator) between model name and message bodies.
**This separator and prefix are the same in all three kits** — verified
in the wire-test below.

---

## HTTP status mapping (enforce mode)

| Denial class | HTTP status | Meaning |
|---|---|---|
| LOCK | 401 | Capability HMAC not provisioned, expired, or epoch-rotated |
| JAM | 429 | Quota / concurrency limit exhausted |
| SHATTER | 422 | Envelope malformed (e.g. invalid sequence) |
| DEFLECT | 451 | Policy class deny (unavailable for legal reasons) |
| DENY | 403 | Fall-through deny |
| TAMPER | 422 | Integrity check failed |

All three kits map identically.

---

## Common env vars

| Var | Default | Purpose |
|---|---|---|
| `CUBIE_ADMIT_URL` | `https://cubie-edge-attest.nick-9a6.workers.dev/admit` | Admit endpoint; swap to bare-metal sidecar in production |
| `CUBIE_CAPABILITY_HMAC` | (empty) | Required for PASS verdicts in enforce mode |
| `CUBIE_ADAPTER_ID` | `1` | Numeric adapter ID assigned to this gateway instance |
| `CUBIE_MODE` | `enforce` | `enforce` or `shadow` |
| `CUBIE_TIMEOUT_MS` (Portkey), `CUBIE_TIMEOUT_SEC` (LiteLLM), `timeout_ms` (Kong) | `250` ms | Probe timeout per admit decision |

---

## Cross-language wire-test (verified 2026-05-30)

Same inputs → same `cube_object_hash` across Python (LiteLLM kit) and
Node (Portkey kit):

```
LiteLLM (Python sha256, \x1e separator):
  decision_id     = cf-edge-66394050128126d0
  cube_object_hash = 66394050128126d0f8aa8cb823ef8f6d629686e783ab9267922cd077defb1ed3

Portkey (Node crypto sha256, \x1e separator):
  decision_id     = cf-edge-66394050128126d0
  cube_object_hash = 66394050128126d0f8aa8cb823ef8f6d629686e783ab9267922cd077defb1ed3

→ byte-identical. Hash contract is portable.
```

Kong's `resty.sha256` produces the same digest with the equivalent
`"\30"` Lua byte (30 decimal = `\x1e`).

---

## Modes

### `enforce` (default)
- DENY verdict → aborts request with HTTP status mapped from denial class
- Admit endpoint unreachable → 503 (fail-closed). LiteLLM raises a `RuntimeError`; Portkey returns `{ verdict: "DENY", denial_class: "TAMPER", status: 503 }`; Kong `kong.response.exit(503, ...)`.

### `shadow`
- DENY verdict → request proceeds, verdict is **logged** into request metadata for offline review (LiteLLM: `metadata.cubie_shadow_verdict`; Portkey: `shadow_verdict` field; Kong: `kong.log.warn`)
- Admit unreachable → request proceeds, warning logged

This is the recommended mode for the **first 7 days** of any WWT pilot deploy. See `01_ATC_Deployment_Playbook.md` §"Day 1-7 Shadow-mode observation".

---

## Production swap

For all three kits, the only env-var change at production cutover is:

```
CUBIE_ADMIT_URL=http://cubie-admit-gate.<your-cubie-namespace>:8910/v1/admit
```

The bare-metal `cubie-admit-gate` sidecar implements the same wire
contract. The kit code does NOT change.

---

## What this is NOT

These kits do NOT:
- Hold capability HMAC keys (those are provisioned by `cubie-control`)
- Write to the dual ledger (that's the admit-gate's job)
- Replace the bare-metal admit gate (this is the contract surface)
- Implement Cubie's formal verification claims (those live in the proof corpus)

They simply gate gateway traffic through the admit decision so customers
can wire their existing AI gateway stack to Cubie with ~30 minutes of work.
