Back to Blog
Developer ToolsSecurityTutorialBest Practices

SSH Keys, API Keys, and .env Files -- The Developer Security Guide You Actually Need

Published on April 4, 202611 min read

SSH Keys, API Keys, and .env Files -- The Developer Security Guide You Actually Need

Every developer has done it at least once -- accidentally committed an API key to a public repository, pushed a .env file with database credentials, or left a secret hardcoded in source code. Some developers learn this lesson from a blog post. Others learn it from a surprise AWS bill.

This guide covers the security fundamentals that every developer needs: SSH keys, API key management, environment variables, and the practices that keep your credentials safe.


SSH Keys -- Stop Typing Your Password

SSH keys replace password authentication with cryptographic key pairs. Instead of typing your GitHub password every time you push, your machine proves its identity with a key.

How SSH Keys Work

An SSH key pair consists of two files:

  • Private key -- stays on your machine, never shared with anyone. This is like your house key.
  • Public key -- uploaded to services like GitHub, servers, etc. This is like the lock on your door.

When you connect to a server, your machine uses the private key to prove that it owns the corresponding public key. No password is transmitted.

Generating an SSH Key

> ssh-keygen -t ed25519 -C "your.email@example.com"

When prompted:

  • File location: Press Enter to accept the default (~/.ssh/id_ed25519)
  • Passphrase: Enter a strong passphrase. This encrypts your private key on disk, so even if someone copies the file, they cannot use it without the passphrase.

This creates two files:

  • ~/.ssh/id_ed25519 -- your private key (never share this)
  • ~/.ssh/id_ed25519.pub -- your public key (safe to share)

Adding Your Key to the SSH Agent

The SSH agent remembers your passphrase so you do not have to type it every time:

> eval "$(ssh-agent -s)"

> ssh-add ~/.ssh/id_ed25519

On macOS, add this to your ~/.ssh/config to use the Keychain:

> Host *

> AddKeysToAgent yes

> UseKeychain yes

> IdentityFile ~/.ssh/id_ed25519

Adding Your Key to GitHub

Copy your public key:

> cat ~/.ssh/id_ed25519.pub

Go to GitHub -> Settings -> SSH and GPG Keys -> New SSH Key. Paste the public key and save.

Test the connection:

> ssh -T git@github.com

You should see: "Hi username! You've authenticated successfully."

Switch Your Repos to SSH

If your repositories use HTTPS URLs, switch them to SSH:

> git remote set-url origin git@github.com:username/repo.git

Now you can push and pull without entering a password.

Multiple SSH Keys

If you have separate keys for work and personal accounts, use your SSH config:

> # Personal GitHub

> Host github.com-personal

> HostName github.com

> User git

> IdentityFile ~/.ssh/id_ed25519_personal

>

> # Work GitHub

> Host github.com-work

> HostName github.com

> User git

> IdentityFile ~/.ssh/id_ed25519_work

Then clone repos with the alias:

> git clone git@github.com-work:company/repo.git


API Keys -- Treat Them Like Passwords

API keys grant access to services. Treat every API key like a password -- because to the service, it is one.

Rules for API Keys

  1. 1Never hardcode API keys in source code. Not even temporarily. Not even in a test file. Not even in a branch you plan to delete.
  2. 2Never commit API keys to Git. Even if you delete them in the next commit, they remain in the Git history forever. Bots actively scan GitHub for exposed keys.
  3. 3Use environment variables to pass keys to your application at runtime.
  4. 4Rotate keys regularly. If you suspect a key has been exposed, rotate it immediately.
  5. 5Use separate keys for development and production. Never use your production Stripe key in development.
  6. 6Set the minimum required permissions. If an API key only needs read access, do not give it write access.

What Happens When Keys Leak

This is not hypothetical. Real consequences include:

  • AWS keys: Cryptominers spin up hundreds of instances. Developers have received bills for $50,000+ within hours.
  • Stripe keys: Attackers can process fraudulent payments or access customer data.
  • Database credentials: Complete data breach. Your users' data is stolen.
  • SendGrid/Mailgun keys: Attackers send spam from your domain, getting you blacklisted.

GitHub scans every push for known key formats and notifies the service provider. But this is a safety net, not a strategy.


Environment Variables and .env Files

Environment variables are the standard way to pass configuration and secrets to your application without putting them in code.

The .env File

Create a .env file in your project root:

> DATABASE_URL=postgres://user:password@localhost:5432/myapp

> REDIS_URL=redis://localhost:6379

> API_KEY=sk_test_abc123

> JWT_SECRET=your-jwt-secret-here

> SMTP_HOST=smtp.mailtrap.io

> SMTP_USER=your-smtp-user

> SMTP_PASS=your-smtp-password

Loading .env Files

Node.js -- use the dotenv package:

> npm install dotenv

At the top of your entry file:

> require("dotenv").config();

> // or with ES modules:

> import "dotenv/config";

Access variables:

> const dbUrl = process.env.DATABASE_URL;

Python -- use python-dotenv:

> pip install python-dotenv

> from dotenv import load_dotenv

> import os

>

> load_dotenv()

> db_url = os.getenv("DATABASE_URL")

