ikvm-gateway
A standalone transcoding proxy that bridges a Supermicro HTML5 iKVM console (the proprietary Nuvoton/InsydeVNC protocol with an ATEN AST2100 video codec) to a standard RFB/VNC stream over WebSocket, so any stock noVNC client can view and control the BMC console. Credentials never reach the browser.
[noVNC browser] <-- standard RFB 3.8 over WS, security None (our origin) --> [ikvm-gateway]
|
InsydeVNC over WSS (SID cookie + token) / TLS
v
[Supermicro BMC]
How it works
- Upstream (
src/ikvm_gateway/upstream/) — authenticates to the BMC (web login -> SID cookie; Redfish OEM IKVM launch -> per-sessionentry_valuetoken), openswss://<bmc>/, completes the InsydeVNC type-16 handshake (echoRFB 055.008, security type0x10, sendtoken[24] + zero[24]), then decodes each0x57AST2100 rectangle into an RGB framebuffer. - Decoder (
rust/, shipped asikvm_gateway._ast2100) — the AST2100 codec, implemented in Rust (PyO3), reimplemented from the board's own served decoder. Full-frame decode is ~1-3 ms. It is bundled into the same wheel as the Python package. - Downstream (
src/ikvm_gateway/downstream/) — a standard RFB 3.8 server offering security None, serving the framebuffer as Raw over a binary WebSocket. Stock noVNC connects directly. - Input (
src/ikvm_gateway/input/) — translates RFB key/pointer events (X11 keysyms) into ATEN HID KeyEvent/PointerEvent messages.
Install
From PyPI (prebuilt wheels bundle the native decoder; no Rust toolchain needed):
pip install ikvm-gw
For development, requires Python >= 3.12, uv, and a Rust toolchain. The project builds as a single maturin mixed Rust/Python wheel:
uv sync
# build the Rust decoder into the venv (reads ./pyproject.toml + ./Cargo.toml)
VIRTUAL_ENV="$PWD/.venv" uv run maturin develop
Run
Provide BMC credentials in a local secret file (git-ignored), three lines:
<bmc-host-or-ip>
<bmc-username>
<bmc-password>
Start the gateway (it prints a generated control API key to stderr):
uv run python -m ikvm_gateway --secret secret --bind-host 127.0.0.1 --bind-port 5700
Use from noVNC
Turnkey local viewer
uv run python -m tools.launch_viewer --api-key <key-printed-by-the-gateway>
# then open the printed http://127.0.0.1:8800/ URL in a browser
Manual integration
The downstream is plain RFB 3.8 (security None) over a binary WebSocket, so unmodified noVNC works. The one-time session ticket is presented via the WebSocket subprotocol:
- Server-side (never in the browser), fetch a ticket with the API key:
GET http://<gateway>/sessions Authorization: Bearer <API_KEY> -> {"status":200,"message":"session ticket issued","data":{"ticket":"<ticket>"}} - Connect noVNC, passing the ticket as a WebSocket subprotocol:
new RFB(document.getElementById("screen"), "ws://<gateway>/vnc", { wsProtocols: ["<ticket>"], });
Security model (per REQUIREMENTS.md §8)
- BMC credentials and the session token never reach the browser; the gateway terminates upstream auth and offers RFB security None downstream.
- The BMC host is fixed from server configuration (the
secretfile / config), never taken from a client request — no SSRF. - The downstream control endpoint requires a bearer API key (constant-time compared). It issues one-time, short-TTL tickets; the ticket is consumed on the WebSocket handshake and never appears in a URL, query string, or log.
- Per-session and global concurrency caps, idle and max-duration timeouts, and send-side backpressure are enforced.
- Upstream TLS to the BMC uses an unverified context (self-signed BMC certs are the norm; the management network is the trust boundary).
Status and limitations (v1)
- Verified end-to-end against a live Supermicro AST2500/2600 board: the console renders in a standard RFB client and keyboard input reaches the host.
- The decoder is stateless, so the upstream requests full (non-incremental) frames each refresh (a full AST2100 frame decodes in ~1-3 ms). Making the decoder stateful to support incremental/skip blocks is a planned optimization.
- Downstream encoding is Raw only; Tight/ZRLE is a planned optimization to cut bandwidth.
- Only the Supermicro HTML5 / AST2100 (
0x57) path is implemented; the VQ / low-JPEG / skip block paths in the decoder are ported but not yet exercised on the wire.
Tests
uv run pytest -q # Python
cargo test # Rust decoder
Release
Tagging a version (e.g. git tag v0.1.0 && git push --tags) triggers
.github/workflows/pypi.yaml, which builds abi3 wheels (Linux x86_64/aarch64,
macOS x86_64/arm64, Windows x64) plus an sdist and publishes to PyPI via Trusted
Publishing (OIDC) — register the repo as a Trusted Publisher for the
ikvm-gw project on PyPI first.
License
GNU Lesser General Public License v3.0 or later (LGPL-3.0-or-later). See
COPYING.LESSER (LGPL terms) and COPYING (the
GPL-3.0 text the LGPL builds on).
noVNC is loaded unmodified from a CDN at runtime and is not redistributed here (noVNC is MPL-2.0).
Release files for ikvm-gw 1.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ikvm_gw-1.0.1.tar.gz | 128.6 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| ikvm_gw-1.0.1-cp312-abi3-win_amd64.whl | CPython 3.12 | abi3 | Windows x86-64 | Details |
| ikvm_gw-1.0.1-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.12 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| ikvm_gw-1.0.1-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | CPython 3.12 | abi3 | Linux glibc 2.17+ ARM64 | Details |
| ikvm_gw-1.0.1-cp312-abi3-macosx_11_0_arm64.whl | CPython 3.12 | abi3 | macOS 11.0+ ARM64 | Details |
| ikvm_gw-1.0.1-cp312-abi3-macosx_10_12_x86_64.whl | CPython 3.12 | abi3 | macOS 10.12+ x86-64 | Details |
Total release size: 1.4 MB
Release files / ikvm_gw-1.0.1.tar.gz
| Download URL | ikvm_gw-1.0.1.tar.gz |
|---|---|
| Size | 128.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6d2f17a20be0b9dd7adc635dafb08d44b9fd07f26b0a3e4afd0ae4caf6d91025
|
|
BLAKE2b-256 checksum How to use checksums |
a88ab2314c2c675b2d2a4e9d364ad527a16a1a7c64f5a8c3dbc93649d2f29193
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 19, 2026.
Transparency logRelease files / ikvm_gw-1.0.1-cp312-abi3-win_amd64.whl
| Download URL | ikvm_gw-1.0.1-cp312-abi3-win_amd64.whl |
|---|---|
| Size | 161.7 kB |
| Tags | CPython 3.12 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
73bfc7f3e1e16f9a553ce48de989dd2915974685d0c3a26189be3e8317dc09e1
|
|
BLAKE2b-256 checksum How to use checksums |
6fe40aaf4f3a020b8bc5cfd67c8282a35d80c8965cf619728a5bc3691fa5af3e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 19, 2026.
Transparency logRelease files / ikvm_gw-1.0.1-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | ikvm_gw-1.0.1-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 294.7 kB |
| Tags | CPython 3.12 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
c53a955892a6023d5f014f090c78c1e6eddc0e9cc669df07de136e901983416f
|
|
BLAKE2b-256 checksum How to use checksums |
e7a88d4115d5bed596130cb510f5e68bf7a1da9a22b4d6f38ea40951c560cbfc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 19, 2026.
Transparency logRelease files / ikvm_gw-1.0.1-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | ikvm_gw-1.0.1-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 290.7 kB |
| Tags | CPython 3.12 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
ae391aad3ff368bd69dd94a39f80b0bcb5c69e5c7031a8989924a978a936b43c
|
|
BLAKE2b-256 checksum How to use checksums |
434008109947af6e043ced3b699a80cea4cc5bf2740bbfecaecdf41e041b16e2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 19, 2026.
Transparency logRelease files / ikvm_gw-1.0.1-cp312-abi3-macosx_11_0_arm64.whl
| Download URL | ikvm_gw-1.0.1-cp312-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 262.7 kB |
| Tags | CPython 3.12 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
98904ce1687723bd9f7d446290e045cd109091c10476399e2d6eeaae121d3e56
|
|
BLAKE2b-256 checksum How to use checksums |
49d767e917db9ed95c5da17ad5ff3a2f905e208c6b1b85c65109ecc2df2bcf5b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 19, 2026.
Transparency logRelease files / ikvm_gw-1.0.1-cp312-abi3-macosx_10_12_x86_64.whl
| Download URL | ikvm_gw-1.0.1-cp312-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 264.1 kB |
| Tags | CPython 3.12 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
cab12669cd44cdbb10ef199b75b930576236e41f7b8883217e00ede9653f859a
|
|
BLAKE2b-256 checksum How to use checksums |
5d87efd2b8a2a77d832299d76b2981e283a2e06161a9361e14b900b02fda5964
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 19, 2026.
Transparency log