Home/Blog/Article
SecurityDevSecOpsSecrets ManagementReactCI/CDAI AgentsGitHub

.env Files Are Not Secrets: How Secrets Leak Through GitHub, AI Agents, CI/CD and React

T
Team VAPT Insights·August 18, 2026·12 min read
.env Files Are Not Secrets: How Secrets Leak Through GitHub, AI Agents, CI/CD and React

Environment files are everywhere in modern application development.

Developers use .env files to store database credentials, API keys, JWT secrets, cloud credentials, third-party tokens, and other configuration values.

But there is a dangerous misconception:

Putting a secret inside .env does not make the secret secure.

An .env file is usually just a plain-text file.

If an attacker, accidentally exposed repository, CI/CD pipeline, AI coding agent, compromised development machine, or client-side application can access those values, the secrets may be exposed.

This article explains how .env secrets leak, what happens when they are pushed to GitHub, what AI agents have to do with it, and why putting secrets in React or other client-side applications can be especially dangerous.


What Is an .env File?

An .env file is commonly used to store environment-specific configuration.

For example:

DATABASE_URL=postgresql://app_user:[email protected]/app
JWT_SECRET=your-secret-key
STRIPE_SECRET_KEY=sk_live_xxxxxxxxx
AWS_ACCESS_KEY_ID=xxxxxxxx
AWS_SECRET_ACCESS_KEY=xxxxxxxx

This keeps configuration values outside the application's source code.

A typical application may load them like this:

const databaseUrl = process.env.DATABASE_URL;

The important point is:

.env is a configuration mechanism, not a security mechanism.

The file itself does not encrypt the values.


Why .env Files Can Be Critical

An .env file can contain credentials that provide access to important systems.

Depending on the application, leaked environment variables could expose:

  • Databases
  • Cloud infrastructure
  • Payment services
  • Email services
  • Authentication systems
  • Internal APIs
  • Storage buckets
  • Third-party services
  • Encryption or signing keys

The impact depends on what the exposed credential can access.

For example:

DATABASE_PASSWORD=MyPassword123

may look like one leaked password. But if that database account has administrator privileges, the impact could be much larger.

Similarly:

AWS_SECRET_ACCESS_KEY=...

could potentially provide access to cloud resources depending on the permissions attached to that identity.

The real question is not:

"Was the .env file leaked?"

The better question is:

"What permissions did the leaked secrets have?"


What Happens When .env Is Accidentally Pushed to GitHub?

This is one of the most common mistakes.

A developer creates .env and then runs:

git add .
git commit -m "initial commit"
git push

If .env wasn't excluded, the credentials may now be inside the Git repository.

A developer might then add .gitignore rules:

.env
.env.*
!.env.example

This is good practice, but there is an important limitation:

.gitignore does not remove secrets that have already been committed.

The secret may still exist in Git history.

Why Deleting .env From GitHub Is Not Enough

Suppose you notice the mistake and delete .env. It is tempting to think the problem is solved. It isn't.

Git repositories maintain history. The secret may still exist in:

  • Previous commits
  • Branches and tags
  • Forks
  • Local repositories
  • CI/CD caches
  • Build artifacts and logs
  • Backups

There is another important issue: the secret may have already been copied before you deleted it.

Therefore:

Treat an exposed credential as compromised. Do not rely on simply deleting the file.


What Should You Do If .env Was Pushed?

The first priority should be credential rotation, not file deletion.

A practical incident-response sequence:

  1. Identify the exposed secrets
  2. Revoke or rotate them immediately
  3. Check whether the credentials were used
  4. Review access logs
  5. Remove the secrets from Git history
  6. Add appropriate .gitignore rules
  7. Replace exposed values with new credentials
  8. Review who and what had access to the repository

For example, if this was accidentally committed:

STRIPE_SECRET_KEY=sk_live_old_secret

Deleting .env is not the main fix. The first priority should be to revoke or rotate the exposed Stripe credential.

The same principle applies to database passwords, cloud credentials, API tokens, SSH keys, JWT signing secrets, and encryption keys.

Secret rotation is more important than file deletion.


The AI-Agent Problem: A New and Underappreciated Risk

This is the part most security guides skip entirely.

Modern development workflows increasingly involve AI coding agents. An agent may be given access to source code, Git repositories, terminals, build systems, local files, package managers, development environments, and CI/CD systems.

This creates a critical security question:

Does the AI agent really need access to .env?

If an agent is asked to fix a React component, it probably does not need:

PRODUCTION_DATABASE_PASSWORD=...
AWS_PRODUCTION_SECRET=...
PAYMENT_PROVIDER_SECRET=...

The Blast Radius Problem

When you give an AI agent broad filesystem or repository access, you are not just giving it access to code. You may be giving it access to every secret in your project.

Consider what a typical agent session might access:

Developer
    |
    v
