Menu

API Security

Learn API Security for API Engineer for free: roadmap, examples, subskills, and a skill exam.

Published: January 21, 2026 | Updated: January 21, 2026

What you'll learn

API Security for API Engineers means designing, building, and operating APIs that resist real attacks while staying usable. You’ll learn how to authenticate clients and users (OAuth2/OIDC, API keys), authorize access (RBAC/ABAC), protect tokens, validate input, secure transport (TLS), verify signatures/HMAC, and model threats using the OWASP API Top 10.

Why it matters for API Engineers

  • Prevents breaches and data leaks that can halt development and damage trust.
  • Enables safe integrations with partners, mobile apps, and third-party services.
  • Reduces operational load: fewer incidents, clearer policies, faster audits.
  • Unlocks advanced tasks: zero-trust architectures, mTLS, robust token lifecycles, and secure webhooks.

Who this is for

  • API and backend engineers building public or internal APIs.
  • Platform engineers maintaining gateways, auth services, and service meshes.
  • Full-stack engineers who need secure server-side endpoints.

Prerequisites

  • Comfortable with building REST/HTTP APIs and handling headers/status codes.
  • Basic understanding of JSON, JWTs, and HTTP TLS certificates.
  • Ability to read code examples in at least one backend language (Node.js, Python, or Go).

Learning path (roadmap)

1) Foundations: identity and transport

  • Set TLS to require TLS 1.2+; disable older protocols and weak ciphers.
  • Implement Authentication: API keys for service-to-service, OAuth2/OIDC for users.
  • Parse and validate JWTs: issuer, audience, signature, exp/nbf.

2) Authorization and input defense

  • Apply RBAC for coarse permissions; use ABAC for fine-grained rules.
  • Centralize input validation and sanitization for all endpoints.

3) Token lifecycle and key management

  • Short-lived access tokens, refresh tokens with rotation, revoke on compromise.
  • Rotate signing keys; implement JWKS caching and kid-based verification.

4) Integrity, webhooks, and threat modeling

  • Sign requests and webhooks with HMAC; verify on receipt.
  • Run an OWASP API Top 10 review and a quick threat model per feature.

5) Operational hardening

  • Consistent error handling; no secret leakage.
  • Logging/metrics for auth failures, 4xx/5xx anomalies, and token misuse.

Worked examples

1) Validating a JWT (issuer, audience, expiry) in Node.js
// npm i jose
import { jwtVerify, createLocalJWKSet } from 'jose'

const JWKS_URL = 'https://issuer.example.com/.well-known/jwks.json'
const ISSUER = 'https://issuer.example.com/'
const AUD = 'orders-api'

// cache JWKS
const jwks = createLocalJWKSet(await (await fetch(JWKS_URL)).json())

export async function verifyAccessToken(bearer) {
  if (!bearer?.startsWith('Bearer ')) throw new Error('Missing bearer')
  const token = bearer.slice(7)
  const { payload } = await jwtVerify(token, jwks, {
    issuer: ISSUER,
    audience: AUD,
    algorithms: ['RS256']
  })
  // Optional: check custom claims (scp/roles)
  if (!payload.scp?.includes('orders:read')) throw new Error('Insufficient scope')
  return payload
}

Key points: use JWKS and kid to pick the right key, enforce issuer/audience, and verify scopes.

2) Refresh token rotation (server-side)
// Pseudocode for rotation logic
function rotateRefreshToken(oldTokenId, userId) {
  const old = db.refresh_tokens.findById(oldTokenId)
  if (!old || old.revoked) throw new Error('Invalid refresh token')
  if (old.user_id !== userId) throw new Error('Subject mismatch')

  // Revoke old and create new atomically
  db.transaction(() => {
    db.refresh_tokens.revoke(oldTokenId)
    const newTokenId = uuid()
    db.refresh_tokens.insert({ id: newTokenId, user_id: userId, expires_at: now()+30d })
    return signRefreshToken(newTokenId, userId)
  })
}

Rule: if a used refresh token was already rotated, revoke the entire family to stop token replay.

3) Pydantic request validation in FastAPI (input validation)
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, constr, conint

app = FastAPI()

class CreateOrder(BaseModel):
    sku: constr(strip_whitespace=True, min_length=3, max_length=64)
    qty: conint(gt=0, le=1000)
    note: constr(max_length=500) | None = None

@app.post('/orders')
async def create_order(body: CreateOrder):
    # body is validated and sanitized (e.g., stripped strings)
    return { 'ok': True }

Validate every request object, not just the outer payload.

4) Verifying webhook HMAC signature (Python)
import hmac, hashlib, base64

