Thuta Learning
AdvancedDevOps & Toolsbeginner

Production Security and Access Control

What you'll walk away with

  • Explain the core ideas behind Production Security and Access Control
  • Read the diagram and trace how a request or data flows through the architecture
  • Explain what this means for your own project's decisions

Build the mental model

Production security is a set of layers, not one setting. HTTPS encrypting traffic in transit is non-negotiable, not optional polish.

  • Authentication — who are you (logging in).
  • Authorization — what are you allowed to do (permissions after login). Confusing the two is a classic bug source.
  • Secrets — passwords, API keys, signing keys — live outside code, in env vars or a secrets manager, never committed.

Least privilege: give every user/service only the permissions it needs. A firewall enforces the network version — open only the ports actually needed.

CORS is not authentication

CORS is a browser-enforced policy on cross-origin requests. It does not protect an API from a non-browser client like a script or curl, which ignores CORS entirely — real auth checks are still required on every endpoint.

Security headers (CSP, HSTS) add browser-enforced protection. IAM — identity, role, permission, policy — is the vendor-neutral framework for who/what can do what.

text
LAYERED PRODUCTION SECURITY
---------------------------
LAYERED PRODUCTION SECURITY
------------------------------

   internet
      |
      v
  +-----------------------------+
  |  HTTPS (encrypt in transit) |
  +-----------------------------+
      |
      v
  +-----------------------------+
  |  FIREWALL (only needed      |
  |  ports reach the server)    |
  +-----------------------------+
      |
      v
  +-----------------------------+
  |  IAM / LEAST PRIVILEGE      |
  |  (what each user/service    |
  |   can do once inside)       |
  +-----------------------------+
      |
      v
  [ APPLICATION + DATA ]

Connect it to a real scenario

CORS enforcement, at its core, checks an incoming Origin header against a list of trusted sites.

An allowed origin gets 'allow' with the origin echoed back as the header. A rejected origin gets 'reject' with no header — telling the browser to block the response.

CORS only matters to browsers

A script or server calling your API directly never sends an Origin header the way a browser does. Real authentication and authorization on every endpoint is still required.

Production Security Basics

Try the working example

javascript
function createCorsChecker(allowedOrigins) {
  return function checkOrigin(origin) {
    const allowed = allowedOrigins.includes(origin);
    return {
      origin,
      decision: allowed ? "allow" : "reject",
      headerSent: allowed ? origin : null,
    };
  };
}

const checkOrigin = createCorsChecker([
  "https://app.example.com",
  "https://admin.example.com",
]);

console.log(JSON.stringify(checkOrigin("https://app.example.com")));
console.log(JSON.stringify(checkOrigin("https://evil-clone.com")));
You should see
{"origin":"https://app.example.com","decision":"allow","headerSent":"https://app.example.com"}
{"origin":"https://evil-clone.com","decision":"reject","headerSent":null}

5-minute try-it

Add a wildcard subdomain case: allow any origin matching '*.example.com'. Modify createCorsChecker to support it and test with 'https://staging.example.com' and 'https://example.com.evil.com'.

One important caution

Relying on CORS as the only protection for an API endpoint, then discovering a curl request bypasses it entirely.

Granting a service or user broad admin permissions 'to save time' instead of the specific permissions the task actually needs.

MDN — Cross-Origin Resource Sharing (CORS)Cloud & Deployment

Easy traps

  • Relying on CORS as the only protection for an API endpoint, then discovering a curl request bypasses it entirely.
  • Granting a service or user broad admin permissions 'to save time' instead of the specific permissions the task actually needs.
  • Never assume that working on localhost means it will work in production -- environment, network, database, and security differences can all bite.

Exercise

Add a wildcard subdomain case: allow any origin matching '*.example.com'. Modify createCorsChecker to support it and test with 'https://staging.example.com' and 'https://example.com.evil.com'.

You'll know it worked when: {"origin":"https://app.example.com","decision":"allow","headerSent":"https://app.example.com"} {"origin":"https://evil-clone.com","decision":"reject","headerSent":null}

Production Security and Access Control | Thuta Learning