Skip to main content

Latest Post

Record Types & Page Layout Strategy

  Record Types & Page Layout Strategy 💬 In plain words:   Record Types let one object act like different forms for different teams. Different picklist values, page layouts, and processes — same Account object. Use them for truly different business processes. Not for cosmetic layout changes. 📌 Example:   One Account object, two businesses: 'Retail Customer' record type shows B2C picklist values and layout. 'Enterprise Client' shows contract fields and a different sales process. Same table, two costumes. 🧠 One object, many costumes:   A Record Type is a costume on the same object — different picklists and layouts, same table underneath. Concept Record Types split one object into business variants. •   Each type can carry its own subset of picklist values, its own business process — Lead, Case and Opportunity stages — and its own page layout per profile. •   Lightning has changed the calculus. Dynamic Forms and conditional comp...

Object-Level & Field-Level Security (CRUD/FLS)

 Object-Level & Field-Level Security (CRUD/FLS)

💬 In plain words:  Two locks on data: object-level (can you touch Accounts at all — Create/Read/Update/Delete) and field-level (okay, but can you see the Salary field?). Sharing decides WHICH records; CRUD/FLS decides WHAT you can do with the object and its fields.

📌 Example:  Asha can see the Candidate object (object-level ✓) but the Salary field is hidden from her profile (field-level ✗). She opens the record fine — the Salary column is simply not there, even in reports and the API.

Concept

CRUD (object permissions) and FLS (field permissions) are granted via profiles/permission sets and are enforced automatically in the standard UI, standard controllers, and Lightning Data Service — but NOT automatically in Apex, which runs in system mode by default on API v66 and earlier (from v67, user mode is the default — see 3.7). In older code Apex must opt in: SOQL with WITH USER_MODE, DML with 'as user', or Security.stripInaccessible() to sanitize records. This is distinct from record-level sharing (Module 3) — CRUD/FLS answers 'which objects/fields', sharing answers 'which rows'. Directly reused in Module 11.3 (secure SOQL) and Module 9 (LDS enforces FLS for LWC).

🧠 CRUD/FLS vs Sharing:  CRUD/FLS = WHICH objects & fields. Sharing = WHICH rows. Apex runs in SYSTEM mode → you must opt in (USER_MODE / stripInaccessible).

Core Q&A

Q: How do you enforce CRUD/FLS in Apex, and which mechanism do you choose when?

🎯 Say this first:  Use WITH USER_MODE in SOQL/DML as the default; Security.stripInaccessible for cleaning data; manual describe checks only for special cases.

A: Prefer user-mode database operations: 'SELECT ... WITH USER_MODE' and 'insert as user records' — they enforce CRUD, FLS, and sharing together and report all violations. WITH SECURITY_ENFORCED is the older query-only option; it throws on the first violation, ignores polymorphic fields, and does nothing for DML. Security.stripInaccessible(AccessType.READABLE/CREATABLE, records) is the graceful-degradation tool — instead of throwing, it strips fields the user cannot access, which is right for integration-facing or bulk paths where partial success is acceptable. Rule of thumb: user mode as the default in new code, stripInaccessible when you must not throw, SECURITY_ENFORCED only in legacy code you are not refactoring — and note it is REMOVED at API v67+: it no longer compiles (3.7).

// Modern default

List<Case> cases = [SELECT Id, Subject FROM Case

                   WHERE Status = 'Open' WITH USER_MODE];

 

// Graceful degradation

SObjectAccessDecision d = Security.stripInaccessible(

    AccessType.READABLE, cases);

return d.getRecords();

Follow-ups (scenario-based)

Q1: The standard UI hides a field from a user, but your LWC calling an Apex @AuraEnabled method still shows it. Why, and what are the two distinct fixes?

A1: Because the Apex method runs in system mode: FLS was checked by the page layout, not by your query. Fix one: make the Apex enforce security (WITH USER_MODE or stripInaccessible before returning). Fix two: eliminate the custom Apex read path and use Lightning Data Service / getRecord wire, which enforces FLS and CRUD for free and gives you caching (ties into Module 9.6). An architect answer notes the second option is preferred when no complex server logic is needed.

Q2: A configurable approval engine lets business users change rules without engineering. How do you stop that from becoming a privilege-escalation path?

A2: Two layers. First, config objects carry their own CRUD/FLS, so only the 'Approval Config Author' permission set can write rules. Second, the engine's evaluation code is designed carefully: rule evaluation reads config 'without sharing' (rules must apply globally), but every action it takes on the target record is executed in user mode. An approver can never be made to see or edit fields their own FLS forbids. That is, the engine amplifies process authority, never data authority. Stating that separation crisply is a strong architect-round moment.

Read this also :- 
Reports, Dashboards & Analytics Architecture