← All posts
· 3 min read ·
DevSecOpsSecuritySalesforceCI/CD

DevSecOps in the Salesforce Ecosystem

Security can't be a final gate before production. Here's how to integrate it into every phase of the Salesforce development lifecycle without killing developer velocity.

Circuit board representing integrated DevSecOps systems

DevSecOps in the Salesforce world has a particular challenge that pure software teams don’t face: your “code” is a mix of Apex, metadata configuration, declarative automation, and managed package customisation. Each requires a different approach to security.

The goal is the same as any DevSecOps implementation: make security continuous, automated, and fast enough that it doesn’t create friction.

The Four Security Layers

Salesforce DevSecOps operates on four layers simultaneously:

Code layer - Apex, LWC, Aura, Visualforce. Static analysis, secrets scanning, dependency scanning. Standard DevSecOps tooling applies.

Configuration layer - Profiles, permission sets, sharing rules, connected apps. Configuration drift is a security vulnerability. This layer is often missed entirely.

Platform layer - Salesforce’s own security posture - Health Check, Shield, Event Monitoring. The platform has security controls; you have to use them.

Integration layer - Every API endpoint, webhook, connected app, and OAuth flow. This is the attack surface that keeps growing.

Continuous Configuration Scanning

Configuration changes are code changes. A permission set modification that grants “Modify All Data” to a new profile is as dangerous as a SQL injection vulnerability - more dangerous, because it’s instant and doesn’t require exploit code.

Build a daily (or pipeline-triggered) scan that checks for:

- name: Scan configuration for security violations
  run: |
    sf org display --json | jq '.result.orgId' > org-id.txt

    # Check for overprivileged profiles
    sf data query \
      --query "SELECT Name FROM Profile WHERE PermissionsModifyAllData = true AND Name != 'System Administrator'" \
      --result-format csv

    # Check for exposed API access
    sf data query \
      --query "SELECT Name FROM ConnectedApplication WHERE RefreshTokenValidityPeriod = 0" \
      --result-format csv

Alert on any result. These should be empty in a well-governed org.

Security as a Pipeline Stage

The pipeline order matters:

Commit → SAST (Apex/LWC) → Config scan → Dependency check → Deploy to sandbox → Integration tests → Security smoke test → Deploy to production

The security smoke test in staging is often skipped. It shouldn’t be. It verifies:

  • Login works with MFA
  • IP restrictions are enforced correctly
  • Named Credentials resolve to the right endpoints
  • No Apex test has SeeAllData=true in production-bound code

Managing Third-Party Risk

Managed packages are third-party software installed directly into your org with Apex execution privileges. They can read any data the installing user can access. They can make outbound callouts. They have permissions that most developers never audit.

Build a managed package inventory with:

  • Package version and last-update date
  • Permissions requested (from the package’s PackageLicense)
  • Last security review date
  • Business justification

Run this quarterly. Flag packages that haven’t been updated in 12 months.

Incident Response Preparation

DevSecOps includes preparing for when security fails. For Salesforce:

Detection - Event Monitoring forwarded to SIEM, with alerts for: admin login from new country, bulk data export, permission escalation, unusual API call volume.

Containment - Know how to: freeze a user account in 30 seconds, revoke a Connected App’s tokens, enable enhanced login security for all users, and pull Event Monitoring logs for a given time window.

Recovery - Your production org’s metadata is in git. Your data can be restored from backup. Know your RTO and RPO.

Document the runbook before you need it. Practice it.

The Developer Experience Tradeoff

Security tools add friction. The goal is to make the friction invisible - fail fast on obvious issues (a 30-second scan on git push) and reserve longer checks for the pipeline stages where the developer is already waiting for feedback.

The worst implementation: a 20-minute security scan blocking every commit. The developer disables it within a week.

The best implementation: 30-second quick scan on commit, full scan in CI while the PR is in review, so there’s always a result waiting before the reviewer finishes reading the code. Zero additional wait time, complete coverage.

That’s the DevSecOps goal: security that runs faster than the developer moves.

← All posts