← Back to Developer Blog
💻 DeveloperFebruary 28, 20267 min read

Environment Variables: Stop Hardcoding Secrets

API keys in code? Database passwords committed to Git? Here's how to manage environment config properly.

By Raspib Technology Team

Environment Variables: Stop Hardcoding Secrets

Seen this?

$apiKey = 'sk_live_abc123xyz789';  // Committed to Git
$dbPassword = 'supersecret123';    // Everyone can see

Your secrets are public. Here's how to fix it.

The Problem

// config/services.php
return [
    'paystack' => [
        'secret' => 'sk_live_abc123xyz789',  // Hardcoded!
    ],
];

This file is in Git. Anyone with repo access sees your API key.

The Solution: Environment Variables

// .env (NOT in Git)
PAYSTACK_SECRET=sk_live_abc123xyz789

// config/services.php
return [
    'paystack' => [
        'secret' => env('PAYSTACK_SECRET'),
    ],
];

Secrets stay out of Git. Each environment has its own values.

Setup

Laravel

Already configured. Just use .env:

APP_NAME=MyApp
APP_ENV=production
APP_DEBUG=false

DB_HOST=127.0.0.1
DB_DATABASE=myapp
DB_USERNAME=root
DB_PASSWORD=secret

PAYSTACK_SECRET=sk_live_xxx
MAIL_PASSWORD=xxx

Node.js

npm install dotenv
// .env
DATABASE_URL=postgresql://user:pass@localhost/db
API_KEY=abc123

// app.js
require('dotenv').config();

const apiKey = process.env.API_KEY;

Multiple Environments

Development

# .env.development
APP_ENV=local
APP_DEBUG=true
DB_DATABASE=myapp_dev
PAYSTACK_SECRET=sk_test_xxx

Staging

# .env.staging
APP_ENV=staging
APP_DEBUG=false
DB_DATABASE=myapp_staging
PAYSTACK_SECRET=sk_test_xxx

Production

# .env.production
APP_ENV=production
APP_DEBUG=false
DB_DATABASE=myapp_prod
PAYSTACK_SECRET=sk_live_xxx

Accessing Config

Laravel

// Get config value
$secret = config('services.paystack.secret');

// With default
$timeout = config('services.api.timeout', 30);

// Check environment
if (app()->environment('production')) {
    // Production-specific code
}

Node.js

const apiKey = process.env.API_KEY;
const dbUrl = process.env.DATABASE_URL || 'postgresql://localhost/db';

if (process.env.NODE_ENV === 'production') {
    // Production code
}

Security Best Practices

1. Never Commit .env

# .gitignore
.env
.env.*
!.env.example

2. Use .env.example

# .env.example (committed to Git)
APP_NAME=
APP_ENV=
DB_HOST=
DB_DATABASE=
DB_USERNAME=
DB_PASSWORD=
PAYSTACK_SECRET=

Shows what variables are needed without exposing values.

3. Rotate Secrets Regularly

# Generate new app key
php artisan key:generate

# Update API keys quarterly
# Update database passwords annually

4. Use Different Keys Per Environment

# Development
PAYSTACK_SECRET=sk_test_xxx

# Production
PAYSTACK_SECRET=sk_live_yyy

If dev key leaks, production is safe.

Real Incident

Client: E-commerce site

What happened:

  • Developer committed .env to Git
  • Repo was public
  • Someone found Paystack live key
  • Made test transactions
  • ₦50,000 lost before we noticed

Fix:

  • Rotated all API keys
  • Made repo private
  • Added .env to .gitignore
  • Set up secret scanning

Lesson: Never commit secrets. Ever.

Managing Secrets in Production

Option 1: Server Environment Variables

# Set on server
export DB_PASSWORD=secret
export PAYSTACK_SECRET=sk_live_xxx

Option 2: Deployment Platform

Vercel:

vercel env add PAYSTACK_SECRET

Heroku:

heroku config:set PAYSTACK_SECRET=sk_live_xxx

AWS: Use AWS Secrets Manager or Parameter Store.

Option 3: .env File on Server

# Upload .env via SSH
scp .env.production server:/var/www/app/.env

Keep .env out of Git, upload manually.

Validation

Validate required variables on startup:

// Laravel: config/app.php
$required = [
    'APP_KEY',
    'DB_PASSWORD',
    'PAYSTACK_SECRET',
];

foreach ($required as $var) {
    if (empty(env($var))) {
        throw new Exception("Missing required environment variable: {$var}");
    }
}

App won't start if config is missing.

Common Mistakes

Mistake 1: Using env() in Code

// Bad: Doesn't work with config cache
$secret = env('PAYSTACK_SECRET');

// Good: Use config()
$secret = config('services.paystack.secret');

Mistake 2: Committing .env

# Check if .env is tracked
git ls-files | grep .env

# If found, remove it
git rm --cached .env
git commit -m "Remove .env from Git"

Mistake 3: Same Secrets Everywhere

# Don't use production secrets in development
# Use test keys for development

Config Caching (Laravel)

Production optimization:

# Cache config (faster loading)
php artisan config:cache

# After changing .env
php artisan config:clear
php artisan config:cache

Important: env() doesn't work with cached config. Always use config().

Organizing Config

// config/services.php
return [
    'paystack' => [
        'public_key' => env('PAYSTACK_PUBLIC_KEY'),
        'secret_key' => env('PAYSTACK_SECRET_KEY'),
        'webhook_url' => env('PAYSTACK_WEBHOOK_URL'),
    ],
    
    'flutterwave' => [
        'public_key' => env('FLUTTERWAVE_PUBLIC_KEY'),
        'secret_key' => env('FLUTTERWAVE_SECRET_KEY'),
    ],
];

Group related config together.

Real Project Setup

Project: Payment processing API

.env.example:

# Application
APP_NAME=PaymentAPI
APP_ENV=production
APP_DEBUG=false
APP_URL=https://api.example.com

# Database
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=
DB_USERNAME=
DB_PASSWORD=

# Payment Gateways
PAYSTACK_PUBLIC_KEY=
PAYSTACK_SECRET_KEY=
FLUTTERWAVE_PUBLIC_KEY=
FLUTTERWAVE_SECRET_KEY=

# Email
MAIL_MAILER=smtp
MAIL_HOST=
MAIL_PORT=
MAIL_USERNAME=
MAIL_PASSWORD=

# Redis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=
REDIS_PORT=6379

Clear. Organized. No secrets exposed.

Checking for Exposed Secrets

GitHub Secret Scanning

GitHub automatically scans for exposed secrets. Enable it.

Manual Check

# Search for potential secrets in Git history
git log -p | grep -i "password\|secret\|key"

Tools

# Install gitleaks
brew install gitleaks

# Scan repo
gitleaks detect

Bottom Line

Environment variables keep secrets safe.

Use .env for local development. Use platform secrets for production. Never commit secrets to Git.

Simple rule: If it's secret, it goes in .env.


Need security audit?

We audit codebases for Nigerian businesses. Find exposed secrets, security issues, vulnerabilities.

📞 WhatsApp: +234 708 711 0468
📧 info@raspibtech.com
📍 Lagos Island

Related:

Need Help with Your Project?

Let's discuss how Raspib Technology can help transform your business

Related Articles

Environment Variables Guide - Manage Config Properly