Best practices for securing MapQuest API keys. Covers environment variables, referrer restrictions, server-side proxying, key rotation, and incident response when a key is exposed.
Your MapQuest API key is a secret credential. Exposing it allows others to use your quota, incur charges on your account, and potentially abuse MapQuest services. Always treat API keys like passwords.
# .env.local (never commit this file)
VITE_MAPQUEST_API_KEY=your_key_here
// Access in code:
const apiKey = import.meta.env.VITE_MAPQUEST_API_KEY;
# .gitignore — ensure .env files are excluded
.env
.env.local
.env*.local
# .env
MAPQUEST_API_KEY=your_key_here
require('dotenv').config();
const apiKey = process.env.MAPQUEST_API_KEY;
// ❌ WRONG — key is visible in source code and bundle
const apiKey = 'Ab1Cd2Ef3Gh4Ij5Kl6Mn7Op8Qr9';
// ❌ WRONG — key in git history forever
// git commit -m "added api key"
In the MapQuest Developer Portal, set Allowed Referrers for each key:
https://yourdomain.com/* — productionhttps://staging.yourdomain.com/* — staginghttp://localhost:* — local developmentThis limits the key to only work when requests originate from your domains. Client-side keys with referrer restrictions are significantly safer than unrestricted keys.
Limitation: Referrer headers can be spoofed by determined bad actors. For truly sensitive apps, use server-side proxying instead.
Never send MapQuest API requests directly from client-side code in production. Instead, proxy through your backend:
// Express.js proxy route
const express = require('express');
const router = express.Router();
router.get('/geocode', async (req, res) => {
const { address } = req.query;
// Validate input
if (!address || address.length > 500) {
return res.status(400).json({ error: 'Invalid address' });
}
// Optional: rate limit per user/IP here
try {
const response = await fetch(
`https://www.mapquestapi.com/geocoding/v1/address?key=${process.env.MAPQUEST_API_KEY}&location=${encodeURIComponent(address)}&thumbMaps=false`
);
const data = await response.json();
res.json(data);
} catch (err) {
res.status(500).json({ error: 'Geocoding service unavailable' });
}
});
// Client-side — call your proxy, not MapQuest directly
const response = await fetch(`/api/geocode?address=${encodeURIComponent(address)}`);
Benefits of proxying:
Create multiple keys in the MapQuest Developer Portal:
| Key Name | Purpose | Restrictions |
|---|---|---|
production-web | Live site | Referrer: https://yourdomain.com/* |
staging-web | Staging environment | Referrer: https://staging.yourdomain.com/* |
development | Local dev | Referrer: http://localhost:* |
server-side | Backend proxy | No referrer (IP-restricted if possible) |
Rotate keys every 90 days or immediately after any potential exposure.
If you suspect a key was exposed (e.g., committed to a public repo):
git filter-branch or BFG Repo Cleaner)# If key was committed — remove from git history
# Install BFG: https://rtyley.github.io/bfg-repo-cleaner/
bfg --replace-text secrets.txt my-repo.git
git push --force
.env / environment variable, never in source code.env files added to .gitignore❌ Don't log API keys in console.log or server logs
❌ Don't share API keys in Slack, email, or issue trackers
❌ Don't use the same key for development and production
❌ Don't store keys in local storage or cookies (accessible to JS/XSS)
❌ Don't put keys in URLs (they appear in server logs and browser history)