Co-Founder & CTO, LegelpTech
APIs are the attack surface of modern applications. In 2025, API-related breaches accounted for the majority of data exposure incidents — not because APIs are inherently insecure, but because most teams treat security as an afterthought rather than a design constraint. Every integration point, every public endpoint, every webhook is a potential entry vector. This guide covers the security architecture we implement across every API project — from authentication design to runtime threat detection.
These aren't theoretical best practices pulled from a textbook. They're battle-tested patterns from building enterprise APIs for fintech platforms handling payment data, healthcare systems processing PHI, and e-commerce platforms managing millions of customer records. If your API handles sensitive data or faces the public internet, every section here applies to you.
Backend engineers, architects, and CTOs building or maintaining REST/GraphQL APIs that serve external consumers (partner integrations, mobile apps, third-party developers). Especially relevant if you're approaching a SOC 2, PCI-DSS, or HIPAA compliance audit.
Not for you if: You're building purely internal microservice communication (that has different threat models) or looking for vendor-specific configuration guides.
Before diving into solutions, understand the threats. The OWASP API Security Top 10 represents the most common and impactful API vulnerabilities. Here's how they map to real-world exploits and the controls that address them:
| Vulnerability | Real-World Impact | Primary Defense | Section Below |
|---|---|---|---|
| Broken Object-Level Auth (BOLA) | Users access other users' data by changing IDs | Object-level authorization checks | Authorization |
| Broken Authentication | Account takeover, credential stuffing | OAuth 2.0 + PKCE, MFA | Authentication |
| Broken Object Property-Level Auth | Mass assignment, data leakage | Schema validation, response filtering | Input Validation |
| Unrestricted Resource Consumption | DDoS, resource exhaustion, cost spikes | Rate limiting, payload limits | Rate Limiting |
| Broken Function-Level Auth | Privilege escalation | RBAC, middleware enforcement | Authorization |
| Server-Side Request Forgery (SSRF) | Internal network scanning | URL allowlisting, egress filtering | Network Security |
| Security Misconfiguration | Exposed debug endpoints, verbose errors | Hardened defaults, security headers | Configuration |
| Lack of Protection from Automated Threats | Scraping, credential stuffing, inventory hoarding | Bot detection, behavioral analysis | Monitoring |
Authentication verifies who is making the request. The choice of authentication mechanism depends on who your API consumers are.
| Consumer Type | Recommended Auth | Why | Token Lifetime |
|---|---|---|---|
| Web/Mobile Apps (user-facing) | OAuth 2.0 + PKCE | No client secret exposure, industry standard | Access: 15 min, Refresh: 7 days |
| Server-to-Server | API Keys + HMAC Signatures | No user context needed, request integrity | Key rotation: every 90 days |
| Enterprise SSO | SAML 2.0 / OIDC | Enterprise identity provider integration | Session: 8 hours max |
| Third-party developers | OAuth 2.0 Client Credentials | Scoped access, revocable | Access: 1 hour, no refresh |
| Webhooks (outbound) | HMAC-SHA256 Signatures | Receiver verifies payload integrity | Per-request, no expiry |
If you use JWTs (and most modern APIs do), these rules are non-negotiable: always validate the signature using your public key (never accept unsigned tokens or the "none" algorithm), set short access token expiration (15 minutes maximum), implement refresh token rotation (each refresh token is single-use — using it issues a new one and invalidates the old), store refresh tokens server-side in a database (not in localStorage or cookies without proper flags), include only essential claims in the token payload (user ID, roles, tenant ID — never PII), and use RS256 or ES256 signing algorithms (not HS256, which uses a shared secret).
Never use basic authentication for production APIs. Basic auth sends credentials in every request (base64-encoded, not encrypted). Even over HTTPS, this creates unnecessary exposure — credentials can be logged, cached by proxies, or leaked through browser history. Use it only for initial token exchange, never for ongoing API calls.
Authentication tells you who they are. Authorization determines what they can do. The #1 API vulnerability (BOLA) is an authorization failure — users accessing resources they shouldn't by simply changing an ID parameter.
Implement authorization at three layers for defense in depth: gateway-level (verify the token is valid and has the required scope), service-level (verify the user's role has permission for this endpoint/action), and object-level (verify the user has access to this specific resource instance). Most API breaches happen because teams implement the first two layers but skip object-level authorization. Every database query must include a tenant/owner filter — never rely on the URL alone to determine ownership.
| Model | Best For | Complexity | Example |
|---|---|---|---|
| RBAC (Role-Based) | Most B2B SaaS, internal tools | Low | Admin can edit, Viewer can read |
| ABAC (Attribute-Based) | Complex enterprise, multi-tenant | Medium | User in EU can access EU data during business hours |
| ReBAC (Relationship-Based) | Social, document sharing, org hierarchies | High | User can edit if they're in the document's workspace |
Rate limiting protects your API from abuse, prevents resource exhaustion, and ensures fair usage across consumers. Without it, a single misbehaving client can bring down your entire platform.
Implement rate limits at multiple granularities, not just a global limit. Each layer catches a different type of abuse:
| Layer | Scope | Typical Limit | Purpose |
|---|---|---|---|
| Global | All requests across all clients | 10,000 req/sec | DDoS protection, infrastructure safety |
| Per-API Key | Single integration | 100–1,000 req/min | Fair usage, plan enforcement |
| Per-User | Individual authenticated user | 30–100 req/min | Prevent account-level abuse |
| Per-IP | Unauthenticated requests | 10–30 req/min | Brute force protection |
| Per-Endpoint | Sensitive operations | 5–10 req/min | Protect expensive/sensitive endpoints |
Use the token bucket algorithm for smoother rate limiting rather than fixed windows. Token bucket allows bursts (e.g., 10 requests in 1 second) while maintaining the average rate limit. Always return proper 429 Too Many Requests responses with Retry-After and X-RateLimit-Remaining headers so clients can self-regulate.
Every piece of data entering your API is potentially malicious until validated. Input validation is your first line of defense against injection attacks, data corruption, and business logic manipulation.
application/json (or whatever your API supports).limit=999999999 can exhaust your database.Encryption protects data confidentiality. You need it at two levels: transport encryption (protecting data as it moves across the network) and field-level encryption (protecting specific sensitive data elements even if an attacker gains database access).
Enforce TLS 1.3 (or TLS 1.2 minimum) for all API traffic. Disable TLS 1.0 and 1.1 entirely — they have known vulnerabilities. Configure HSTS (HTTP Strict Transport Security) headers with a minimum max-age of 1 year. Use certificate pinning for mobile applications to prevent man-in-the-middle attacks via compromised certificate authorities.
For sensitive data (PII, payment information, health records), transport encryption alone is insufficient. Implement application-level encryption using AES-256-GCM for these fields. This means the data is encrypted before it reaches the database and decrypted only when needed by the application. Even a database breach or backup leak doesn't expose the raw data. Store encryption keys in a managed KMS (AWS KMS, Azure Key Vault, Google Cloud KMS, or HashiCorp Vault) — never in application code, config files, or environment variables on the same server.
You can't defend against attacks you can't see. API security monitoring is not optional — it's the difference between catching a breach in minutes versus discovering it months later in a compliance audit.
Log every API request with: timestamp, source IP, authenticated user/API key, HTTP method and endpoint, response status code, response latency, request size, and a correlation ID for tracing. Never log request bodies containing passwords, tokens, credit card numbers, or PII. Use structured logging (JSON) for machine-parseable analysis.
Set up real-time alerts for these security-relevant events:
API versioning is a security concern, not just a compatibility concern. Old API versions often lack security improvements present in newer versions, and supporting deprecated versions indefinitely increases your attack surface.
| Versioning Strategy | Approach | Pros | Cons |
|---|---|---|---|
| URL Path | /v1/users | Clear, easy to route, cache-friendly | URL duplication |
| Header | Accept: application/vnd.api.v2+json | Clean URLs, REST-pure | Harder to test, debug |
| Query Parameter | /users?version=2 | Easy to implement | Cache issues, not RESTful |
We recommend URL path versioning for most enterprise APIs — it's the clearest for consumers and easiest to route at the gateway level. When deprecating an API version: provide minimum 6-month notice, send Deprecation and Sunset headers on every response, monitor usage metrics to track migration progress, and hard-sunset the old version only when active usage drops below 1% of peak.
Misconfigured CORS and missing security headers are among the easiest vulnerabilities to exploit — and the easiest to fix. Here's the security header configuration that every production API should have:
CORS (Cross-Origin Resource Sharing)
Never use Access-Control-Allow-Origin: * for authenticated APIs. Whitelist specific domains. For APIs consumed by your own frontend only, restrict to your exact domain(s). For public APIs, restrict to registered domains and validate the Origin header against your whitelist.
Security Headers
Set X-Content-Type-Options: nosniff (prevents MIME-type sniffing), X-Frame-Options: DENY (prevents clickjacking), Strict-Transport-Security (forces HTTPS), and Cache-Control: no-store for endpoints returning sensitive data.
API Gateway Security
Deploy an API gateway (Kong, AWS API Gateway, Apigee) in front of your services. The gateway handles TLS termination, authentication, rate limiting, and request/response transformation — keeping your service code focused on business logic rather than cross-cutting security concerns.
Use this checklist before deploying any API to production. Every item should be verified:
☐ TLS 1.2+ enforced, TLS 1.0/1.1 disabled
☐ OAuth 2.0/PKCE for user-facing, API keys + HMAC for server-to-server
☐ JWT tokens with short expiration (≤15 min), refresh token rotation enabled
☐ Object-level authorization on every endpoint (not just role checks)
☐ Rate limiting at global, per-key, per-user, and per-IP levels
☐ JSON Schema validation for all request bodies
☐ Payload size limits enforced at gateway
☐ No sensitive data in URL parameters
☐ Response DTOs — never return raw database objects
☐ Field-level encryption for PII and sensitive data (AES-256-GCM)
☐ Encryption keys in managed KMS (not in code or config files)
☐ Structured logging with correlation IDs
☐ No passwords, tokens, or PII in logs
☐ Real-time alerting for auth failures, error spikes, anomalies
☐ CORS restricted to known domains (no wildcards for auth APIs)
☐ Security headers set (HSTS, X-Content-Type-Options, X-Frame-Options)
☐ API versioning with deprecation headers
☐ Error responses reveal no internal details (stack traces, SQL, paths)
☐ OWASP API Top 10 self-assessment completed
Key takeaway: API security is not a feature you add before launch — it's an architectural decision made at design time. Every security control described above is cheaper to implement during initial development than to retrofit after deployment. The cost of securing an API during development is 5–10% of the project budget. The cost of a security breach is 10–100x that amount, plus reputational damage that can't be quantified.
Both, for different consumers. API keys are simpler and appropriate for server-to-server integrations where there's no user context. OAuth 2.0 is required when user identity matters (user-facing applications, third-party developer access, or any scenario where you need delegated authorization). Most production APIs support both.
Layer your defenses: use a CDN/WAF (Cloudflare, AWS Shield) for network-level DDoS protection, implement rate limiting at the API gateway for application-level protection, set payload size limits to prevent resource exhaustion, and use auto-scaling to absorb legitimate traffic spikes. For critical APIs, consider dedicated DDoS protection services that provide always-on monitoring and mitigation.
Support overlapping validity — when rotating, issue a new key while keeping the old key active for a grace period (typically 24–72 hours). This allows consumers to update their integrations without downtime. Notify consumers via email 7 days before the old key expires. Log usage of deprecated keys so you can track migration progress.
GraphQL introduces unique challenges: query depth limiting (prevent deeply nested queries that exhaust resources), query complexity analysis (assign costs to fields and reject queries exceeding a threshold), field-level authorization (GraphQL resolvers must check permissions per field, not just per endpoint), and introspection disabling in production (the schema itself is an information leak).
For API gateways: Kong, AWS API Gateway, or Apigee. For runtime security: 42Crunch, Salt Security, or Noname Security. For testing: OWASP ZAP (free), Burp Suite (professional), or Postman with security test collections. For monitoring: Datadog API Security, Elastic APM, or the ELK stack. Start with the gateway and monitoring — they provide the highest security ROI.
Co-Founder & CTO, LegelpTech
Chandra leads LegelpTech's engineering organization and oversees the technical architecture of all client projects. With deep expertise in cloud infrastructure, API design, and automation systems, he brings hands-on technical leadership to every engagement.
Chandra Prakash · 16 min read
SaaS DevelopmentChandra Prakash · 14 min read
Cloud MigrationChandra Prakash · 16 min read
Our team brings deep technical knowledge to every engagement. Let's discuss your requirements.
Talk to Our Team