Security

Security


Identity, Claims, and Roles

• Identity: This represents who the user is, typically verified through an authentication provider and represented by a unique user ID.

• Claims: These are key-value pairs embedded in a token that assert facts about the user, such as their email, tenant_id, or organization_id.

• Roles: Roles group permissions together (e.g., Admin, Viewer, BillingManager) to determine what broad actions an identity is allowed to perform.


JWT and OAuth 2.0

• OAuth 2.0: This framework handles delegated authorization, allowing an application to obtain limited access to user accounts without exposing credentials.

• JSON Web Tokens (JWT): A JWT is a compact, cryptographically signed token used to securely transmit claims between parties.

• Token Verification: Your server must validate the JWT signature, expiration (exp), issuer (iss), and audience (aud) on every incoming request before reading any claims.


Server-Side Authorization

• Zero Trust on Client Inputs: Never rely on a customer_id or tenant_id sent in a URL path, query string, or JSON body to determine data ownership.

• Context Extraction: Extract the trusted tenant_id and roles directly from the validated JWT claims or a server-side session store.

• Middleware Enforcement: Use centralized authorization middleware or policies to verify that the user's role permits the requested action (e.g., checking if a user has pricing:read before executing the controller).


Data-Level Access Control

• Tenant Scoping in Queries: Every database query must include a mandatory WHERE tenant_id = :authenticated_tenant_id clause.

• Row-Level Security (RLS): Databases like PostgreSQL support native RLS policies that automatically filter rows based on the current session's tenant context, acting as a safety net against developer error.

• Indirect Object References: Avoid exposing sequential database IDs (like /invoices/1001) to prevent Insecure Direct Object Reference (IDOR) attacks. Use UUIDs and still enforce ownership checks on every lookup.


Preventing Cross-Customer Data & Pricing Leaks

• Isolate Pricing Tables: Store custom customer pricing in a table explicitly keyed by tenant_id and product_id. Never return a global pricing catalog with customer-specific overrides visible in the payload.

• Server-Side Price Calculation: Always calculate quotes, discounts, and totals on the backend using the authenticated tenant_id. Ignore any price or discount values sent from the frontend.

• Cache Key Isolation: If you cache API responses or pricing tiers (e.g., in Redis), always include the tenant_id in the cache key (e.g., pricing:{tenant_id}:{product_id}) so cached data never bleeds across customers.

• Automated Security Testing: Write integration tests that authenticate as Customer A and explicitly attempt to read, update, or fetch pricing for Customer B's IDs, asserting that the server returns a 403 Forbidden or 404 Not Found.

Comments

Popular posts from this blog

Whitelabel Options

Free AI Tools

Await