your brief, your key/your key, checked
Sending your own model key to somebody else's server is a real risk, and you are right to hesitate. This page does not ask you to trust us. It shows you every line of ours that touches your key, and the test that turns red if that ever changes.
Your key reaches one destination, and nowhere else.
We are not going to tell you your key is safe — that is a word nobody can check. The claim is narrower and testable: when you send x-llm-key, it is used to authenticate exactly one outbound call to OpenRouter, and it is never written to a log, a cache, a disk, or a response. Everything below is the evidence for that sentence.
ByokHeader · app/main.py
score() · app/scorer.py
complete() · app/llm_client.py
Four places people reasonably worry about. In each case the reason it cannot be there matters more than our promise that it is not.
| the worry | why it cannot happen |
|---|---|
| In the logs |
Our access log format is client address, request line, status — headers and bodies are not part of it. The one place that logs on failure prints a Python traceback, and Python tracebacks carry source lines, not the values of local variables. What lands in the log is the literal text of the f-string that builds the header, never the key it built.
uvicorn CMD · Dockerfile — log.exception() · app/main.py
|
| In the cache |
A BYOK score never reads or writes the shared verdict cache. Service-funded cached verdicts are keyed by ruleset_version : model : strategy : sha256(brief); no key material is stored in either keys or values.
_judge() · app/scorer.py
|
| In an error response |
When the provider rejects a call we return a 502. It used to include the underlying error text, which is exactly the shortcut secrets escape through — your key is a header on the very request that just failed. It now returns a fixed string, and the detail is logged server-side instead. That is safe by construction rather than safe because of which exception happened to arrive.
post_score() · app/main.py
|
| In your browser |
In the console, the key field is a password input with autocomplete off, and the value lives in a single JavaScript variable. It is never written to localStorage or sessionStorage, so it does not survive a reload and cannot be read later by anything else served from this origin.
#byok · site/console.html
|
Prose is not a guarantee. A failing build is.
Everything above describes the code as it is today, and a page cannot stop somebody adding a well-meaning debug line next year. So the claim is also a test. It sends a real request to every endpoint that accepts your key, each with a sentinel value, then hunts that sentinel through every channel this service can emit on — every log record, anything printed to stdout or stderr, the response body, the response headers, and everything handed to Redis — and fails unless it appears in exactly one place: the Authorization header of the call to OpenRouter.
assert call["headers"]["authorization"] == f"Bearer {CANARY}"
assert CANARY not in response.text
assert CANARY not in str(dict(response.headers))
for key, value in redis_writes:
assert CANARY not in key and CANARY not in str(value)
for record in caplog.records:
assert CANARY not in caplog.handler.format(record)
captured = capfd.readouterr() # a bare print() leaks past every
assert CANARY not in captured.out # log-record assertion above
assert CANARY not in captured.err
It runs on every commit, and we check that it can fail: adding a single log.debug of the key turns it red. Read it, or run it yourself — tests/test_byok_leak.py.
Three parties see your key, not one. TLS protects it in transit, but it does not terminate at the code above. briefs.welance.com sits behind Cloudflare, which decrypts every request — your key included — before a second hop to our own server, where it lives in memory for the moment your request is in flight. So it is seen by Cloudflare, by us, and by OpenRouter. Anyone who has compromised either server could read it, and Cloudflare's terms govern their leg of it, not ours. This is true of every service that forwards a credential on your behalf, and no amount of care in our code changes it. If that risk is unacceptable for your key, it should be — do not send it, and see the options below.
BYOK scores are always fresh. Supplying your key bypasses both reads and writes to the shared verdict cache. Service-funded calls may use the 24-hour cache unless they send no_cache: true.
Downstream is not ours. Once the call reaches OpenRouter, their terms and their retention apply, not ours. We can tell you what we do; we cannot make promises on their behalf.
This is a small open-source service. It is rate-limited and served over TLS by people who care about getting this right. It is not an audited compliance product, and we would rather say so here than imply otherwise.
And we have an interest to declare. This bar gates welance's own Directory, and welance pitches there as a team like any other. What that obliges us to — no lead-mining from briefs, no training, the same bar for our own briefs, provably — is written out in the Operator Covenant.
Send a spend-capped key. OpenRouter lets you mint a key with its own credit limit. Use one here rather than your main key: it turns the worst case from an open-ended loss into a known, small number, and it costs you nothing.
Or send no key at all. Leave the header off and the call runs on our spend-capped key. welance uses V4 Pro for authoritative scoring and V4 Flash for suggestions and verification; Sonnet is not enabled.
Or run the whole thing yourself. It is MIT-licensed and the container is one command. Then the only server that sees your key is yours — github.com/welance/perfect-brief.
If you find a path that stores, logs, or echoes a caller's key, that is a vulnerability and we want to hear about it before anyone else does: report it privately or write to [email protected]. Our full policy, including scope, is in SECURITY.md.