Your bot token is the one secret that matters most. Anyone who has it can log in as your bot, read messages, ban people, spam servers, and generally cause a mess in your name. So treating that token carefully is not optional, it's the whole game. This is a practical guide to keeping it safe, plus exactly what to do if it ever gets out.
What the token actually is
When you create a bot in the Discord developer portal, Discord gives you a token. It's a long string that looks like random letters and numbers with a couple of dots in it. That string is your bot. Discord doesn't ask for a username and password when your code connects, it just checks the token. So if someone copies it, Discord can't tell them apart from you.
People leak these all the time. Usually it's an accident, like pushing code to a public GitHub repo with the token sitting right there in a variable. Bots that scan GitHub find those tokens within minutes. We've seen people lose a bot the same day they made it because of one careless commit.
Never hardcode the token in your code
The most common mistake is writing the token straight into your script. It looks harmless while you're testing, something like this in bot.py:
client.run("MTIzNDU2Nzg5...your-token-here")
Don't do this. The moment that file gets shared, screenshotted, backed up to the wrong place, or pushed to a repo, the token goes with it. And once it's in your git history, it stays there even if you delete the line later. Removing it from one commit doesn't remove it from the previous ones.
The fix is to keep the token out of your code entirely and load it from somewhere else at runtime. That somewhere is usually a .env file.
Using a.env file
A .env file is a plain text file that holds your secrets as key and value pairs. Your code reads from it, but the file itself never goes anywhere near your repo. Here's what one looks like:
DISCORD_TOKEN=MTIzNDU2Nzg5...your-token-here
DATABASE_URL=postgres://user:pass@localhost:5432/mybot
In Python with python-dotenv
Install the package, then load it at the top of your bot. You'll need python-dotenv in your requirements.txt.
import os
from dotenv import load_dotenv
load_dotenv()
token = os.getenv("DISCORD_TOKEN")
client.run(token)
In JavaScript with dotenv
Same idea on the discord.js side. Add dotenv to your package.json dependencies, then read the value from process.env.
require("dotenv").config();
const token = process.env.DISCORD_TOKEN;
client.login(token);
Now your token lives in one file that you control, and your actual code only ever refers to the name DISCORD_TOKEN, never the value. That's the whole point. You can paste your code anywhere and the secret stays behind.
Add.env to your.gitignore
Here's the part people forget. Creating a .env file does nothing if git still tracks it. You have to tell git to ignore it. Open or create a file called .gitignore in your project and add this line:
.env
Do this before your first commit. If you've already committed the file once, adding it to .gitignore won't pull it back out of history. In that case you should assume the token is already exposed and reset it (more on that in a second).
A quick warning: if you share your project as a template or example, make a .env.example file with the keys but no real values. That way other people know what to fill in, and you never accidentally ship a working secret.
DISCORD_TOKEN=
DATABASE_URL=
What to do the moment a token leaks
So you pushed the token, or pasted it somewhere public, or a friend sent you a screenshot of your editor with the token visible. Don't panic, but do move fast. The single most important step is this: reset the token in the developer portal.
Go to the Discord developer portal, open your application, head to the Bot tab, and click Reset Token. The old token stops working instantly. Anyone who copied it now holds a useless string. Then take the new token and put it in your .env file or your host's settings.
Resetting is not a big deal and it's not a sign you did something wrong. It takes about ten seconds. The only thing that breaks is anywhere you were using the old token, so you'll need to update those spots. If your bot is on a host, update the value there too and restart it.
If you even suspect a token might be exposed, reset it. There's no downside to resetting a token you weren't sure about. There's a big downside to leaving a leaked one alone.
Trying to scrub the token out of your git history with tools is fine to do afterward for tidiness, but it does not replace resetting. The token is already out. Treat it as burned and get a fresh one.
Least privilege intents and permissions
Keeping the token secret is the main job, but there's a second layer worth thinking about. The less your bot can do, the less damage anyone can do with it. This is the idea behind least privilege: only grant what you actually use.
On the gateway side, Discord has privileged intents like message content, server members, and presence. Only turn on the ones your bot needs. If your bot just runs slash commands and doesn't read message text, you don't need the message content intent at all. Leaving it off is one fewer thing to worry about.
On the permissions side, when you generate your invite link, don't tick Administrator out of laziness. Pick the specific permissions the bot uses. A moderation bot might need Kick Members and Ban Members. A music bot needs Connect and Speak. Most bots do not need Administrator, and handing it out means a compromised bot can do everything in the server.
- Turn on only the gateway intents your code reads.
- Pick specific permissions in the invite link instead of Administrator.
- Review both every so often and remove anything you stopped using.
Environment variables on a host and in CI
The .env file works great on your own machine. Once your bot moves to a server or a hosting panel, you usually set the same values as environment variables instead. Your code doesn't change, since os.getenv and process.env read environment variables either way. You're just feeding the value from a different place.
On a Linux box running your bot under systemd or pm2, you can point at an environment file or define variables in the service config. On Bytte.cloud, you set these in the control panel at panel.bytte.cloud, so the token lives in the panel and never sits in a file on disk that you might commit by accident. Either way, keep that file readable only by the user that runs the bot. Don't make it world readable.
If you use continuous integration, like GitHub Actions, never paste secrets into the workflow file. Use the platform's secrets store. In GitHub that's repository secrets, and you reference them in the workflow without the real value ever appearing in the file. Build logs can be public, so a token printed in a log is a leaked token.
A small habit that helps
Don't print your token. It's tempting to add a print(token) or console.log(token) line while debugging to check it loaded. If that output ends up in a log file or a screenshot, you've leaked it. Print the first few characters at most, or just print whether the value exists.
print("token loaded:", token is not None)
Never paste tokens in support channels
This one comes up a lot when people ask for help. Someone's bot won't start, they jump into a Discord support channel, and they paste their whole config or error log to show what's going on. The token is sitting right there in the paste.
No legitimate support person, ours included, will ever need your token to help you. If anyone asks for it, that's a red flag, full stop. When you share logs or config for help, blank out the token first. Replace it with something like DISCORD_TOKEN=hidden. If you ever do paste a real one by mistake, delete the message and reset the token right away. Deleting alone isn't enough, because someone may have already seen it.
The same goes for screenshots. People black out the wrong thing all the time, or the token is still visible in a tab behind the error. Take a second look before you hit send.
Pulling it together
Most token leaks come down to two habits. Keep the token out of your code and in a .env file or your host's settings, and make sure that file is ignored by git before you ever commit. Do those two things and you've avoided the vast majority of accidents.
If something does slip out, the fix is simple and fast: reset the token in the developer portal, update it everywhere you use it, and move on. Pair that with least privilege intents and permissions so a bad day stays small, and you're in good shape. Set it up right once, and you mostly never have to think about it again.



