Mahamudul Hasan Rubel
HomeAboutProjectsSkillsExperienceBlogPhotosContact
Mahamudul Hasan Rubel

Senior Software Engineer crafting high-performance web applications and SaaS platforms.

Navigation

  • Home
  • About
  • Projects
  • Skills
  • Experience
  • Blog
  • Photos
  • Contact

Get in Touch

Available for senior/lead roles and consulting.

bd.mhrubel@gmail.comHire Me

© 2026 Mahamudul Hasan Rubel. All rights reserved.

Built with using Next.js 16 & Tailwind v4

Back to Blog
SecurityJune 20, 20265 min read

Handling secrets securely to prevent accidental credential leakage

Handling secrets securely is non-negotiable for production apps. Learn how to stop leaking API keys and database credentials in your codebase today.

securitysecrets-managementdevopsbest-practicesweb-developmentWebBackend
Focus on password security with white keyboard tiles spelling 'PASSWORD' on a coral background.

I remember the sinking feeling of getting an automated alert from GitHub that a DB_PASSWORD had been pushed to a public repository. It took about 40 minutes of frantic remediation—revoking keys, rotating database credentials, and scrubbing commit history—to fix a mistake that shouldn't have happened in the first place.

Handling secrets securely isn't just about security theater; it's about building a workflow that makes the right thing the easiest thing to do. If your configuration management feels like a chore, you’re more likely to cut corners.

The Problem with Hardcoded Secrets

We've all seen it: a config.js file with a hardcoded Stripe API key or an AWS secret nestled directly in a deployment script. It’s tempting, especially during early development, but it creates a permanent footprint in your Git history. Even if you delete the file in the next commit, that secret remains in the history for anyone with read access to the repository.

When I started out, I treated .env files like magic. I’d create them, forget to add them to .gitignore, and wonder why my local setup felt so brittle. You have to treat environment variables as external dependencies, not configuration code.

Handling secrets with environment-based injection

The industry-standard approach for most full-stack applications is using .env files for local development combined with a dedicated secrets manager for production. Tools like dotenv for Node.js or native support in frameworks like Laravel make this relatively straightforward.

However, the "local development" part is where most leaks occur. To keep your sanity, follow these rules:

  1. Never commit .env files. Add them to your .gitignore immediately.
  2. Use a .env.example template. This file should contain keys but no values. It serves as documentation for your team.
  3. Validate your config. If your app requires a STRIPE_KEY to function, verify it exists at startup. If it's missing, throw a clear error.

I often see developers struggle to designing error responses clients can actually use for your API because they don't have a centralized config loader. By validating your environment variables the moment your app boots, you catch missing secrets in development instead of waiting for a production crash.

Moving beyond local files

Professional man organizing office belongings in a cardboard box, preparing for transition.

Once you move past local development, local .env files are no longer sufficient. You need a centralized way to inject secrets into your runtime environment.

For cloud-native deployments, I prefer using native secret management services. If you’re on AWS, use Secrets Manager or Systems Manager Parameter Store. If you're on GCP, use Secret Manager. These services allow you to rotate keys automatically, which is the only real way to mitigate a leak if it happens.

If you’re managing your own infrastructure, consider HashiCorp Vault. It’s powerful, but it has a steep learning curve. Don't over-engineer it if you’re a small team. Start with the basics:

  • Inject secrets as environment variables at runtime.
  • Ensure your CI/CD pipeline (GitHub Actions, GitLab CI) has its own protected variable store.
  • Never pass secrets as command-line arguments, as these often show up in process lists (ps aux).

Avoiding common pitfalls

Even with a vault in place, you can still leak data through logging. I’ve seen developers write middleware that logs the entire request object, which often includes headers containing Authorization: Bearer <TOKEN>.

Always sanitize your logs. If you’re using a logging library like Pino or Winston, configure a redactor to scrub sensitive keys like password, token, and secret.

Also, be careful when using third-party services for monitoring or error tracking. If you’re sending logs to Sentry or Datadog, verify that your client-side SDK isn't accidentally capturing environment variables or sensitive headers. When typing async code in TypeScript without fighting the compiler, you might be tempted to log the entire error object; resist that urge if the object contains sensitive metadata.

A note on CI/CD hygiene

Your CI/CD pipeline is often the weakest link. I once saw a build script that echoed the contents of an environment variable to the console to "debug" a connection issue. That output was then stored in the build logs for 90 days.

Treat your CI logs with the same security posture as your production database. If you need to debug, use a debugger or a remote shell, but never dump your entire environment to the logs.

Is it ever "safe" enough?

A close-up of a notebook page with motivational handwritten text: "You are enough."

I’m still not entirely comfortable with the state of secret management in small projects. We rely heavily on environment variables, which are inherently "plain text" once the process starts. If an attacker gains code execution on your server, they can usually read the memory or the process environment.

The best defense is defense-in-depth:

  • Use short-lived credentials whenever possible (e.g., IAM roles for service accounts).
  • Rotate secrets regularly.
  • Limit the scope of your API keys (e.g., a database user that can only SELECT but not DROP tables).

I’ve learned that security is never a "set it and forget it" task. You’ll likely find a new way to leak a secret next month—maybe through a misconfigured logging sink or a new third-party integration. The goal isn't to be perfect; the goal is to make the cost of a mistake manageable and the process of remediation automated.

What’s the most embarrassing way you’ve leaked a secret? I’ve realized that most of us have a "first time" story. My advice: automate your secret rotation today, because you don't want to be doing it manually at 2:00 AM on a Sunday.

Frequently Asked Questions

How do I handle secrets that need to be shared across a team? Use a shared secret manager like 1Password or Bitwarden for Teams. Never share secrets over Slack or email.

Should I use a .env file in production? No. It’s better to inject environment variables via your cloud provider’s container orchestration or CI/CD platform.

What should I do if I accidentally commit a secret? Rotate the secret immediately. Don't just delete it from Git; assume the secret is compromised the moment it hits the remote repository.

Back to Blog

Similar Posts

Weathered wooden gate sign reading 'Please Close Gate Behind You' in a lush green woodland.
SecurityJune 20, 20264 min read

CSRF protection that you understand and can implement today

CSRF protection doesn't have to be a black box. Learn how to secure your forms and API requests using modern browser standards and proven patterns.

Read more
Close-up of colorful programming code displayed on a computer screen, showcasing modern coding concepts.
Security
June 20, 2026
4 min read

XSS prevention strategies: A guide for modern web developers

XSS prevention strategies are essential for securing modern web apps. Learn to identify the three main variants and implement robust, layered defenses today.

Read more
Three syringes arranged on a red surface showcasing medical equipment with copy space.
SecurityJune 20, 20264 min read

Preventing SQL injection in modern frameworks: A practical guide

Preventing SQL injection in modern frameworks starts with understanding how ORMs and parameterized queries protect your database. Learn how to secure your code.

Read more