Skip to content

CRUD Probing

Weylon Solis edited this page Mar 18, 2026 · 1 revision

CRUD Probing

CRUD probing empirically tests what DML operations the current session can perform on each Salesforce object. Instead of relying on metadata alone, it attempts actual Create, Read, Edit, and Delete operations to determine effective permissions.

How it works

  1. For each target object, ForceHound calls getObjectInfo to discover field metadata (required fields, data types, reference targets, picklist values)
  2. Create probe: Builds a minimal valid record using dummy_values.py value generation, submits via createRecord. If it succeeds, the record is immediately deleted to clean up.
  3. Read probe: Fetches one existing record via getRecordWithFields.
  4. Edit probe (aggressive mode only): Saves the current value of a field, writes a new value, then restores the original.
  5. Delete probe (aggressive mode only): Deletes one existing record per object. This is destructive.

Results are emitted as CrudCanCreate, CrudCanRead, CrudCanEdit, CrudCanDelete edges from the session user to each SF_Object.

Usage

# Basic CRUD probe (create + read only)
forcehound --collector aura ... --crud -o output.json

# Aggressive mode (create + read + edit + delete)
forcehound --collector aura ... --crud --aggressive -o output.json

# Limit to specific objects
forcehound --collector aura ... --crud --crud-objects Account,Contact,Opportunity

# Dry run — log what would be probed without executing
forcehound --collector aura ... --crud --crud-dry-run

# Allow delete-probing protected objects (User, Profile, etc.)
forcehound --collector aura ... --crud --aggressive --unsafe

Edge kinds

Edge Meaning
CrudCanCreate Session user can create records of this object type
CrudCanRead Session user can read records of this object type
CrudCanEdit Session user can edit records of this object type
CrudCanDelete Session user can delete records of this object type

These are distinct from the API collector's CanCreate/CanRead/CanEdit/CanDelete edges, which represent metadata-declared ObjectPermissions on PermissionSets.

Skipped objects

Certain objects are always skipped to avoid disrupting org configuration:

  • System objects: Organization, SetupAuditTrail, LoginHistory, ApexLog, AsyncApexJob, CronTrigger, CronJobDetail
  • Identity objects: Profile, PermissionSet, PermissionSetAssignment, PermissionSetGroup, PermissionSetGroupComponent, UserRole, GroupMember
  • Objects ending in: __ChangeEvent, __Share, __Feed, __History

Protected objects (aggressive delete)

Even in aggressive mode, the following objects are protected from deletion unless --unsafe is used:

User, Profile, PermissionSet, UserRole, Group, Organization, plus auth/integration objects (OAuthToken, ConnectedApplication, ExternalDataSource, NamedCredential), Apex code objects, Aura/LWC bundles, Visualforce objects, Flows, and audit/logging objects.

Customizing dummy values

Edit forcehound/collectors/crud/dummy_values.py to customize the values used for create/edit probes. The module generates type-appropriate dummy values (strings, numbers, dates, emails, URLs, picklist selections, reference lookups) based on field metadata.

Deletion log

In aggressive mode, deletions are logged to forcehound_deletions_<timestamp>.json with the record ID, object name, and field snapshot of each deleted record.

Clone this wiki locally