sf-agent-framework
Version:
AI Agent Orchestration Framework for Salesforce Development - Two-phase architecture with 70% context reduction
588 lines (461 loc) • 13.5 kB
Markdown
# Salesforce Security Best Practices
## Overview
Security is paramount in Salesforce implementations. This guide provides
comprehensive best practices for securing your Salesforce org, data, and
integrations.
## Security Architecture
### Defense in Depth
**Layer 1: Perimeter Security**
- IP restrictions
- Login hours
- Network access controls
- VPN requirements
**Layer 2: Identity and Access**
- Strong authentication
- Multi-factor authentication (MFA)
- Single Sign-On (SSO)
- Session management
**Layer 3: Application Security**
- Profile and permission sets
- Field-level security
- Object permissions
- Apex security
**Layer 4: Data Security**
- Encryption at rest
- Encryption in transit
- Data masking
- Classification
### Zero Trust Model
- Never trust, always verify
- Least privilege access
- Continuous verification
- Assume breach mentality
- Micro-segmentation
## Authentication Best Practices
### Password Policies
```yaml
Minimum Requirements:
Length: 12 characters
Complexity:
- Uppercase letters
- Lowercase letters
- Numbers
- Special characters
History: Last 12 passwords
Expiration: 90 days
Lockout: 5 failed attempts
Reset: Secure email process
```
### Multi-Factor Authentication (MFA)
**Implementation Strategy**:
1. **Phase 1**: Admins and privileged users
2. **Phase 2**: All internal users
3. **Phase 3**: Partner and customer users
**MFA Methods**:
- Salesforce Authenticator (recommended)
- SMS (being phased out)
- Time-based tokens (TOTP)
- Security keys (U2F/WebAuthn)
### Single Sign-On (SSO)
**SAML Configuration**:
```xml
<saml:Assertion>
<saml:Subject>
<saml:NameID Format="email">user@company.com</saml:NameID>
</saml:Subject>
<saml:AttributeStatement>
<saml:Attribute Name="username"/>
<saml:Attribute Name="email"/>
<saml:Attribute Name="federation_id"/>
</saml:AttributeStatement>
</saml:Assertion>
```
**SSO Best Practices**:
- Use federation ID for mapping
- Implement Just-In-Time provisioning
- Regular certificate rotation
- Monitor failed SSO attempts
- Have break-glass procedures
## Access Control
### Organization-Wide Defaults (OWD)
**Restrictive by Default**:
```yaml
Recommended Settings:
Account: Private
Contact: Controlled by Parent
Opportunity: Private
Case: Private
Custom Objects: Private
Exceptions:
- Public read-only for reference data
- Controlled by parent for tight relationships
```
### Profile and Permission Set Strategy
**Profile Minimization**:
```apex
// Base profiles with minimal permissions
Standard User Profile:
- Read on most objects
- No modify all
- No view all
- Limited system permissions
// Permission sets for additional access
Permission Set: Sales_Data_Access
- Edit Opportunity
- Edit Account
- Run Reports
Permission Set: Marketing_User
- Manage Campaigns
- Import Leads
- Mass Email
```
### Role Hierarchy
**Design Principles**:
- Mirror organizational structure
- Minimize hierarchy depth
- Avoid circular references
- Regular review and cleanup
- Document role purposes
### Sharing Rules
**Types and Usage**:
1. **Ownership-Based**: Share based on record owner
2. **Criteria-Based**: Share based on field values
3. **Manual Sharing**: Ad-hoc sharing needs
4. **Apex Sharing**: Programmatic complex sharing
**Best Practice Implementation**:
```apex
public class SharingManager {
public static void shareWithTeam(Id recordId, Id teamId) {
CustomObject__Share share = new CustomObject__Share(
ParentId = recordId,
UserOrGroupId = teamId,
AccessLevel = 'Read',
RowCause = Schema.CustomObject__Share.RowCause.Team_Member__c
);
Database.SaveResult sr = Database.insert(share, false);
if(!sr.isSuccess()) {
// Handle sharing failure
logSharingError(sr.getErrors());
}
}
}
```
## Field-Level Security
### Data Classification
```yaml
Public:
- Company name
- Published content
- Marketing materials
Internal:
- Employee information
- Internal procedures
- Department data
Confidential:
- Customer PII
- Financial data
- Contracts
Restricted:
- SSN/Tax IDs
- Credit card data
- Health information
```
### Field Security Implementation
```apex
// Check field-level security in Apex
public static Boolean isFieldAccessible(String objectName, String fieldName) {
Schema.DescribeFieldResult fieldDescribe = Schema.getGlobalDescribe()
.get(objectName)
.getDescribe()
.fields
.getMap()
.get(fieldName)
.getDescribe();
return fieldDescribe.isAccessible();
}
// Enforce FLS in SOQL
List<Contact> contacts = [SELECT Id, Name, SSN__c
FROM Contact
WITH SECURITY_ENFORCED];
```
## Data Encryption
### Platform Encryption
**What to Encrypt**:
- PII fields (SSN, DOB, etc.)
- Financial data
- Health information
- Sensitive custom fields
- Files and attachments
- Search indexes
**Encryption Configuration**:
```yaml
Encryption Policy:
Algorithm: AES-256
Key Rotation: Quarterly
Key Derivation: Tenant secrets
Bring Your Own Key: Optional
Fields to Encrypt:
- Account.Tax_ID__c
- Contact.Social_Security_Number__c
- Case.Medical_Record_Number__c
- Custom_Object__c.Sensitive_Data__c
```
### Classic Encryption
- Use for specific compliance needs
- 175-character limit
- Masked by default
- Special permissions required
- Not searchable
## Apex Security
### CRUD/FLS Enforcement
```apex
public with sharing class SecureController {
public static List<Account> getAccounts() {
// Check object accessibility
if (!Schema.sObjectType.Account.isAccessible()) {
throw new SecurityException('Insufficient access to Account');
}
// Check field accessibility
if (!Schema.sObjectType.Account.fields.Name.isAccessible() ||
!Schema.sObjectType.Account.fields.AnnualRevenue.isAccessible()) {
throw new SecurityException('Insufficient field access');
}
// Use WITH SECURITY_ENFORCED
return [SELECT Id, Name, AnnualRevenue
FROM Account
WHERE OwnerId = :UserInfo.getUserId()
WITH SECURITY_ENFORCED];
}
}
```
### Input Validation
```apex
public class InputValidator {
// Prevent SOQL injection
public static String sanitizeInput(String userInput) {
return String.escapeSingleQuotes(userInput);
}
// Validate email format
public static Boolean isValidEmail(String email) {
String emailRegex = '^[a-zA-Z0-9._|\\%#~`=?&/$^*!}{+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$';
Pattern pattern = Pattern.compile(emailRegex);
Matcher matcher = pattern.matcher(email);
return matcher.matches();
}
// Prevent XSS
public static String escapeHtml(String input) {
return input.escapeHtml4();
}
}
```
### Secure Coding Practices
```apex
// Use bind variables
String accountName = 'Acme%';
List<Account> accounts = [SELECT Id FROM Account WHERE Name LIKE :accountName];
// Avoid dynamic SOQL when possible
// If necessary, validate thoroughly
public static List<SObject> dynamicQuery(String objectName, String fields) {
// Whitelist validation
Set<String> allowedObjects = new Set<String>{'Account', 'Contact', 'Lead'};
if (!allowedObjects.contains(objectName)) {
throw new SecurityException('Invalid object');
}
// Build query safely
String query = 'SELECT ' + String.escapeSingleQuotes(fields) +
' FROM ' + String.escapeSingleQuotes(objectName) +
' WITH SECURITY_ENFORCED';
return Database.query(query);
}
```
## Integration Security
### API Security
**Authentication Methods**:
1. **OAuth 2.0**: Recommended for web apps
2. **JWT Bearer**: Server-to-server
3. **Username-Password**: Legacy, avoid
4. **Session ID**: Internal use only
**OAuth Implementation**:
```javascript
// OAuth 2.0 flow
const oauth2 = new OAuth2({
clientId: process.env.SF_CLIENT_ID,
clientSecret: process.env.SF_CLIENT_SECRET,
redirectUri: process.env.SF_REDIRECT_URI,
authorizationUrl: 'https://login.salesforce.com/services/oauth2/authorize',
tokenUrl: 'https://login.salesforce.com/services/oauth2/token',
});
// Refresh token rotation
function refreshAccessToken(refreshToken) {
return oauth2.refreshToken(refreshToken).then((response) => {
// Store new tokens securely
secureStorage.set('access_token', response.access_token);
secureStorage.set('refresh_token', response.refresh_token);
return response.access_token;
});
}
```
### Named Credentials
```xml
<NamedCredential>
<fullName>External_System</fullName>
<label>External System</label>
<type>SecuredEndpoint</type>
<endpoint>https://api.external.com</endpoint>
<principalType>NamedUser</principalType>
<protocol>OAuth2</protocol>
<authProvider>External_Auth_Provider</authProvider>
</NamedCredential>
```
### Secure Callouts
```apex
public class SecureCallout {
public static HttpResponse makeCallout(String endpoint, String body) {
Http http = new Http();
HttpRequest request = new HttpRequest();
// Use named credential
request.setEndpoint('callout:External_System' + endpoint);
request.setMethod('POST');
request.setHeader('Content-Type', 'application/json');
// Encrypt sensitive data
if (containsSensitiveData(body)) {
body = encryptPayload(body);
request.setHeader('X-Encrypted', 'true');
}
request.setBody(body);
request.setTimeout(120000); // 2 minutes
try {
HttpResponse response = http.send(request);
logCallout(request, response);
return response;
} catch (Exception e) {
logError(e);
throw new CalloutException('Callout failed: ' + e.getMessage());
}
}
}
```
## Session Security
### Session Settings
```yaml
Recommended Configuration:
Timeout: 2 hours
Timeout Warning: 15 minutes
Disable Session ID in URL: Yes
Lock Sessions to IP: Yes (with caution)
Lock Sessions to Domain: Yes
Force Relogin on Login Page: Yes
Clickjack Protection: Enabled for all pages
XSS Protection: Enabled
Content Sniffing Protection: Enabled
```
### Session Management
```apex
// Monitor concurrent sessions
public class SessionMonitor {
public static void checkConcurrentSessions() {
List<AuthSession> sessions = [SELECT Id, UsersId, CreatedDate,
SourceIp, LoginType
FROM AuthSession
WHERE UsersId = :UserInfo.getUserId()
AND IsCurrent = false];
if (sessions.size() > 3) {
// Alert on suspicious activity
createSecurityAlert('Multiple concurrent sessions detected');
}
}
}
```
## Monitoring and Auditing
### Event Monitoring
```apex
// Real-time event monitoring
public class SecurityEventMonitor {
public static void monitorLoginEvent(LoginEvent event) {
if (event.Status != 'Success') {
// Track failed logins
if (getFailedLoginCount(event.UserId) > 3) {
lockUserAccount(event.UserId);
notifySecurityTeam(event);
}
} else if (isAnomalousLogin(event)) {
// Detect unusual login patterns
requireAdditionalVerification(event.UserId);
}
}
}
```
### Audit Logging
**What to Audit**:
- Login/logout events
- Data access (read)
- Data modifications (create/update/delete)
- Configuration changes
- Permission changes
- Failed access attempts
- API usage
- Report/Dashboard access
### Security Health Check
- Run monthly
- Review critical risks
- Address high-risk items immediately
- Track score improvements
- Document remediations
## Incident Response
### Incident Response Plan
```yaml
Phases:
1. Preparation:
- Response team identified
- Tools and access ready
- Playbooks documented
2. Detection:
- Monitoring alerts
- User reports
- Automated detection
3. Containment:
- Isolate affected systems
- Preserve evidence
- Stop the breach
4. Eradication:
- Remove threat
- Patch vulnerabilities
- Update controls
5. Recovery:
- Restore services
- Monitor closely
- Verify security
6. Lessons Learned:
- Document incident
- Update procedures
- Improve controls
```
## Security Best Practices Checklist
### Daily
- [ ] Review login failures
- [ ] Check security alerts
- [ ] Monitor API usage
- [ ] Verify backup completion
### Weekly
- [ ] Review user access changes
- [ ] Check sharing rule modifications
- [ ] Audit privileged operations
- [ ] Review integration logs
### Monthly
- [ ] Run Security Health Check
- [ ] Review and deprovision unused users
- [ ] Audit permission changes
- [ ] Update security documentation
- [ ] Security training/awareness
### Quarterly
- [ ] Penetration testing
- [ ] Security assessment
- [ ] Policy review and update
- [ ] Disaster recovery testing
- [ ] Third-party security reviews
### Annually
- [ ] Complete security audit
- [ ] Policy comprehensive review
- [ ] Security architecture review
- [ ] Compliance certification
- [ ] Security roadmap planning