AI Agent
    |
    +---- Source code          ✅ Needed
    |
    +---- Test configuration   ✅ Needed
    |
    +---- .env (dev)           ⚠️  Usually not needed
    |
    +---- .env.production      ❌ Definitely not needed
    |
    +---- AWS credentials      ❌ Definitely not needed
    |
    +---- SSH keys             ❌ Definitely not needed

Follow the Principle of Least Privilege — For Agents Too

The same security principle that applies to human users, service accounts, and applications applies equally to AI agents:

Give an agent only the access required to complete the task.

Practical steps:

  • Use separate .env files for development and production, and ensure agents only have access to development values
  • Scope your agent's workspace to the directories it actually needs
  • Never store production credentials in local files that agents can read
  • Treat agent access as you would a junior contractor: task-scoped, not all-access
  • Audit what files your agent tool can read before granting it repository access

This is not a theoretical concern. As AI agents become more capable and more deeply integrated into developer tooling, they will increasingly be the path of least resistance for an attacker — or for accidental exposure.


The Biggest React Mistake: Putting Secrets in Client-Side Variables

This is where .env security becomes especially important.

A developer may think:

"The credentials are in .env, so users cannot see them."

That assumption is dangerous when it comes to client-side applications.

A client-side application runs on the user's device. If a value is included in the browser bundle or intentionally exposed to the client, the user can potentially inspect it.

The browser is not a trusted environment.

React Applications Cannot Keep Browser-Side Secrets

This architecture is dangerous:

React Application
       |
       v
Database
       ^
       |
DB password exposed to browser ❌

A safer architecture is:

React Application
       |
       v
Backend API
       |
       v
Database ✅

The database credentials stay on the server. The browser only receives the data it is authorised to receive.

What About NEXT_PUBLIC_ Variables?

Next.js provides a common example of this problem.

A variable such as:

NEXT_PUBLIC_API_URL=https://api.example.com

is intended to be exposed to client-side code. That is fine for values that are genuinely public.

But this would be dangerous:

NEXT_PUBLIC_DB_PASSWORD=SuperSecretPassword     ❌
NEXT_PUBLIC_STRIPE_SECRET_KEY=sk_live_xxxxx     ❌
NEXT_PUBLIC_AWS_SECRET_ACCESS_KEY=xxxxxxxx      ❌

The NEXT_PUBLIC_ prefix is effectively telling the framework: this value can be exposed to the browser. Never use a public/client-side environment variable for a secret.

"But It Is Inside JavaScript"

Another misconception: "The user can't see my environment variables because they are compiled into the application."

Client-side JavaScript is not a secret storage mechanism. Users can inspect applications through browser developer tools, JavaScript bundles, network requests, source maps, and browser storage.

Anything delivered to the browser should be considered public.

Server-Side vs Client-Side: A Simple Classification

Variable Safe to expose?
NEXT_PUBLIC_API_URL=https://api.example.com ✅ Yes — genuinely public
NEXT_PUBLIC_APP_NAME=My Application ✅ Yes — genuinely public
DATABASE_URL=... ❌ No — server-side only
JWT_SECRET=... ❌ No — server-side only
AWS_SECRET_ACCESS_KEY=... ❌ No — server-side only
STRIPE_SECRET_KEY=... ❌ No — server-side only
ENCRYPTION_KEY=... ❌ No — server-side only

Use .env.example

A useful development practice is to commit a template instead of the real .env.

# .env.example

DATABASE_URL=
JWT_SECRET=
STRIPE_SECRET_KEY=

Keep the real file local and add it to .gitignore:

.env
.env.*
!.env.example

This gives developers a clear understanding of which variables are required without exposing the actual credentials.


.env Is Fine for Development — But Production Needs More

Using .env locally is common and often practical. For production environments, consider dedicated secret-management mechanisms such as:

  • Cloud secret managers (AWS Secrets Manager, GCP Secret Manager, Azure Key Vault)
  • CI/CD secret stores (GitHub Actions Secrets, GitLab CI Variables)
  • Container/orchestration secrets (Kubernetes Secrets)
  • Enterprise secret-management platforms (HashiCorp Vault, Doppler)

The goal is to avoid distributing production secrets unnecessarily.


CI/CD Can Also Leak Environment Variables

Even if .env never reaches GitHub, secrets can still leak through CI/CD.

Be careful with commands that print environment variables:

printenv
# or
echo $DATABASE_URL

Secrets can accidentally appear in build logs, debug output, error messages, test reports, and build artifacts.

A secret should never be printed simply to verify that it exists.


Common .env Security Mistakes

Mistake Why It Matters
Committing .env Pushes secrets into version-controlled, potentially public history
Assuming .gitignore protects already-tracked files Does not remove previously committed secrets
Only deleting the leaked file Credentials may already be compromised
Putting secrets in React client-side code Browser environment is public; secrets are visible
Using NEXT_PUBLIC_ for secrets Client-side variables are intentionally exposed
Giving AI agents unnecessary access Agents can read everything in their workspace scope
Using production credentials locally Dev environment breaches can escalate to production
Printing secrets in CI/CD logs Logs are another form of secret exposure

