API Protocol v2
Enterprise only — server issues session secrets, clients verify Ed25519, and Operations run on signed envelopes. API 1.2 / 1.3 / 1.4 stay fully supported.
api_v2). Non-Enterprise calls get HTTP 403. Everyone else keeps using /api/1.2/–/api/1.4/.Authority stays on the server — clients only transport and verify
No shared wire pepper in the SDK. Session secret comes from init. Every follow-up call carries nonce, monotonic seq, and HMAC mac. Responses are Ed25519-signed; SDKs fail closed if the signature is missing.
https://libreauth.nutexe.dev/api/v2/
Why Protocol v2
No client-held pepper
SDKs ship with public app id / ownerid and Ed25519 public key only — nothing that grants API privilege by itself.
Fail-closed crypto
Missing nonce, seq, mac, or response signature → reject. No omit-bypass.
Signed Operations
check may return a signed ops envelope — clients verify before execute; opsack needs a device signature.
1.x stays open
Free / Developer / Pro / Enterprise keep API 1.2–1.4. v2 is an Enterprise upgrade path, not a forced cutover.
Quick Start
Enterprise plan
Panel → Billing → Enterprise. Hub Plans must have Protocol v2 enabled on the tier.
Pick a v2 SDK
Copy LibreAuthV2 from the SDK Portal (login + Developer / Pro / Enterprise for View/Download) or docs SDKs. C++ sendable pack: C++ Pack.
Point URL
Use https://libreauth.nutexe.dev/api/v2/ — call Init() then Login / License. If Hash Check is on for the app, pass the exe MD5: Init($md5).
Request MAC
After init, every request must include session, ts, nonce, seq, and mac.
POST
/api/v2/
2.0
{sha256(body_json)}
{session}
{ts}
{nonce}
{seq}
mac = HMAC-SHA256(canonical, session_secret) as lowercase hex. Response headers X-Signature-Timestamp + X-Signature-Ed25519 must verify against the server public key.
AEAD response body
When the session has a stored sess_secret, authenticated replies may include X-LA-Enc: aead.
- Wire:
base64(iv16 || tag16 || ciphertext) - Key:
SHA256("la2aead|" + session_secret)(32 raw bytes) - Cipher: AES-256-GCM with 16-byte IV (OpenSSL / C++ / PHP). .NET
AesGcmonly accepts 12 — use BouncyCastle.Cryptography in C#.
licensesuccess with client AEAD decrypt failed means an outdated C# / incomplete SDK — not a bad license key.Sequence after login / license
init→ client starts atseq = 0login/licensesendsseq = 1; server rotates session and returns"seq": 0- Client must adopt that value (ForceAdopt). If
seqis missing (legacy), adopt1 - Next
checksendsadopted + 1
Client increments before the HTTP call; server bumps only after MAC OK. On unsigned Ghost/WAF 404 or pre-bump Fail, roll client seq back.
หลัง login/license SDK เก็บ pack grant — HasFeature / info.features. ดู Subscriptions & Features.
type=feature — server ticket
หลัง license เรียก Feature("inject") — เซิร์ฟตรวจแพ็กคีย์แล้วออก feature_token (TTL 60s). Lite ที่ไม่มีชื่อนั้นได้ 403 Feature not entitled. เปิด Panel Require Feature Ack เมื่อต้องการ one-shot consume.
HTTP 404 Ghost on Init
HTTP 404 Ghost — app name/ownerid not found ส่วนใหญ่ไม่ใช่ Cloudflare WAF — เซิร์ฟเรียก ApiV2::Ghost() เมื่อหาแอปไม่เจอ (ชื่อผิด / ownerid ผิด / แอปปิด)| สถานการณ์ | สาเหตุ | แก้ |
|---|---|---|
init → 404 ไม่มี X-Signature-Ed25519 | name + ownerid ไม่ตรงแถวใน apps (secret name ต้องตรงตัวอักษร) | Panel → Manage Apps → คัดลอก name + Owner ID 10 ตัว · อย่าใช้ชื่อแสดงผลผิดตัว |
| หลัง login/check → 404 unsigned | WAF / proxy กลืน body หรือ path ผิด | ยืนยัน URL /api/v2/ · ดู Cloudflare · roll seq กลับ (SDK ทำให้อยู่แล้ว) |
Panel SELECT APP ≠ config name | client Init คนละแอปกับที่เปิด Operations | ตั้งชื่อเดียวกันทั้งสองฝั่ง · Devices จะว่างถ้าคนละแอป |
SDK ทุกภาษาแยกข้อความ: Init = Ghost / app not found · request อื่น = Ghost/WAF + seq rolled back. Spec: GHOST_404.md · PROTOCOL_V2.md
Idle TTL — Invalid session on Login
Invalid session ตอนกด Login/License? ส่วนใหญ่ไม่ใช่คีย์ผิด — session จาก init ถูก wipe เพราะไม่มี API traffic นานเกิน 90 วินาที (idle_ttl).| ค่า | Default | ผล |
|---|---|---|
idle_ttl | 90s | ไม่มี request หลัง init → เซิร์ฟลบ session → login/license ได้ Invalid session |
check_stale | 45s | หลัง license แล้วไม่ check (Redis) → kill |
check_interval | 15s | client ควร poll |
- เปิดแอป →
Init→ หน้าใส่ License ค้าง > 90 วิ → กด Login → Invalid session - SDK ล่าสุด:
Login/Licenseจับ error นี้แล้ว Init ใหม่ + retry ครั้งเดียว อัตโนมัติ - อย่าสับสนกับ
Invalid license key/Invalid mac/Invalid sequence
รายละเอียด: Troubleshooting → API v2 · Error Codes → Protocol v2 · PROTOCOL_V2.md
Request Flow
init(+ optionaldevice_pubkey, optionalhash) →session,session_secret,pubkey,policy(includeshash_check,hash_auto_ban,tool_auto_ban,block_ai,idle_ttl, …)login/licensewith MAC +hwid→ rotated session +seq: 0(SDK re-Inits once if session was wiped by idle TTL)check/var/opsackwith MAC + samehwidban— self-report ban (HWID from session; unvalidated Ops may ban onlybound_hwid)- AEAD body when
X-LA-Enc: aead
type=var — Global Variables
Global app variables are never public. Server gate (VarCore::ClientAccessError):
- Session validated (login / license) + non-empty
credential - User exists, not banned, active subscription
bound_hwidset + requesthwidmust match (stolen session alone fails)- HWID/IP not blacklisted · license key not banned · optional app
hwid_lock - Fresh
checkheartbeat (v2) before firstvar - Entitlement
varenabled · name charset[A-Za-z0-9._:-]≤ 64 - Response includes
var_mac(HMAC-SHA256 over value with session secret)
Init-only sessions → Session not authenticated. Expired sub → No active subscription / heartbeat sub_expired. Panel / Seller always force authed=1.
Flow: init → license/login → check → type=var + varid + hwid. API v1: same HWID gate on var / getvar / setvar.
See Error Codes → Variables · API Endpoints.
type=ban — Client Self-Ban
Authenticated (or Ops Init-bound) clients can ask the server to ban the current machine after a Hardening trip.
- Body:
type=ban,reason(≤99 chars, e.g.tool:bad_process), optionalhwid - When session is not login-validated: server ignores client HWID and uses
bound_hwidonly - Respect panel
tool_auto_ban— only call Ban whenpolicy.tool_auto_banis true - SDK: C#
BanAsync· C++Ban· PHPBan· Pythonban
Server-side hash rejects can auto-ban without the client when hash_auto_ban is ON — see Access Controls.
Operations Envelope
On authenticated check, the server may attach a signed ops object (payload, sig, raw, optional jti). Verify Ed25519 before execute. Ack with opsack + device_sig from the enrolled device key (enroll via device_pubkey on init — kept across license/login rotation). Wire result_data as base64 + result_enc=b64; forward envelope jti once. Send the same hwid on every check/opsack so bound_hwid matches the panel target. Spec: sdk/PROTOCOL_V2.md.
- C++:
ops_executor.hpp - C#:
OpsEnvelope.cs - Places (
list_dirtokens):OPS_PLACES.md· panel guide Operations → Places - Contract:
PROTOCOL_V2.md
Official SDKs
| Language | v2 source | Docs |
|---|---|---|
| PHP | LibreAuthV2.php | Setup |
| C# | LibreAuthV2.cs | Setup |
| Python | libreauth_v2.py | Setup |
| JavaScript | libreauth-v2.js | Setup · BFF for browsers |
| Go / Java / Rust / Ruby / Perl / Lua | PROTOCOL_V2.md + language ports in portal | |
| React / Vue | BFF only — React · Vue | |
require 'LibreAuthV2.php';
$app = new LibreAuthV2('AppName', 'OWNER_ID_10', 'https://libreauth.nutexe.dev/api/v2/');
$app->Init(); // or Init($exeMd5) when Hash Check is on
$app->Login('user', 'pass', 'HWID');
Seller API + Protocol v2
Seller API (/seller-api/, sellerkey) is orthogonal to Protocol v2. It already manages apps whose clients call /api/v2/. Seller wire stays JSON + Bearer — not HMAC. See Seller API. type=info returns capabilities.api_v2.
Protocol comparison
| 1.3 | 1.4 | v2 | |
|---|---|---|---|
| Plan | All | Enterprise | Enterprise |
| Endpoint | /api/1.3/ | /api/1.4/ | /api/v2/ |
| Client pepper | Yes (wire) | Yes (opaque) | No |
| Session secret | — | — | Server-issued |
| Request MAC | — | — | HMAC required |
| Still supported | Yes | Yes | Yes (Enterprise) |