Storing Bybit API keys safely: a short list you can actually follow
Most key incidents are not sophisticated. A key ends up in a repository, a chat message, or an environment that more people can read than anyone intended.
Vizanix engineering · about the author
- SECTION
- Bybit API
- PUBLISHED
- 2026-08-28
- CHAPTERS
- 7
- READ NEXT
- 3
- LANGUAGE
- written in English
An exchange API key is a bearer credential. Whoever holds it can do everything it is permitted to do, from anywhere the allowlist permits, with no further authentication. Treat it accordingly and most of the practice follows.
Never grant withdrawal permission
This is the single rule that turns a catastrophe into an inconvenience. A trading bot needs trade permission and read permission. It does not need the ability to move funds off the exchange, ever.
A stolen trade-only key can lose you money through bad trading — real, but bounded and visible. A stolen withdrawal key empties the account. If a developer asks for withdrawal permission on your account, that is the end of the conversation, not the start of a negotiation.
Use the IP allowlist
Bybit lets you bind a key to specific source addresses. A key that only works from your server is dramatically less useful to anyone who copies it. This is free and it is skipped constantly because it makes the first deployment slightly harder.
The operational cost is real but small: when you move servers you must remember to update the list, and the symptom of forgetting is 10018. Map that error to a clear alert and the cost disappears.
Where the secret lives
In order of preference:
- A secret manager, if you already run one.
- A file readable only by the service user, loaded at process start —
chmod 600, owned by the account the bot runs as. - An environment variable set from a systemd unit's
EnvironmentFile, which is the same thing with a different shape.
And the places it must never live: source control, a Docker image layer, a command line (visible in ps), a log line, an error report, a screenshot in a support chat, or a message to a bot.
# Read at startup, keep in memory, never echo.
def load_secret(path: str) -> str:
st = os.stat(path)
if st.st_mode & 0o077:
raise SystemExit(f"{path} is group/world readable — refusing to start")
return pathlib.Path(path).read_text().strip()
# In every log formatter, in every exception handler:
def redact(text: str) -> str:
return API_KEY_RE.sub("***", text)That second function matters more than it looks. Keys leak into logs through exception tracebacks that include the request headers. Redaction at the log formatter is the only place that catches all of them.
Keys must not travel through Telegram
A Telegram control plane is genuinely useful — it is how our own executor is operated. But there is a hard line: the bot accepts commands through Telegram, never secrets.
A key pasted into a chat exists in Telegram's servers, in the chat history of every participant, in desktop client caches and in whatever backup those devices make. It cannot be unsent. If a system asks you to send an API key to a bot, that system is designed wrong.
The correct flow is that keys are placed on the server by the person who owns them, and the chat interface can only refer to them by name.
One key per purpose
Separate keys for separate bots, and separate keys for read-only monitoring. The benefit shows up during an incident: you can revoke the one that misbehaved without stopping everything else, and the venue's own logs tell you which component did what.
This is also what makes multi-account operation tractable. Our executor supports several keys per user, each with its own strategy, its own universe and its own statistics — which only works because a key is a unit of isolation rather than a shared global.
Rotation, and having a plan
Rotate on schedule and immediately on any suspicion. The thing that makes rotation painful is not the cryptography, it is discovering at 2am that nobody knows which services use that key.
Write the answer down before you need it: which key, which service, which host, who owns it, how to revoke it. A key inventory is a boring document that becomes very valuable exactly once.
The short version
- Trade permission only. Never withdrawal.
- IP allowlist on, always.
- Secret in a mode-600 file or a secret manager, loaded at start.
- Redaction in the log formatter, not at each call site.
- No secrets through chat interfaces, ever.
- One key per bot, per account, per purpose.
- A written inventory and a rotation you have actually rehearsed.
This article describes engineering practice. It is not investment advice. Vizanix develops software and does not promise trading returns.