A Better Secret Architecture

A safer modern architecture:

                    ┌─────────────────┐
                    │     Browser     │
                    │   React / Next  │
                    └────────┬────────┘
                             │
                             │ HTTPS
                             v
                    ┌─────────────────┐
                    │   Backend API   │
                    └────────┬────────┘
                             │
                     Secret access
                             │
                             v
                    ┌─────────────────┐
                    │ Secret Manager  │
                    └────────┬────────┘
                             │
                             v
                    ┌─────────────────┐
                    │    Database     │
                    └─────────────────┘

The browser doesn't need the database password. The backend retrieves the required secret from a controlled environment.


What If the Secret Was Already Exposed? — Incident Checklist

  • Identify exactly which secrets were exposed
  • Immediately revoke or rotate the affected credentials
  • Check access logs for suspicious activity
  • Determine whether production resources were accessible
  • Remove secrets from Git history
  • Search branches and tags for copies
  • Check CI/CD logs and artifacts
  • Check forks and other repository copies where applicable
  • Add .env rules to .gitignore
  • Create a safe .env.example
  • Move production secrets to appropriate secret management
  • Review repository and agent permissions
  • Document the incident

How Critical Is an .env Leak?

There is no single severity rating for every .env leak. It depends on the secret and its permissions.

Exposed Value Potential Impact
Public API URL Usually Low
Public application name Usually Informational
Database read-only credential Medium to High
Database admin credential Critical
Cloud credential with broad permissions Critical
Payment provider secret High to Critical
JWT signing secret High
Encryption key Critical
Production admin API token Critical

The filename .env does not determine severity. The permissions behind the exposed values determine the real risk.


Final .env Security Checklist

Before deploying an application, ask:

  • Is .env excluded from Git?
  • Is .env.example provided instead?
  • Are production secrets stored in a dedicated secret manager?
  • Are database credentials kept server-side only?
  • Are client-side variables free of secrets?
  • Are NEXT_PUBLIC_ variables genuinely public?
  • Are AI agents scoped to only the access they actually need?
  • Are CI/CD secrets protected from logs?
  • Are credentials scoped using least privilege?
  • Is there a process for rotating leaked credentials?
  • Are repositories scanned for accidentally committed secrets?

Conclusion

An .env file may look like a small configuration file, but it can contain the keys to an entire application.

A single accidental GitHub commit can expose database credentials, cloud access, payment credentials, authentication secrets, or internal API tokens.

The risk becomes even greater when the same secrets are accessible to AI agents, CI/CD systems, or client-side applications.

The safest mindset is simple:

Don't ask whether your .env file is hidden. Ask who — or what — can access the secrets inside it.

Security is not about hiding a file. Security is about controlling access to the secrets.


Secure Your Applications With VAPT Insights

Secret exposure is only one part of application security.

VAPT Insights helps organisations identify security weaknesses across their applications and infrastructure through automated security assessments.

From security headers and SSL/TLS configuration to exposed services and application security checks, continuous visibility helps teams identify problems before attackers do.

Build securely. Scan continuously. Protect what matters.

Back to all posts
Share Center

Share Analysis

Distribute security intelligence across your network.

XLinkedInFacebookEmail

Related Articles

GitLab CVE-2026-19478: CVSS 9.4 Critical Vulnerability Explained

GitLab CVE-2026-19478: CVSS 9.4 Critical Vulnerability Explained

Aug 23, 2026
Critical Nuxt DevTools RCE (CVE-2026-71319): Unauthenticated Remote Command Execution in Development Mode

Critical Nuxt DevTools RCE (CVE-2026-71319): Unauthenticated Remote Command Execution in Development Mode

Aug 6, 2026
HTTP Security Headers Explained: Every Header Your Website Needs in 2026

HTTP Security Headers Explained: Every Header Your Website Needs in 2026

Aug 3, 2026

Related Articles

GitLab CVE-2026-19478: CVSS 9.4 Critical Vulnerability Explained

GitLab CVE-2026-19478: CVSS 9.4 Critical Vulnerability Explained

Aug 23, 2026
Critical Nuxt DevTools RCE (CVE-2026-71319): Unauthenticated Remote Command Execution in Development Mode

Critical Nuxt DevTools RCE (CVE-2026-71319): Unauthenticated Remote Command Execution in Development Mode

Aug 6, 2026
HTTP Security Headers Explained: Every Header Your Website Needs in 2026

HTTP Security Headers Explained: Every Header Your Website Needs in 2026

Aug 3, 2026
V
VAPT Insights
FeaturesSBOMPricingBlogDocs
DPDP Readiness
LoginGet Started
FeaturesSBOMPricingBlogDocs
Tools
Headers ScannerSSL CertificateSBOM Viewer
DPDP Readiness
Sign inCreate Account