MMakerToLaunch

Guides

What Files Should I NOT Upload to GitHub?

Uploading the wrong file to GitHub can leak API keys, expose user data, or hand attackers everything they need to run up your cloud bill. GitHub is where your code lives — and often where hosting platforms, collaborators, and bots read from. Treat every upload as potentially public, even if your repository is private. This guide lists what must never be uploaded, what should stay local via .gitignore, and exactly what to do if you already pushed a secret.

Updated July 2026 · 9 min read

Written for AI makers using tools like Cursor, Bolt, Lovable, Replit, Claude, and ChatGPT.

Quick answer

Never upload .env files with real secrets, private keys, production database dumps, or live API keys. Use .gitignore to exclude node_modules, build output, virtual environments, and local databases. Upload .env.example with fake values instead. If a secret was uploaded, rotate it immediately.

Who this is for

  • You are about to upload an AI-built project to GitHub for the first time
  • You are not sure which files are dangerous vs just unnecessary
  • You want a security-focused checklist before connecting a host
  • You think you may have already uploaded a secret and need to fix it

What you'll need

  • Access to your project folder on your computer
  • A text editor to create or edit .gitignore
  • Accounts for any API services whose keys might be in your project
  • Optional: our safe-upload checklist tool for a guided review

Why file choice matters for security

GitHub repositories are designed for sharing code. Bots scan public repos for API keys within seconds of a push. Private repos reduce casual exposure but do not eliminate risk — collaborators, CI tools, and accidental visibility changes still leak files.

AI coding tools make this worse by generating .env files, embedding keys in source code, and creating config you did not write yourself. You may not even know a secret exists until a scan or a bill alerts you.

The fix is structural: know what never belongs in Git, use .gitignore consistently, and upload a .env.example template so hosts and teammates know which variables to set without seeing real values.

.env files — the number one mistake

A .env file stores environment variables as key=value pairs: DATABASE_URL, OPENAI_API_KEY, STRIPE_SECRET_KEY, and dozens of others. Your app reads these at startup. Locally, .env is convenient. On GitHub, it is a live broadcast of your secrets.

Never commit .env, .env.local, .env.production, or any variant with real values. Add them all to .gitignore. Create .env.example instead — same variable names, placeholder values like your_key_here or https://example.com.

Some makers think renaming .env to .env.backup or secrets.txt hides it. Bots and scanners look for those patterns too. If the file contains real credentials, it must not be in Git regardless of filename.

  • .env → never upload
  • .env.local, .env.production → never upload
  • .env.example → safe to upload (fake values only)
  • Hard-coded keys in .js or .py files → remove and use env vars

API keys, tokens, and passwords

Any string that proves identity to a third-party service is a secret: OpenAI keys (sk-...), Stripe secret keys (sk_live_...), AWS access keys, SendGrid tokens, JWT signing secrets, and database passwords.

AI tools sometimes paste these directly into source files — a function with const apiKey = "sk-..." is a ticking time bomb. Search your project for sk_, pk_live, AIza, and password= before your first upload.

If a key was ever committed, assume it is compromised. Deleting the file from GitHub is not enough — history retains it. Rotate the key in the provider’s dashboard and generate a new one.

  • OpenAI, Anthropic, Stripe, Twilio, SendGrid keys
  • AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
  • Database passwords in connection strings
  • OAuth client secrets and JWT signing keys

Local database files

SQLite files (db.sqlite3, database.db, app.db) often contain real user data from local testing — emails, hashed passwords, session tokens. Uploading them exposes that data and bloats your repo.

Production should use a hosted database (Railway Postgres, Supabase, PlanetScale, etc.) with a DATABASE_URL environment variable. Your local SQLite file stays on your laptop for development only.

Exception: tiny empty SQLite files used only for automated tests sometimes get committed — but for AI-built apps, assume any .db file is unsafe until you verify its contents.

Generated and dependency folders

These folders are not secrets, but uploading them causes failed pushes, slow clones, and confused hosts that try to use stale dependencies instead of installing fresh ones.

node_modules/ contains thousands of npm packages — reinstall with npm install. .next/, dist/, and build/ are compiled output — regenerate with npm run build. Python’s __pycache__/ and .venv/ are machine-specific.

Add each to .gitignore. Your host’s build step recreates them. If node_modules was already committed, remove it from Git tracking, add to .gitignore, commit, and push.

  • node_modules/ — reinstall from package.json
  • .next/, dist/, build/, out/ — rebuild on deploy
  • __pycache__/, .venv/, .pytest_cache/ — Python artifacts
  • .turbo/, .cache/ — tooling caches

Certificates and private key files

Files ending in .pem, .key, id_rsa, id_ed25519, or .p12 are cryptographic private keys. They prove you are you to servers, SSH hosts, and signing services. Uploading them gives attackers your identity.

SSL/TLS certificates for local HTTPS development sometimes land in project folders. Production certificates usually live on the host or a CDN — not in your repo.

