From salesforce-pack
Guides Salesforce security for Connected Apps, OAuth scopes, integration users, credential storage, and field-level security. Use when securing API access or auditing configurations.
npx claudepluginhub jeremylongshore/claude-code-plugins-plus-skills --plugin salesforce-packThis skill is limited to using the following tools:
Security best practices for Salesforce integrations: Connected App configuration, OAuth scope management, field-level security, and credential rotation.
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Guides building MCP servers enabling LLMs to interact with external services via tools. Covers best practices, TypeScript/Node (MCP SDK), Python (FastMCP).
Generates original PNG/PDF visual art via design philosophy manifestos for posters, graphics, and static designs on user request.
Security best practices for Salesforce integrations: Connected App configuration, OAuth scope management, field-level security, and credential rotation.
Setup > App Manager > New Connected App:
1. Enable OAuth Settings
2. Callback URL: https://yourapp.com/oauth/callback (NOT localhost in prod)
3. Selected OAuth Scopes — USE MINIMUM REQUIRED:
- "Manage user data via APIs (api)" — for REST/SOQL access
- "Perform requests at any time (refresh_token, offline_access)" — for refresh tokens
- DO NOT add "Full access (full)" unless absolutely necessary
4. Require Proof Key for Code Exchange (PKCE): Enable for public clients
5. Require Secret for Web Server Flow: Enable
6. IP Relaxation: "Enforce IP restrictions" (not "Relax IP restrictions")
# .env (NEVER commit to git)
SF_LOGIN_URL=https://login.salesforce.com
SF_USERNAME=integration-user@yourcompany.com
SF_PASSWORD=<from-vault>
SF_SECURITY_TOKEN=<from-vault>
SF_CLIENT_ID=<connected-app-consumer-key>
SF_CLIENT_SECRET=<connected-app-consumer-secret>
# .gitignore — ALWAYS include
.env
.env.local
.env.*.local
server.key # JWT private key
*.pem
*.key
Create a dedicated Salesforce user for API access:
1. Profile: Create "API Integration" profile (clone from Standard User)
- Login Hours: restrict to expected operating hours
- Login IP Ranges: restrict to your server IPs
- Object permissions: ONLY objects your integration needs
2. Permission Set: "Integration API Access"
- Object: Account — Read, Create, Edit (no Delete)
- Object: Contact — Read, Create, Edit (no Delete)
- Field-Level Security: only expose fields the integration reads/writes
3. NEVER use a System Administrator user for integrations
// Always check FLS before operations — especially for managed packages
const conn = await getConnection();
const meta = await conn.sobject('Account').describe();
// Check if field is accessible (readable)
const industryField = meta.fields.find(f => f.name === 'Industry');
if (!industryField?.accessible) {
throw new Error('Industry field is not accessible — check FLS');
}
// Check if field is updateable (writable)
if (!industryField?.updateable) {
console.warn('Industry field is read-only for this user');
}
// Check which fields the current user can actually see
const accessibleFields = meta.fields
.filter(f => f.accessible)
.map(f => f.name);
console.log('Accessible fields:', accessibleFields.length);
# Salesforce security tokens auto-reset when password changes
# Rotation procedure:
# 1. Setup > My Personal Information > Reset My Security Token
# 2. New token is emailed to the user
# 3. Update SF_SECURITY_TOKEN in your vault/env
# 4. Verify connection works with new token
# 5. For JWT: rotate the certificate in the Connected App
# Automate rotation check
sf org display --target-org integration-user --json | jq '.result.accessToken'
// Query Setup Audit Trail for security events
const auditTrail = await conn.query(`
SELECT CreatedDate, CreatedBy.Username, Action, Section, Display
FROM SetupAuditTrail
WHERE CreatedDate >= LAST_N_DAYS:7
AND (Section = 'Connected Apps' OR Section = 'Users' OR Section = 'Profiles')
ORDER BY CreatedDate DESC
LIMIT 50
`);
for (const entry of auditTrail.records) {
console.log(`${entry.CreatedDate} | ${entry.CreatedBy?.Username} | ${entry.Action} | ${entry.Display}`);
}
full).env and *.key files in .gitignore| Security Issue | Detection | Mitigation |
|---|---|---|
| Exposed credentials in git | git log -p --all -S 'SF_PASSWORD' | Rotate immediately, use git-secrets |
| Overprivileged user | Check profile permissions | Create restricted integration profile |
| Missing FLS | Describe call shows accessible: false | Update Permission Set |
| IP not whitelisted | LOGIN_MUST_USE_SECURITY_TOKEN | Add IP to login IP ranges |
For production deployment, see salesforce-prod-checklist.