connected-app-security-policies
Managing OAuth policies, IP relaxation, session security, PKCE, and credential rotation for Salesforce Connected Apps. Use when hardening Connected App security, rotating client secrets, configuring IP restrictions, or requiring high-assurance sessions. NOT for basic Connected App setup or creation. NOT for OAuth flow implementation (use oauth-flows-and-connected-apps).
Best use case
connected-app-security-policies is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Managing OAuth policies, IP relaxation, session security, PKCE, and credential rotation for Salesforce Connected Apps. Use when hardening Connected App security, rotating client secrets, configuring IP restrictions, or requiring high-assurance sessions. NOT for basic Connected App setup or creation. NOT for OAuth flow implementation (use oauth-flows-and-connected-apps).
Teams using connected-app-security-policies should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/connected-app-security-policies/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How connected-app-security-policies Compares
| Feature / Agent | connected-app-security-policies | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Managing OAuth policies, IP relaxation, session security, PKCE, and credential rotation for Salesforce Connected Apps. Use when hardening Connected App security, rotating client secrets, configuring IP restrictions, or requiring high-assurance sessions. NOT for basic Connected App setup or creation. NOT for OAuth flow implementation (use oauth-flows-and-connected-apps).
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Connected App Security Policies This skill activates when a practitioner needs to harden, audit, or troubleshoot the OAuth access policies attached to an existing Salesforce Connected App — covering IP relaxation modes, PKCE, high-assurance sessions, JWT Bearer clock drift, and zero-grace-period client secret rotation. --- ## Before Starting Gather this context before working on anything in this domain: - Identify the Connected App by name and the OAuth flow type it uses (Web Server / JWT Bearer / User-Agent / Device / Refresh Token). - Confirm whether the org has Login IP Ranges set on profiles or network access settings — IP relaxation interacts with both. - Note the API version of any automated tooling touching this Connected App; ECA (External Client Apps) policy model became default in API v65 and promotes credential rotation instantly with no grace period. --- ## Core Concepts ### IP Relaxation — Three Distinct Security Postures The **oauthPolicy.ipRelaxation** field on a Connected App has exactly three values. Each carries a meaningfully different security posture: | Value | Label in UI | Effect | |---|---|---| | `enforceIpRanges` | Enforce IP Restrictions | Token requests are rejected if the caller IP is outside the org's trusted IP ranges or the user's profile ranges. Strictest posture. | | `relaxIpRangesWithSecondFactor` | Relax IP Restrictions, Enforce 2FA | Callers outside trusted IPs are challenged with a second factor rather than blocked outright. Balances security and usability. | | `relaxIpRanges` | Relax IP Restrictions | IP restrictions are not checked at all. Appropriate only for server-to-server flows where the integration user has no IP range constraint and no human login is involved. | Choosing `relaxIpRanges` for a Connected App used by human users eliminates a meaningful layer of defense; audit regularly to ensure this is intentional. ### PKCE and the Require Secret Constraint PKCE (Proof Key for Code Exchange) prevents authorization code interception attacks in public clients. To enable PKCE on the Web Server flow in Salesforce: 1. Edit the Connected App → OAuth Settings → enable **Require Proof Key for Code Exchange (PKCE) Extension for Supported Authorization Flows**. 2. **You must simultaneously disable** "Require Secret for Web Server Flow" (`oauthPolicy.requireSecretForWebServerFlow = false`). These two settings are mutually exclusive: PKCE replaces the client_secret challenge; keeping Require Secret enabled will cause token exchange to fail even with a valid code_verifier. PKCE is recommended for all public clients (mobile, SPA) regardless of whether a client secret is technically available. ### JWT Bearer Flow — 60-Second Clock Drift Window The JWT Bearer flow authenticates without user interaction using a signed JWT. The assertion's `iat` and `exp` claims must satisfy `exp - iat <= 3 minutes` and the JWT must reach Salesforce within 60 seconds of `iat`. Any clock skew on the signing server beyond 60 seconds produces an `invalid_grant` error with no other indication of the cause. Resolution: synchronize server clocks with NTP, keep JWT TTL short (≤ 3 minutes), and log the `iat` timestamp on every issued assertion for debugging. ### High-Assurance Sessions — Three States Salesforce session security levels apply to Connected Apps through the **High Assurance Session Required** policy. The policy has three states: - **High Assurance** — the access token is only valid if the user authenticated at a High Assurance level (e.g. MFA). Low-assurance tokens trigger re-authentication. - **Switch to High Assurance** — Salesforce prompts the user to step up their session to High Assurance at next login. Enforcement is deferred until step-up completes. - **Blocked** — users whose session security level cannot satisfy High Assurance are denied access to the Connected App entirely. Use **Blocked** for Connected Apps that access sensitive data and have no legitimate low-assurance use case. Use **Switch to High Assurance** during migration periods where legacy integrations need time to update. ### Client Secret Rotation — No Grace Period in ECA Model In the External Client Apps (ECA) credential model (default from API v65 / Spring '25), rotating a consumer secret using the ECA API promotes the new secret **immediately**. There is no overlap window where both old and new secrets are valid. This is a breaking change from the legacy Connected App behavior where some tools provided rotation helpers with brief coexistence windows. Plan rotations as a coordinated deployment: update all consumers before or immediately after rotation; use short-lived tokens where possible to minimize the impact window. --- ## Common Patterns ### Pattern: Hardening a Server-to-Server Integration **When to use:** A Named Credential or external system uses the JWT Bearer or Client Credentials flow to call Salesforce APIs without user context. **How it works:** 1. Set IP Relaxation to `enforceIpRanges` and add the integration server's egress IPs to the Connected App's IP ranges (or to the integration user's profile ranges). 2. Enable "Require Secret for Web Server Flow" only if the Web Server flow is also in use; for pure JWT Bearer leave it unchecked. 3. Set High Assurance to **Blocked** since no human session is involved — this prevents credential stuffing via a stolen token. 4. Restrict OAuth scopes to the minimum required (e.g. `api` instead of `full`). 5. Schedule client secret rotation; document the zero-grace-period constraint in the runbook. **Why not relax IP restrictions:** A compromised token combined with relaxed IP restrictions grants an attacker full API access from any network. The IP check is a cheap, effective second barrier. ### Pattern: PKCE for a Single-Page App or Mobile Client **When to use:** A React/LWC OSS SPA or a mobile app uses the Web Server (Authorization Code) flow. The client cannot securely store a client secret. **How it works:** 1. Generate a cryptographically random `code_verifier` (43–128 characters, URL-safe base64 per RFC 7636). 2. Compute `code_challenge = BASE64URL(SHA256(code_verifier))`. 3. Include `code_challenge` and `code_challenge_method=S256` in the authorization URL. 4. In the Connected App, enable PKCE and disable "Require Secret for Web Server Flow". 5. Submit `code_verifier` in the token request body in place of `client_secret`. **Why not skip PKCE:** Authorization codes intercepted via redirect URI hijacking or browser history can be exchanged for tokens. PKCE binds the code to the original requester, eliminating this attack vector. --- ## Decision Guidance | Situation | Recommended Approach | Reason | |---|---|---| | Server-to-server with known IP egress | `enforceIpRanges` | Eliminates network-level abuse of leaked tokens | | Human SSO where IP ranges are unpredictable | `relaxIpRangesWithSecondFactor` | Preserves 2FA as the security gate without blocking roaming users | | Public client (SPA, mobile) | PKCE + disable Require Secret | No safe place to store a client secret; PKCE is the correct substitute | | Sensitive data API, MFA-mandatory org | High Assurance = Blocked | Ensures only MFA-verified sessions can access the Connected App | | Credential rotation in ECA model | Coordinated same-deployment swap | No grace period exists; old secret is immediately invalid after rotation | | JWT Bearer `invalid_grant` with no obvious cause | Check clock drift on signing server | 60-second window; NTP sync resolves most cases | --- ## Recommended Workflow 1. **Identify the Connected App and its flow type.** Pull the ConnectedApp metadata XML or review Setup > App Manager > Edit to confirm the OAuth flow, current IP relaxation value, session policy state, and whether PKCE or Require Secret is enabled. 2. **Assess IP relaxation posture.** Map the integration's source IPs. Choose `enforceIpRanges` for server-to-server, `relaxIpRangesWithSecondFactor` for human-facing flows, and document any deliberate use of `relaxIpRanges`. 3. **Configure session security.** Set High Assurance Required to **Blocked** for API-only Connected Apps. Set **Switch to High Assurance** as a migration state for human-facing apps moving toward MFA enforcement. 4. **Apply PKCE where applicable.** For public clients, enable PKCE and confirm "Require Secret for Web Server Flow" is disabled. For confidential server clients, enable Require Secret and disable PKCE. 5. **Plan client secret rotation.** Confirm whether the org is on the ECA model (API v65+). If yes, treat rotation as an atomic operation: update all consumers in the same deployment window. Document the no-grace-period behavior in the runbook. 6. **Validate JWT Bearer clock sync.** If the flow uses JWT Bearer, verify NTP sync on the signing host and ensure JWT TTL is set to ≤ 3 minutes. 7. **Run validate_repo and confirm metadata is committed.** After any Connected App metadata change, deploy via change set or SFDX and confirm the retrieved metadata matches intent. --- ## Review Checklist Run through these before marking work in this area complete: - [ ] IP Relaxation value is documented and justified for the flow type - [ ] PKCE enabled and Require Secret disabled (if public client), or vice versa for confidential client - [ ] High Assurance session policy set to Blocked for API-only apps, or documented exception recorded - [ ] Client secret rotation procedure documented with zero-grace-period warning - [ ] JWT Bearer signing host NTP sync verified if flow is in use - [ ] OAuth scopes restricted to minimum required --- ## Salesforce-Specific Gotchas Non-obvious platform behaviors that cause real production problems: 1. **PKCE and Require Secret are mutually exclusive** — Enabling both causes token exchange failures with a cryptic `invalid_client_credentials` error. Salesforce does not warn you at save time; the error only appears at runtime. 2. **ECA rotation has zero grace period** — In the ECA model (v65+), rotating the consumer secret via the API promotes the new value instantly. Any active integrations using the old secret break immediately, with no overlap window. Legacy tooling that assumed a rotation buffer will cause outages. 3. **High Assurance "Switch to High Assurance" does not enforce immediately** — The "Switch" state prompts but does not block. If the intent is enforcement, it must be changed to **Blocked** after the migration window. Orgs have left integrations in "Switch" indefinitely, thinking they are enforcing MFA. 4. **JWT Bearer 60-second clock drift silently produces invalid_grant** — The error message `invalid_grant` is shared with many other JWT validation failures. Clock drift is the most common and least obvious cause. Log the JWT `iat` claim on every request to isolate this. 5. **IP Relaxation applies to the Connected App, not the user** — Setting `relaxIpRanges` on a Connected App overrides the user's profile IP range restrictions for that app's token requests. Practitioners often assume profile IP ranges are always enforced regardless of Connected App settings. --- ## Output Artifacts | Artifact | Description | |---|---| | OAuth policy configuration | IP relaxation value, session security level, PKCE/Require Secret state, and scope list for the Connected App | | Rotation runbook | Step-by-step credential rotation procedure noting zero-grace-period constraint and consumer update sequence | | JWT Bearer validation checklist | Clock sync status, JWT TTL, claim log format | --- ## Related Skills - `security/oauth-flows-and-connected-apps` — Use when the question is about OAuth flow types, token exchange mechanics, or initial Connected App creation rather than hardening existing policies. - `security/api-security-and-rate-limiting` — Use alongside this skill when scope minimization and rate limit enforcement on API consumers is also required. - `architect/security-architecture-review` — Use when a full org-level security review is needed beyond individual Connected App policies.
Related Skills
visualforce-security-and-modernization
Use when hardening or modernizing legacy Visualforce pages — covers the platform CSRF token model and when disabling it is a security regression, view state encryption guarantees and the 170 KB ceiling, FLS/CRUD enforcement gaps on `<apex:outputField>` and on getters that return sObjects, `<apex:includeScript>` interaction with the org Content Security Policy, hosting LWC inside a VF page via `lightning:container` / `lightning-out`, and the retire-vs-harden-vs-leave-alone decision for an inventory of legacy pages. Triggers: 'should I rewrite this Visualforce page in LWC', 'CSRF protection disabled on Visualforce page is that safe', 'community user sees a field they should not on a Visualforce page', 'view state encryption is that enough for sensitive data', 'how do I host an LWC inside a Visualforce page', 'apex:dynamicComponent and apex:actionFunction safe to keep'. NOT for greenfield Visualforce architecture (use apex/visualforce-fundamentals — controller types, view state pattern selection, PDF rendering); NOT for Visualforce email template authoring (use apex/visualforce-email-templates if/when that skill is authored); NOT for general Apex security review across triggers and async (use apex/soql-security and security/secure-coding-review-checklist).
transaction-security-policies
Transaction Security policy creation and configuration: condition builder, enhanced policies, enforcement actions (block, MFA, notification, end session), real-time monitoring mode, and policy troubleshooting. NOT for Event Monitoring log analysis or Shield Event Monitoring setup (use event-monitoring). NOT for Apex testing or debug-log analysis.
session-high-assurance-policies
Enforce step-up authentication for sensitive pages/objects using High Assurance session level and login flow policies. NOT for initial MFA enrollment UX.
security-incident-response
When to use: active or suspected Salesforce org compromise, unauthorized access investigation, attacker containment, forensic evidence collection from EventLogFile/LoginHistory, session revocation, OAuth token cleanup, eradication of attacker persistence, and post-incident recovery verification. Trigger keywords: org compromised, suspicious login, attacker access, session revocation, forensic investigation, breach response, event log forensics, login anomaly investigation, incident response runbook. Does NOT cover general security setup, permission set design, field-level security configuration, or proactive security hardening — those are separate skills. NOT for general security setup.
security-health-check
Use when running, interpreting, or acting on Salesforce Security Health Check results — reading the score, understanding risk categories, evaluating specific settings, creating or importing a custom baseline, querying the Tooling API programmatically, or planning remediation from findings. Triggers: 'security health check score', 'health check failing settings', 'custom baseline', 'remediate health check findings', 'fix risk'. NOT for org hardening implementation, permission model design, or broad baseline config beyond what Health Check directly measures.
network-security-and-trusted-ips
Configure and audit Salesforce network security controls — trusted IP ranges (org-wide Network Access), login IP ranges on profiles, CSP Trusted Sites for Lightning components, CORS allowlists for external JavaScript, and TLS requirements — and troubleshoot login-blocked-by-IP or CSP violation errors. NOT for org-wide session settings, MFA configuration, or real-time Transaction Security Policies.
guest-user-security
Use when hardening the Experience Cloud guest user profile, controlling unauthenticated access to records and Apex, or investigating data exposure through guest SOQL. Covers object permissions, sharing model enforcement for unauthenticated users, and Apex execution context. NOT for Experience Cloud site creation (use Experience Cloud skills) or for authenticated external user security (use security/experience-cloud-security).
guest-user-security-audit
Auditing the security posture of an Experience Cloud (Community) site's Guest User. Covers the post-Spring '21 secure-by-default lockdown (object permissions removed, sharing rule grants required for any access), the Guest User profile permissions to remove (View All Data, Modify All Data, Manage Users, etc.), guest sharing rules, the Run-As-Guest test, OWASP A01 (Broken Access Control) mapping, and the standard set of leakage vectors (Apex with `without sharing`, Aura / LWC `@AuraEnabled` methods, public-site Visualforce, REST endpoints under `/services/apexrest`). NOT for Experience Cloud authenticated user setup (see experience/experience-cloud-user-management), NOT for general Salesforce profile design (see admin/profile-permset-design).
experience-cloud-security
Use when configuring access controls, sharing, or site security for authenticated or guest Experience Cloud (community) users: external OWD, Sharing Sets, Share Groups, CSP, clickjack protection, guest user record access. NOT for internal sharing model configuration (use sharing-and-visibility).
api-security-and-rate-limiting
Use when configuring, auditing, or troubleshooting API rate limits, Connected App OAuth scope restriction, Connected App IP restrictions, API session policies, or API usage monitoring in a Salesforce org. Trigger keywords: 'API rate limit', '429 error', 'OAuth scope restriction', 'Connected App IP restriction', 'API usage monitoring', 'concurrent API limits', 'Bulk API limits'. NOT for OAuth flow implementation, token exchange mechanics, or general Connected App setup — use security/oauth-flows-and-connected-apps for those.
omnistudio-security
Use when designing or reviewing OmniStudio security across OmniScripts, Integration Procedures, DataRaptors, custom LWCs, Apex actions, guest-user exposure, and outbound HTTP actions. Triggers: 'OmniStudio security', 'guest user omniscript', 'DataRaptor CRUD FLS', 'OmniStudio Apex security', 'HTTP action data exposure'. NOT for general portal identity architecture or generic Apex security reviews when OmniStudio is not the main surface.
lwc-security
Use when designing or reviewing Lightning Web Components for DOM safety, Lightning Web Security boundaries, third-party library handling, and secure server-side data access from LWC. Triggers: 'innerHTML in lwc', 'Lightning Web Security', 'document.querySelector', 'light DOM security', 'secure apex class for lwc'. NOT for org-wide sharing architecture or Apex-only security reviews when no LWC surface is involved.