惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

小众软件
小众软件
Security Archives - TechRepublic
Security Archives - TechRepublic
Security Latest
Security Latest
K
Kaspersky official blog
P
Palo Alto Networks Blog
T
Threat Research - Cisco Blogs
D
Darknet – Hacking Tools, Hacker News & Cyber Security
T
Tor Project blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
A
Arctic Wolf
NISL@THU
NISL@THU
GbyAI
GbyAI
腾讯CDC
罗磊的独立博客
Simon Willison's Weblog
Simon Willison's Weblog
Scott Helme
Scott Helme
S
SegmentFault 最新的问题
Cyberwarzone
Cyberwarzone
Jina AI
Jina AI
S
Schneier on Security
WordPress大学
WordPress大学
云风的 BLOG
云风的 BLOG
博客园 - 【当耐特】
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Spread Privacy
Spread Privacy
C
CXSECURITY Database RSS Feed - CXSecurity.com
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
The Register - Security
The Register - Security
C
Cybersecurity and Infrastructure Security Agency CISA
L
Lohrmann on Cybersecurity
V
Vulnerabilities – Threatpost
G
GRAHAM CLULEY
P
Proofpoint News Feed
Cisco Talos Blog
Cisco Talos Blog
博客园_首页
雷峰网
雷峰网
量子位
酷 壳 – CoolShell
酷 壳 – CoolShell
V2EX - 技术
V2EX - 技术
O
OpenAI News
博客园 - 司徒正美
S
Security @ Cisco Blogs
Last Week in AI
Last Week in AI
M
MIT News - Artificial intelligence
博客园 - 叶小钗
Vercel News
Vercel News
AI
AI
博客园 - 聂微东
Webroot Blog
Webroot Blog
J
Java Code Geeks

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
External Client Apps in Salesforce Spring '26: A Practical Migration Guide
Dipojjal Cha · 2026-04-23 · via DEV Community

External Client Apps in Salesforce Spring '26: A Practical Migration Guide

Security and privacy dashboard representing secure API integrations

If you're an admin or developer who's been putting off learning about External Client Apps, Spring '26 just made that decision for you. As of the Spring '26 release, Salesforce disables the creation of new Connected Apps by default in every org. You can still flip a setting to create them short term, but the writing is on the wall. External Client Apps (ECAs) are the future, and the sooner you get comfortable with them, the less painful the migration will be down the road.

I've been working through ECA setups for a few clients over the past few months, and I want to share what I've learned. This isn't marketing fluff. It's the stuff I wish someone had told me before I started clicking around Setup trying to figure out why my OAuth flows kept failing.

Why Salesforce Built External Client Apps

Connected Apps have been around for over a decade. They work, but they carry a lot of baggage. If you've ever tried to package a Connected App and distribute it across multiple orgs, you know what I mean. The metadata model is inconsistent, the security controls are scattered, and the packaging story never really came together the way it should have.

ECAs are Salesforce's answer. They use second-generation managed packaging, which is the same modern framework that powers most new Salesforce development work. They're more secure out of the box because they follow a "closed by default" model. That means the app literally cannot do anything in your org until you install it and explicitly grant permission. No more orphaned Connected Apps sitting in Setup that some admin created three years ago and forgot about.

The other big shift is that ECAs make inbound and outbound governance a lot cleaner. You get clearer separation between who's publishing the app, who's installing it, and what the app is allowed to do in each org. For anyone managing integrations across multiple environments, this alone is worth the effort.

If you're still getting up to speed on the terminology around OAuth flows, token exchange, and scopes, I've found the glossary at salesforcedictionary.com useful for quick lookups during setup. It's saved me from going down Wikipedia rabbit holes more than once.

Developer working on Salesforce integration code at a laptop

What's Actually Changing in Spring '26

Let me be specific about what's happening, because the messaging from Salesforce has been a little scattered.

Starting with Spring '26, new Connected Apps can no longer be created by default. Existing Connected Apps keep working. They're not deprecated yet, and you don't have to migrate them tomorrow. But Salesforce has made it clear that ECAs are the long-term model, and new feature work is happening on the ECA side.

There's also a separate but related change: as of February 16, 2026, you can no longer send session IDs in outbound messages. You have to use OAuth instead. This affects anyone who was using the old session ID pattern for outbound integrations, and it's worth auditing your org for any remaining references.

One important limitation to know about before you start migrating: ECAs don't support the Username-Password OAuth flow. If you have integrations that depend on it, you're stuck on Connected Apps until you either change your auth flow or Salesforce adds support. Push notifications are also not supported on ECAs yet. So before you plan any migration, check what your existing Connected Apps actually do. You might find you can't migrate some of them at all right now, and that's okay.

