Thuta Learning
ProjectsSecurityintermediate

Project: A Developer Security Baseline

What you'll walk away with

  • Explain the core ideas behind Project: A Developer Security Baseline
  • Read the diagram/checklist and trace how the threat, control, and decision connect
  • Explain how this applies to your own digital life or developer workflow

Build the mental model

This capstone combines four Advanced-chapter lessons: authentication-vs-authorization-deep-dive, token-and-session-security, api-security-beyond-secrets, and website-security-layers-review — merging four separate mental checklists into one production-readiness baseline.

Cybersecurity Basics' projects centered on OWASP Top 10 (SQL injection, XSS) input-handling flaws. This baseline sits one layer up — fixing XSS does not help if authorization is never checked per-resource, letting an attacker read another user's data just by changing an ID in the URL.

  • Authentication configured correctly
  • Authorization checked per-resource, not just at login
  • Tokens never logged, committed, or exposed to client-side code
  • API enforces rate limiting
  • Secrets in environment variables, not source code
  • Dependencies kept up to date
text
DEVELOPER SECURITY BASELINE
---------------------------
DEVELOPER SECURITY BASELINE
------------------------------
AUTH          [PASS/FAIL]
  |
  v
AUTHZ         [PASS/FAIL]
  |
  v
TOKENS        [PASS/FAIL]
  |
  v
API           [PASS/FAIL]
  |
  v
SECRETS       [PASS/FAIL]
  |
  v
DEPENDENCIES  [PASS/FAIL]
  |
  v
ALL SIX PASS -> PRODUCTION-READY BASELINE MET

Connect it to a real scenario

Build the baseline as a checklist you can run against any project's configuration. Work through the six categories in a fixed order so nothing gets skipped under deadline pressure.

Authentication

Confirm passwords or passkeys are hashed or handled correctly, and failed-login attempts are rate-limited.

Authorization

Confirm every endpoint that returns or modifies a specific record verifies the requesting user actually owns or is permitted to access that record, not just that they are logged in at all.

Tokens

Search the codebase and logs for tokens appearing in plaintext, confirm none are committed to version control, and confirm none are exposed to client-side JavaScript unnecessarily.

API

Confirm the API enforces rate limiting on sensitive endpoints and that responses return only the fields a client actually needs, not full internal records.

Secrets

Confirm secrets — API keys, database credentials, signing keys — live in environment variables or a secrets manager, never hard-coded in source.

Dependencies

Confirm dependencies are on a maintained update cadence rather than frozen indefinitely.

Never paste real secrets

When you run this checklist against your own project, describe configuration with booleans and short descriptions only — never paste real API keys, tokens, or credentials into this lesson or into any AI tool.

Run the checker function below against a described project's configuration twice: once for a project that fails several categories, and once for a project that passes all six, and compare the two reports side by side.

Try the working example

javascript
function checkDeveloperSecurityBaseline(project) {
  const checks = [
    {
      category: "Authentication",
      pass: project.auth.passwordsHashedCorrectly && project.auth.loginRateLimited,
      detail: "Passwords/passkeys hashed correctly and failed logins are rate-limited",
    },
    {
      category: "Authorization",
      pass: project.authz.checkedPerResource,
      detail: "Every endpoint verifies the caller owns/may access the specific resource, not just that they are logged in",
    },
    {
      category: "Tokens",
      pass: project.tokens.neverLogged && project.tokens.neverCommitted && !project.tokens.exposedToClient,
      detail: "Tokens are never logged, never committed to version control, and not needlessly exposed to client-side code",
    },
    {
      category: "API",
      pass: project.api.rateLimited && project.api.responsesMinimized,
      detail: "Sensitive endpoints are rate-limited and responses return only the fields a client actually needs",
    },
    {
      category: "Secrets",
      pass: project.secrets.inEnvVars,
      detail: "API keys, DB credentials, and signing keys live in environment variables, not source code",
    },
    {
      category: "Dependencies",
      pass: project.dependencies.upToDate,
      detail: "Dependencies are on a maintained update cadence, not frozen indefinitely",
    },
  ];

  const failed = checks.filter((c) => !c.pass);
  return {
    project: project.name,
    passed: checks.length - failed.length,
    total: checks.length,
    overallPass: failed.length === 0,
    checks: checks.map((c) => ({ category: c.category, status: c.pass ? "PASS" : "FAIL", detail: c.detail })),
  };
}

// Described CONFIGURATION only -- booleans, never real keys/tokens/credentials.
const failingProject = {
  name: "Example Project A (needs work)",
  auth: { passwordsHashedCorrectly: true, loginRateLimited: false },
  authz: { checkedPerResource: false },
  tokens: { neverLogged: true, neverCommitted: false, exposedToClient: true },
  api: { rateLimited: false, responsesMinimized: true },
  secrets: { inEnvVars: true },
  dependencies: { upToDate: false },
};

const passingProject = {
  name: "Example Project B (baseline met)",
  auth: { passwordsHashedCorrectly: true, loginRateLimited: true },
  authz: { checkedPerResource: true },
  tokens: { neverLogged: true, neverCommitted: true, exposedToClient: false },
  api: { rateLimited: true, responsesMinimized: true },
  secrets: { inEnvVars: true },
  dependencies: { upToDate: true },
};

for (const project of [failingProject, passingProject]) {
  const report = checkDeveloperSecurityBaseline(project);
  console.log(`\n${report.project}: ${report.passed}/${report.total} checks passed, overall ${report.overallPass ? "PASS" : "FAIL"}`);
  for (const c of report.checks) {
    console.log(`  [${c.status}] ${c.category} -- ${c.detail}`);
  }
}
You should see
Project A fails 5 of 6 checks (only Secrets passes) and reports overallPass: false; Project B passes all 6 checks and reports overallPass: true — matching the console output above, which lists PASS/FAIL per category for both projects.

5-minute try-it

Describe a real or fictional project of your own across the six boolean categories used in the code (never real production secrets), run checkDeveloperSecurityBaseline on it, and write one concrete remediation step for each FAIL it reports.

One important caution

Treating 'the user is logged in' as equivalent to 'the user is authorized' — authentication and authorization are different checks and both must pass per-resource

Running the baseline once before launch and never again, even though a new endpoint, a new dependency, or a new integration can quietly reopen a category that used to pass

OWASP API Security Top 10Digital Privacy & Modern Security

Easy traps

  • Treating 'the user is logged in' as equivalent to 'the user is authorized' — authentication and authorization are different checks and both must pass per-resource
  • Running the baseline once before launch and never again, even though a new endpoint, a new dependency, or a new integration can quietly reopen a category that used to pass
  • This is not a restart of the Cybersecurity Basics course -- it assumes passwords, 2FA, phishing, malware, encryption, and backups are already covered there. This course adds what that one doesn't: passkeys, public Wi-Fi/VPN, browser security, privacy, developer-focused auth/API security, and AI security.

Exercise

Describe a real or fictional project of your own across the six boolean categories used in the code (never real production secrets), run checkDeveloperSecurityBaseline on it, and write one concrete remediation step for each FAIL it reports.

You'll know it worked when: Project A fails 5 of 6 checks (only Secrets passes) and reports overallPass: false; Project B passes all 6 checks and reports overallPass: true — matching the console output above, which lists PASS/FAIL per category for both projects.