If you find a private key file in your AI-generated project, add the pattern to .gitignore and store the key outside the project directory (e.g. ~/.ssh/ for SSH keys).

  • *.pem, *.key — private certificates
  • id_rsa, id_ed25519 — SSH private keys
  • .p12, .pfx — certificate bundles with private keys
  • service-account.json — Google Cloud credentials

Use .gitignore before your first commit

A .gitignore file in your project root tells Git which patterns to skip. Create it before your first commit — it is much harder to untrack files already in history.

Start with stack-specific defaults. Node/Next.js projects need .env, node_modules/, and .next/. Django projects need .env, db.sqlite3, __pycache__/, and media/uploads if they contain user files.

Our safe-upload tool generates a starter .gitignore for common AI-built stacks. Review it, commit it, and verify in GitHub Desktop or your editor that sensitive files no longer appear in the staging area.

  • One pattern per line in .gitignore
  • Lines starting with # are comments
  • *.log ignores all .log files in any folder
  • Already tracked? Remove from Git, then ignore

If you already uploaded a secret

Act fast. Assume the secret is public even if the repo is private. Step one: rotate the compromised key in the provider’s dashboard (Stripe, OpenAI, AWS, etc.) — generate a new key and revoke the old one.

Step two: remove the file from your repository. Delete it, commit, and push. Step three: add the filename pattern to .gitignore so it does not return.

Step four: understand that Git history may still contain the secret. For high-risk exposures, GitHub offers secret scanning alerts, and you may need git filter-repo or BFG Repo-Cleaner to purge history — or create a fresh repo if the project is new. When in doubt, rotating keys is the non-negotiable minimum.

Step five: update your local .env and hosting dashboard with the new key values. Redeploy if the app broke when you revoked the old key.

  • Rotate key in provider dashboard first
  • Delete file from repo and commit
  • Add pattern to .gitignore
  • Update .env and host env vars with new key
  • Consider history purge for severe exposures

Files that are safe and helpful to upload

Not everything is dangerous. Source code (without embedded secrets), configuration templates, and documentation help you and your host understand the project.

Upload: README.md, package.json, requirements.txt, Dockerfile (without secrets in ENV lines), .env.example, LICENSE, and your application source in src/ or app/ folders.

When unsure about a file, ask: “Would I be okay if a stranger read this?” If no, keep it local or replace with a template.

  • README.md — project description and setup steps
  • .env.example — variable names with placeholders
  • package.json / requirements.txt — dependency lists
  • Source code without hard-coded secrets

Common mistakes

  • Committing .env because the AI put it there and the app needs it

    How to fix it: The app needs the values — not the file on GitHub. Use .env locally and set the same variables on your host.

  • Adding .env to .gitignore after already committing it

    How to fix it: Remove the file from Git tracking, commit the deletion, rotate all exposed secrets, and verify it does not reappear.

  • Trusting “private repo” as secret storage

    How to fix it: Private reduces risk; it does not eliminate it. Never commit live credentials to any repository.

  • Uploading a production database dump for “convenience”

    How to fix it: Use migrations and seed scripts with fake data. Real user data belongs in secured production databases only.

Copy-ready prompt

Ask your AI to audit files before upload

Paste this into Cursor, Claude, ChatGPT, Bolt, Lovable, or your AI coding tool.

Ready to paste

Review my project folder and list every file that should NOT be uploaded to GitHub. For each file or pattern, explain whether it is a security risk or just unnecessary bulk.

Check specifically for:
- .env and similar secret files
- API keys hard-coded in source code
- node_modules, build output, and cache folders
- Local database files
- Private keys and certificates

Then generate or improve a .gitignore for my stack. Do not include real secret values in your response.

Paste this into Cursor, Claude, ChatGPT, Bolt, Lovable, or your AI coding tool.

Ready check

Beginner checklist

  • Searched project for hard-coded API keys
  • .env and variants listed in .gitignore
  • .env.example created with placeholder values only
  • node_modules and build folders in .gitignore
  • Local database files excluded
  • Private key files excluded
  • Staged files reviewed before first commit
  • Upload verified on github.com — no secrets visible

Frequently asked questions

Is a private repo 100% safe for secrets?
No. Private reduces public exposure but collaborators, tokens, and misconfigured integrations still leak. Never commit live secrets — use environment variables on your host instead.
What is the difference between .env and .env.example?
.env holds real values and stays on your machine. .env.example lists variable names with fake placeholders — safe to upload so others know what to configure.
Can I delete a secret from GitHub history myself?
Deleting a file in a new commit hides it from the default view but history may retain it. Rotate the key regardless. For serious exposures, use GitHub’s guidance on removing sensitive data or start a fresh repository.
Should I upload package-lock.json or yarn.lock?
Yes. Lock files are safe and help hosts install the exact dependency versions you tested locally.
What about screenshots or design files in the repo?
Usually safe unless they contain visible API keys or user data. Large binary assets can slow clones — use judgment, but they are not security risks like .env.