Two checks, and you want both. The first is a header comparison you can write in a line. The second is not redundancy — it is what makes the first one survive a leak, and it is the only thing that stops a captured request being replayed at your endpoint or at somebody else’s.
The creator key#
Every request carries your key. Compare it in constant time against the value you stored.
import hmac, os
EXPECTED = os.environ["NEXUS_CREATOR_KEY"].encode()
def authorized(headers) -> bool:
presented = headers.get("X-Nexus-Creator-Key", "").encode()
return hmac.compare_digest(presented, EXPECTED)The Ed25519 signature#
The creator key is a shared secret sitting on your server, in an environment variable, possibly in a log. If it leaks, anyone can impersonate Nexus402 to you and take free tool calls. The signature is asymmetric: you hold only a public key, so there is nothing on your side worth stealing.
Three headers carry it:
X-Nexus-Signature: ed25519:<base64 of 64 bytes>
X-Nexus-Timestamp: <unix seconds>
X-Correlation-ID: <uuid>The signed message is exactly six fields joined by single newlines:
<method>\n<host>\n<path and query>\n<timestamp>\n<correlation id>\n<lowercase hex sha256 of the raw body>The host, and the mistake everyone makes#
Why is the host signed at all? Because every creator verifies with the same platform key today. Without the host, a request we signed for one creator would also verify at another creator's endpoint on the same path — letting one creator replay our signature at yours and collect your tool's output unpaid. Per-creator keys will make that structural; signing the host closes it now.
Three more things that silently weaken the check#
- Hash the raw body bytes, before any JSON parse or re-serialise. Re-encoding changes the bytes and the hash will not match.
- Enforce the 60-second window in both directions. Without an upper bound a future-dated request is valid forever; without a lower one a captured request replays forever.
- Join with
\\nand nothing else. No trailing newline, no spaces, no carriage returns.