Keep your secrets out of your Git repository
Database passwords and API keys do not belong in code. How to move them into environment variables — and how Kernel6 stores them once you do.
Almost every website eventually needs a secret: a database password, a payment gateway key, an SMTP password for contact-form mail. The easiest place to put it is right in the code. It is also the worst place, and it is worth fixing before your repository is ever shared, made public, or handed to a new developer.
Why committed secrets are a problem
- Git remembers everything. Deleting a key in a later commit does not remove it from history — anyone with the repository can still find it.
- Repositories travel. They get cloned to laptops, forked, shared with freelancers and occasionally made public by accident.
- Rotating a key that is in code means a code change and a deploy, so in practice it does not get rotated.
If a secret has already been committed, treat it as leaked: generate a new one at the provider, then remove the old one from your code. Rewriting Git history alone is not enough if anyone has already cloned it.
The fix: read secrets from the environment
Instead of writing the value into your code, read it from an environment variable. In Node.js that is process.env:
// Before — the password is in your repository forever
const db = connect('postgres://shop:hunter2@db.example.com/shop');
// After — the code only knows the name of the setting
const db = connect(process.env.DATABASE_URL);Locally, keep the real values in a .env file and add .env to your .gitignore so it never gets committed. Many projects also commit a .env.example with the names but no values, so the next developer knows what to set.
Adding them on Kernel6
Open your project and find Environment variables. Add them one at a time, or choose Paste .env and paste the contents of your local file. The importer understands the shapes people actually paste — export KEY=value, quoted values, comments and blank lines — and a pasted value replaces an existing variable with the same name rather than creating a duplicate.
# Pasting this works as-is
DATABASE_URL=postgres://shop:…@db.example.com/shop
export SMTP_PASSWORD="…"
NEXT_PUBLIC_SITE_URL=https://www.yourshop.inSaved values take effect on your next deploy — the running app still has the old environment until then.
How Kernel6 stores them
- Encrypted at rest with AES-256-GCM. Each value gets its own random nonce, and the stored form cannot be read without the platform’s key.
- Masked in the dashboard. Values load hidden and are only shown when you choose to reveal one, so a screen share does not expose your keys.
- Decrypted only at deploy time, when they are written to a
.envfile next to your app (readable only by the app user) and exported into the app’s environment. - Never placed in the deploy script as text: values travel encoded, so special characters in a password cannot change what the script does.
A few limits worth knowing
- Names use letters, digits and underscores, and cannot start with a digit (the usual shell rule).
- Up to 100 variables per project, each value up to 4,096 characters.
- Values cannot contain line breaks. For a multi-line value such as a private key, store it base64-encoded and decode it in your app.
- Anything prefixed
NEXT_PUBLIC_in a Next.js app is built into the JavaScript sent to browsers. That is by design — so never put a real secret behind that prefix.