Thuta Learning
BasicWeb Developmentintermediate

Secret Management

What you'll walk away with

  • Explain the core ideas behind Secret Management
  • Read the diagram and trace how a request, response, or event flows through the system
  • Explain how this applies to a real API integration you might build

Build the mental model

API Tutorial taught you to attach an API key to a request. It did not tell you where that key should physically live, and getting this wrong is one of the most common real-world security failures.

Writing `const apiKey = "sk_live_abc123"` directly in frontend or mobile app code means the key ships inside the JavaScript bundle or app binary that runs on every user's device. Anyone can open browser devtools and copy the secret key out in seconds.

Minification is not encryption

Minifying code makes it harder to read, but any secret string inside is still plain text in the bundle -- searchable and copyable.

The correct architecture adds a layer: the browser talks to your own backend server, and only your backend holds the real secret key and talks to the external API. Your backend becomes the trusted boundary.

Environment variables are the standard way to hand that secret to your backend without hardcoding it into source files. That `.env` file must be listed in `.gitignore` -- a secret committed to Git stays recoverable from history forever, even after you delete the line.

Secret
A private value, like an API key, password, or token, that grants access -- if it becomes public, it can be misused.
Environment Variable
A configuration value stored outside the codebase and handed to a process at runtime -- the standard way to supply secrets without hardcoding them.
text
SECRET KEY: GOOD PATH VS BAD PATH
---------------------------------
GOOD:
  Browser --> Your Backend --> [ Secret Key (env var) ] --> External API

BAD (do not do this):
  Browser --> [ Secret Key hardcoded in JS ] --> External API
          X-- anyone can read this in devtools --X

Connect it to a real scenario

The scanner below looks for a common, careless pattern: a `const`, `let`, or `var` declaration whose variable name contains "key", "secret", or "token", assigned directly to a quoted string literal of at least twelve characters.

Run it against two snippets. The risky one hardcodes an API key directly above a `fetch` call, and the scanner flags exactly that line. The clean version reads the key from `process.env.API_KEY` instead, and the scanner correctly returns an empty array.

A tool like this is exactly what real teams wire into a pre-commit hook or CI pipeline, catching an accidentally hardcoded key before it ever reaches shared Git history, where removing it later is far harder than never committing it.

Before Committing Code

Try the working example

javascript
function scanForHardcodedSecrets(sourceCode) {
  const pattern = /(const|let|var)\s+(\w*(?:key|secret|token)\w*)\s*=\s*["']([A-Za-z0-9_\-]{12,})["']/gi;
  const findings = [];
  let match;
  while ((match = pattern.exec(sourceCode)) !== null) {
    findings.push({ variable: match[2], flagged: true, snippet: match[0] });
  }
  return findings;
}

const risky = `
const apiKey = "sk_live_51H8x9aBcDeFgHiJkLmNoP";
const userName = "guest";
fetch("https://api.example.com/charge", { headers: { Authorization: apiKey } });
`;

const clean = `
const apiKey = process.env.API_KEY;
const userName = "guest";
fetch("https://api.example.com/charge", { headers: { Authorization: apiKey } });
`;

console.log("Risky file findings:", scanForHardcodedSecrets(risky));
console.log("Clean file findings:", scanForHardcodedSecrets(clean));
You should see
Risky file findings: [{ variable: 'apiKey', flagged: true, snippet: 'const apiKey = "sk_live_51H8x9aBcDeFgHiJkLmNoP"' }]
Clean file findings: []

5-minute try-it

Run `scanForHardcodedSecrets` against a new snippet containing `const dbPassword = "SuperSecret2024!"` and explain why it does or does not get flagged.

One important caution

Forgetting to add .env to .gitignore -- once committed, cleaning it from history is hard

Using a secret as a public-prefixed frontend env variable (like NEXT_PUBLIC_) -- it still ends up baked into the bundle

About secret scanning - GitHub DocsAPI Integration & Webhooks

Easy traps

  • Forgetting to add .env to .gitignore -- once committed, cleaning it from history is hard
  • Using a secret as a public-prefixed frontend env variable (like NEXT_PUBLIC_) -- it still ends up baked into the bundle
  • If you haven't taken the API Tutorial yet, it's worth finishing that first -- this course doesn't re-teach REST/HTTP/auth basics, it builds on top of them with webhooks, testing, reliability, and integration architecture.

Exercise

Run `scanForHardcodedSecrets` against a new snippet containing `const dbPassword = "SuperSecret2024!"` and explain why it does or does not get flagged.

You'll know it worked when: Risky file findings: [{ variable: 'apiKey', flagged: true, snippet: 'const apiKey = "sk_live_51H8x9aBcDeFgHiJkLmNoP"' }] Clean file findings: []

Secret Management | Thuta Learning