SECRET = b'whsec_abc123'

def verify(signature_header: str, body_bytes: bytes) -> bool:
    # signature_header like: "t=1700000000,v1=base64sig"
    items = dict(kv.split('=') for kv in signature_header.split(','))
    timestamp = items['t']
    supplied = base64.b64decode(items['v1'])

    data = f"{timestamp}.".encode() + body_bytes
    computed = hmac.new(SECRET, data, hashlib.sha256).digest()

    return hmac.compare_digest(computed, supplied)

Always use constant-time comparison and include timestamp to limit replay.

5) Enforcing TLS 1.2+ in Nginx
server {
  listen 443 ssl http2;
  ssl_protocols TLSv1.2 TLSv1.3;
  ssl_ciphers 'ECDHE+AESGCM:ECDHE+CHACHA20';
  ssl_prefer_server_ciphers on;
  add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}

Disable TLS 1.0/1.1, prefer modern ciphers, and add HSTS.

Drills and quick exercises

  • [ ] For one endpoint, write the exact scopes/roles needed and test a denied case.
  • [ ] Rotate your API signing key in a test environment and confirm old tokens fail.
  • [ ] Add input validation to every POST/PUT/PATCH route; reject unknown fields.
  • [ ] Enable TLS 1.2+ only; run a quick scan to confirm older versions are off.
  • [ ] Implement HMAC verification for one inbound webhook, including timestamp and replay window.
  • [ ] Perform a 20-minute OWASP API Top 10 self-audit on one service; list top 3 risks and fixes.

Common mistakes and debugging tips

Typical mistakes
  • Accepting any signed JWT without checking issuer/audience.
  • Long-lived tokens with no rotation or revocation plan.
  • Trusting client-provided roles or user IDs without server-side lookup.
  • Returning verbose auth errors that leak details (e.g., which claim failed).
  • Missing input validation on nested objects and arrays.
  • Skipping signature verification for webhooks or using insecure comparison.
  • Allowing HTTP or old TLS versions in production.
Debugging tips
  • Log token kid, issuer, audience, and high-level reason for denial; never log full tokens or secrets.
  • Compare working vs failing tokens by decoded header/payload (without sensitive claims).
  • Check system clock skew for exp/nbf issues; allow a small leeway if needed.
  • For HMAC, confirm exact message bytes and ordering; mismatched encodings cause false failures.
  • Use structured logs with request IDs and principal IDs for traceability.

Mini project: Secure Orders API

Goal: Build a small Orders API that supports user auth (OIDC), role-based access (admin vs user), strict input validation, and a signed webhook.

Requirements
  • Auth: Authorization Code + PKCE via an OIDC provider; verify iss/aud/exp/nbf.
  • Authorization: roles claim (user, admin). Users can read their own orders; admins can read any.
  • Validation: enforce schema for create/update; reject unknown fields.
  • Transport: HTTPS only, TLS 1.2+; HSTS on.
  • Webhook: POST /webhooks/inventory with HMAC signature and 5-minute replay window.
  • Operations: rotate signing key in dev; ensure old webhooks fail after rotation.
Acceptance checks
  • Access token with missing scope is denied with 403 (generic message).
  • Admin role can fetch any order; user role gets 403 for others' orders.
  • Invalid field in payload triggers 400 with machine-readable error.
  • Webhook with altered body or timestamp outside window is rejected.

Subskills

  • Authentication: OAuth2, OIDC, API keys
  • Authorization: RBAC and ABAC
  • Token handling and rotation
  • Input validation and sanitization
  • Transport security (TLS)
  • Signing and HMAC basics
  • Threat modeling for APIs
  • OWASP API Top 10 awareness

Practical projects

  • Mini: Secure Orders API (described above).
  • Intermediate: Service-to-service auth with mTLS and API keys, including key rotation and per-service quotas.
  • Advanced: Multi-tenant API with ABAC, policy-as-code (e.g., JSON-based rules), and audit logging with redaction.

Next steps

  • Harden monitoring: alert on unusual 401/403 spikes and token validation errors.
  • Add replay protections everywhere tokens or signatures are used.
  • Extend to privacy controls and data minimization for sensitive endpoints.

API Security — Skill Exam

This exam checks practical API Security knowledge: authentication, authorization, token handling, input validation, TLS, signing/HMAC, threat modeling, and OWASP API Top 10. You can take it for free. Progress and results are saved only for logged-in users.Rules: closed-notes, 20–30 minutes, pass score 70%. Choose the best answer(s) where multiple answers are allowed.

11 questions70% to pass

Have questions about API Security?

AI Assistant

Ask questions about this tool