How to Create an External Client App

The setup process is similar to Connected Apps but not identical. Here's the basic flow I use:

In Setup, type "External" in Quick Find and click on External Client App Manager. Then click New External Client App. You'll enter a display name and an API name (the API name is what you'll reference in code and metadata, so pick something you won't regret).

Enable OAuth and configure your callback URL. This is the URL that receives the authorization code after a user authenticates. If you're building a server-side integration, this might be an endpoint on your application. For a single-page app, it could be a redirect URI you've registered.

For OAuth scopes, you'll typically want some combination of: api (manage user data via APIs), web (manage user data via web browsers), refresh_token (maintain the session), and lightning (access Lightning apps). Don't just check every box. Grant only what the integration actually needs. This is one of the security wins of ECAs, and it's also just good practice.

Once you save, head to Policies and configure who's allowed to use the app. Setting Permitted Users to "Admin approved users are pre-authorized" is usually what you want for internal integrations, because it forces you to assign a permission set before any user can actually use the app. That way, you control exactly who can authenticate, and you have an audit trail.

Padlock symbolizing the closed-by-default security model of External Client Apps

The Migration Playbook I Use

If you have more than two or three Connected Apps in your org, don't just start migrating randomly. Get organized first.

Step one is inventory. Go to App Manager in Setup and list every Connected App you have. For each one, figure out: what integration is it for, who owns it, is it still in active use, what OAuth flow does it use, and does it rely on any ECA-unsupported features (like Username-Password or push notifications).

You'll probably find two or three apps that nobody knows about. That's normal. Check the login history for each Connected App to see if anyone has actually authenticated against it in the last 90 days. If not, you might be able to just retire it without migrating.

Step two is prioritize. Start with new integrations. Any new integration work should use ECAs from the start. Then migrate your highest-risk or highest-value apps. Highest-risk means apps with broad scopes or admin-level access. Highest-value means the integrations that drive revenue or support critical business processes.

Step three is the actual migration. For each Connected App, create an equivalent ECA with the same OAuth settings. Update your integration code or configuration to point at the new ECA's client ID and secret. Test thoroughly in a sandbox first. I cannot stress this enough. OAuth errors are miserable to debug in production, and every integration has its own quirks.

Once the ECA is working in production, you can remove or disable the old Connected App. Don't do this in the same deployment window as the ECA rollout. Give yourself a couple of weeks to confirm nothing's broken before you pull the trigger.

Common Pitfalls to Watch For

A few things I've run into that cost me time:

Callback URL mismatches are the top cause of OAuth errors. If your callback URL in the ECA doesn't exactly match what your client sends, authentication fails with a generic error that doesn't tell you why. Double-check the URL, including trailing slashes and HTTPS.

Permission sets matter more than they used to. Because ECAs use a closed-by-default model, forgetting to assign the permission set to the user will produce login errors that look like the auth flow is broken. It's not. It's just that the user isn't permitted to use the app.

Scoped tokens behave differently. If you've been relying on the behavior of the old Connected App token system, test carefully. The way refresh tokens and access tokens interact under the ECA model is slightly different in some edge cases.

If you hit a term you don't recognize during all of this, salesforcedictionary.com is a decent quick reference for OAuth and identity concepts in the Salesforce context. I keep it open in a tab when I'm doing heavy integration work.

Digital analytics dashboard showing integration metrics and team insights

What This Means for Your Team

For admins, the biggest shift is that you need to understand ECAs well enough to audit them and grant the right permissions. The "closed by default" model means you'll be involved in every integration decision, which is a good thing, but it does mean more tickets if your team isn't prepared.

For developers, ECAs are the new default. Learn the metadata format, get comfortable with deploying them via SFDX, and update your team's integration templates. The Trailhead modules on External Client Apps are a solid place to start if you want a hands-on walkthrough.

For architects, this is a chance to clean up years of accumulated integration debt. Use the migration as an excuse to document what integrations exist, retire the ones nobody's using, and standardize your patterns going forward. You may not get another opportunity like this for a while.

The Bottom Line

Spring '26 isn't forcing you to migrate all your Connected Apps overnight, but the direction is clear. ECAs are the future, and the earlier you start building muscle memory around them, the smoother the eventual full migration will be. I'd suggest picking one low-risk integration to migrate this month just to go through the process end to end. You'll learn more from one real migration than from reading 10 blog posts (including this one).

If you've already started your ECA migration, I'd love to hear what surprised you. Drop a comment below with what you ran into, what worked, and what you wish you'd known before starting. And if you're just getting started and have a specific question, ask away. I'll try to answer what I can.