The Golden Rule: Never Commit .env Files

Add .env to your .gitignore immediately:

> # .gitignore

> .env

> .env.local

> .env.production

> .env*.local

Create an .env.example File

Instead of committing actual secrets, commit a template file called .env.example with placeholder values:

> DATABASE_URL=postgres://user:password@localhost:5432/myapp

> REDIS_URL=redis://localhost:6379

> API_KEY=your-api-key-here

> JWT_SECRET=generate-a-random-string-here

This tells other developers which variables they need without exposing actual values. Include setup instructions in your README.


Checking for Leaked Secrets

In Your Git History

If you think you might have committed a secret, check:

> git log --all --full-history -p -- .env

> git log --all --full-history -p -S "your_api_key_here"

The second command searches all commits for a specific string.

Removing Secrets from Git History

If you find a committed secret, just deleting it in a new commit is not enough. The old commit still contains it.

Option 1: Use git-filter-repo (recommended):

> pip install git-filter-repo

> git filter-repo --path .env --invert-paths

Option 2: Use BFG Repo-Cleaner:

> bfg --delete-files .env

> git reflog expire --expire=now --all

> git gc --prune=now --aggressive

After either option, force-push to overwrite the remote history. Then immediately rotate every exposed credential.

Pre-Commit Hooks

Use tools like git-secrets or detect-secrets to prevent accidental commits:

> # Install git-secrets

> brew install git-secrets

>

> # Set up in your repo

> git secrets --install

> git secrets --register-aws

This adds a pre-commit hook that blocks commits containing AWS key patterns.


Secret Management in Production

For production deployments, .env files are not enough. Use proper secret management:

Platform-Native Solutions

  • Vercel/Netlify: Built-in environment variable management in the dashboard. Set variables per environment (development, preview, production).
  • GitHub Actions: Repository secrets and environment secrets (Settings -> Secrets)
  • Docker: Use Docker secrets or pass environment variables at runtime, never bake them into images.

Dedicated Secret Managers

For larger applications:

  • HashiCorp Vault -- the industry standard for secret management
  • AWS Secrets Manager -- tight integration with AWS services
  • Google Secret Manager -- same for GCP
  • Azure Key Vault -- same for Azure
  • Doppler -- developer-friendly, works with any platform

These tools provide:

  • Centralized secret storage
  • Automatic rotation
  • Access logging and audit trails
  • Fine-grained access control

Security Checklist for Every Project

Run through this checklist at the start of every project:

  • .env is in .gitignore
  • .env.example exists with placeholder values
  • No secrets are hardcoded in source code
  • SSH keys are set up for Git authentication
  • API keys use minimum required permissions
  • Different credentials for development and production
  • Pre-commit hooks scan for secrets
  • Team members know how to handle a key leak

What to Do When You Leak a Secret

It will happen eventually. When it does:

  1. 1Rotate the credential immediately. Do not wait. Generate a new key and invalidate the old one.
  2. 2Remove it from Git history using git-filter-repo or BFG.
  3. 3Force push the cleaned history.
  4. 4Check access logs on the affected service for unauthorized activity.
  5. 5Notify your team. If it is a shared credential, everyone needs the new key.
  6. 6Set up prevention (pre-commit hooks, secret scanning) so it does not happen again.

The first 5 minutes after discovery are critical. The longer an exposed key stays active, the more damage can be done.


Quick Reference

  • Generate SSH key: ssh-keygen -t ed25519 -C "email"
  • Test SSH connection: ssh -T git@github.com
  • Create .env.example: cp .env .env.example, then replace values with placeholders
  • Search for secrets in history: git log --all -p -S "secret_string"
  • Block secret commits: git secrets --install && git secrets --register-aws

Security is not about being paranoid. It is about building habits that protect you and your users by default. The five minutes it takes to set up proper key management today saves you from the five-alarm fire of a credential leak tomorrow.

For more developer guides and free tools, check out our blog and explore our developer tools.

Explore Our Free Tools & Games

Check out our curated collection of completely free browser games, tools, and extensions.

Browse Free Stuff

More Articles

Developer ToolsJSON

Stop Squinting at Messy JSON - Format It Instantly (Free Tool Inside)

Messy JSON is a productivity killer. Learn why formatting matters, common JSON pitfalls developers hit daily, and try our free browser-based JSON Formatter that works instantly with zero sign-ups.

7 min readRead More→
Browser GamesFree Games

Best Free Browser Games You Can Play Right Now in 2025

Discover the top free browser games of 2025 that require no downloads, no installs, and no sign-ups. From puzzle games to multiplayer adventures, these games run right in your browser.

8 min readRead More→
Developer ToolsFree Tools

Free Developer Tools Every Programmer Needs in Their Toolkit

A comprehensive guide to the best free developer tools available online. From JSON formatters to regex testers, these browser-based tools will supercharge your productivity.

10 min readRead More→
Chrome ExtensionsProductivity

10 Free Chrome Extensions That Will Boost Your Productivity

These free Chrome extensions will transform how you browse, work, and manage your time online. From tab management to dark mode, these extensions are must-haves.

7 min readRead More→