backend
Response Obfuscation Architecture
This document describes the current response obfuscation behavior for protected v1 Nexus routes.
Response Obfuscation Architecture
This document describes the current response obfuscation behavior for protected v1 Nexus routes.
The canonical term for this subsystem is now response obfuscation. Older
references to encryption describe the same route family historically, but the
live implementation is the obfuscation flow documented here.
Use ../README.md for project context and
../API.md for the HTTP contract.
Overview
Nexus no longer uses the older application-layer X25519/AES session encryption flow for protected v1 data responses. The current system uses a lightweight, session-bound obfuscation layer intended to deter casual scraping and direct readability of response bodies.
Properties of the current model:
- keeps transport security on HTTPS
- obfuscates selected
2xxsuccess payloads only - leaves errors as readable JSON envelopes
- binds the obfuscation token to the authenticated JWT
session_id - does not claim strong confidentiality against a determined client operator
Current obfuscated routes:
/v1/bookDetails/v1/verses/v1/chapterSummary/v1/vedavaani/v1/vedavaani/verseAssistant
Current plain authenticated JSON routes:
/v1/session/v1/account
High-Level Flow
- Client authenticates and receives a JWT that includes
session_id - Client calls
POST /v1/session - Server creates an obfuscation session and returns:
obfuscationTokenversionexpiresAt
- Client sends
X-Obfuscation-Tokenon protected v1 data routes - Middleware validates the token and obfuscates only successful responses
- Client reverses the wrapper locally
- Client calls
DELETE /v1/sessionon logout or token invalidation
Token Model
The obfuscationToken is signed server-side and encodes:
session_idversionexp- random
nonce
Server validation checks:
- token signature
- token expiry
- supported token version
session_idmatch against the authenticated JWT- active in-memory obfuscation session presence
Response Transform
For successful protected responses only:
- Minify the response envelope keys
success -> sdata -> dcached -> cpagination -> p
- Minify route-specific payload keys using the versioned alias map
- Serialize compact JSON
- Gzip-compress the bytes
- Apply the reversible nonce-seeded byte transform
- Base64url-encode the result
Headers on obfuscated success responses:
Content-Type: application/octet-stream
X-Obfuscated: 1
X-Obfuscation-Version: v1
Errors are never obfuscated.
Client Integration Notes
Development/debug mode can bypass obfuscation on protected success responses by sending:
x-debug-raw-response: true
That header is intended for local development and testing only. It is honored
only when DENO_ENV is not production; production continues to obfuscate
successful protected responses even if the header is sent.
Client decode sequence:
- Base64url decode the response body
- Extract
noncefrom the obfuscation token payload - Reverse the nonce-seeded byte transform
- Gunzip
- UTF-8 decode
- JSON decode
Exact Byte Transform
The current v1 backend does not use XOR. The transform uses:
- an
offsetderived from the first nonce byte - a rotating read position into the compressed byte array
- an additive mask that uses both the nonce byte and the current index
Server-side transform:
offset = nonceBytes[0] % input.length;
for (let i = 0; i < input.length; i++) {
const sourceIndex = (i + offset) % input.length;
const salt = nonceBytes[(i + offset) % nonceBytes.length];
output[i] = (input[sourceIndex] + salt + i) % 256;
}
Client-side reverse transform:
offset = nonceBytes[0] % input.length;
for (let i = 0; i < input.length; i++) {
const salt = nonceBytes[(i + offset) % nonceBytes.length];
rotated[i] = (input[i] - salt - i + 512) % 256;
}
for (let i = 0; i < input.length; i++) {
const targetIndex = (i + offset) % input.length;
output[targetIndex] = rotated[i];
}
Implementation Reference
Key files:
nexus/src/services/obfuscation.service.tsnexus/src/middleware/obfuscation.tsnexus/src/controllers/v1/keyExchange.controller.tsnexus/src/routes/v1/index.ts
Responsibilities:
obfuscation.service.ts- issues and validates obfuscation tokens
- stores active sessions in memory
- minifies payload keys
- applies and reverses the byte transform for tests
obfuscation.ts- enforces
X-Obfuscation-Token - skips obfuscation for non-
2xxresponses - honors
x-debug-raw-response
- enforces
keyExchange.controller.tsPOST /v1/sessioncreates a sessionDELETE /v1/sessioninvalidates the active session
Operational Notes
- The session store is in-memory and short-lived.
- Re-run
POST /v1/sessionafter JWT refresh whensession_idchanges. - Missing, expired, tampered, or mismatched tokens should return readable JSON errors so client recovery is straightforward.
- This mechanism should be paired with auth, rate limits, and abuse monitoring for actual scraping resistance.
Testing Expectations
When this flow changes, verify:
POST /v1/sessionissues a signed token for a valid JWT- tampered, expired, or mismatched tokens fail with readable JSON errors
- protected routes return obfuscated success payloads
- protected route errors remain plain JSON
DELETE /v1/sessioninvalidates the current token- raw-response debug mode still returns plain JSON
- deobfuscation fixtures round-trip to the original envelope