Future Architecture of CLI Credentials - Usage Patterns and the Path to Zero-Exposure #3561
Replies: 12 comments 3 replies
-
|
Artifact used: (Access Token / Password / SFDX Auth URL): Sfdx Auth Url The impact is not huge, we just found the process to setup a secret with SFDX Auth URL easier |
Beta Was this translation helpful? Give feedback.
-
|
Personal Opinion: For sfdx-url, I think having a 30-45 day refresh token validity is fine. Sandboxes should be refreshed with the same frequency anyways so it's not really an issue. Productions also ok, just need a rotation strategy for it. Traditionally, system to system integrations require service accounts which are usually tied with jwt, mtls cets, oauth. If we want a persistent, long lived system connection then we'll just secure then with the same mechanisms. |
Beta Was this translation helpful? Give feedback.
-
|
Coming at this from a developer/admin angle rather than CI/CD. We use a mix, mostly SFDX Auth URL, through VS Code and the local CLI. My concern with deprecating the retrieval commands is recovery. When an org has a connected app issue or MFA problem and a fresh login won't work, being able to pull a stored auth has been our way back in. JWT doesn't really help there since it depends on the connected app being healthy in the first place. On the 30/45 day expiration, would this apply to sandboxes too or just production? We run DevOps with multi-box pipelines, so between orgs and machines we can easily be over 100 to manage and more as we grow. If it's prod-only that's workable, but across all sandboxes too the reauth churn would add up fast. Some visibility into upcoming expirations across everything locally-authed would help a lot either way. |
Beta Was this translation helpful? Give feedback.
-
|
It might be beneficial to document alternative means of authenticating to dev hubs and scratch orgs in greater detail. Yes the SF url format is easy, and quick, but the JWT shared auth is almost as quick and easy, basically un-documented and exposes nothing. |
Beta Was this translation helpful? Give feedback.
-
|
What will the |
Beta Was this translation helpful? Give feedback.
-
|
@mitchspano btw, forgot to mention - thanks for this work. |
Beta Was this translation helpful? Give feedback.
-
|
Artifact used: SFDX Auth URL If there were a command to login to a scratch org given a logged in DevHub, this would be a non-issue. Although, we do also heavily use In our GitLab pipeline, we have several jobs (each running in separate containers) which need to login to the same scratch org. |
Beta Was this translation helpful? Give feedback.
-
|
I'm glad that you're planning on tightening security, but these recommendations appear to look at the CLI as purely a CI/CD tool, neglecting the requirements from developers and consultants who use it daily. Before I start, let me frame exactly what the issue with the CLI is: Salesforce understands this risk. It's why last year you announced the restrictions concerning Connected Apps and how you would shut down vendors who you felt were breached. The issue is the same here. We have to assume that any computer can and will be breached given enough effort. Whether it's a CI/CD server or app, or a person's home computer. Security is just as much about damage mitigation and "preparing for the worst" as it is "hoping for the best" and assuming nobody will ever gain access to a real user's physical machine. Before we articulate a solution we need to consider the primary use cases of the CLI. Yes, CI/CD is an important one, one that has certain requirements:
But the developer/consultant requirements are vastly different:
From a security standpoint, these two scenarios could not be further apart. Why Enforced Refresh Token Expiration Won't Work: My Approach:
The Result: Additionally: Lastly: |
Beta Was this translation helpful? Give feedback.
-
SummaryArtifact used: Access Token More DetailsMy use case is simple, but business critical. It requires accessing an (scratch org's) access token to run integration API tests during package build pipelines. Lots of our modules implement custom Apex REST endpoints, and these cannot be tested otherwise. As these tests do not have setup/teardown (like apex tests), we can only run them reliably during scratch org validation. The code to retrieve the access token looks something like this const targetOrgAuthInfo = () => {
let targetOrg;
process.argv.forEach((processArg) => {
if (processArg.startsWith("target-org=")) {
targetOrg = processArg.split("=")[1];
}
});
return shell.exec(
targetOrg
? `sf org display --target-org ${targetOrg} --json`
: "sf org display --json",
{
silent: true,
fatal: true
}
).stdout;
};And the actual test case (executed with const result = await axios({
method: "POST",
url: `${authInfo.instanceUrl}/services/apexrest/v1/event/${testData.eventUri}`,
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${authInfo.accessToken}`
},
data: testData.request.body,
validateStatus: () => true
});This works perfectly, especially for data-driven tests that execute 100s of test cases, based on test-case files in a specific directory. |
Beta Was this translation helpful? Give feedback.
-
|
We use a mixture of passwords & SFDX Auth URL Job to be completed with the artifact:
Downstream tool/system that is using the artifact:
The processes need to be siloed as they are, due to having various clients which run through the same CICD tooling.
Additionally, those Auth URLs also allow our devs to connect to scratch orgs created this way by the centralized DevHub account to perform actual work on, push & pull changes from, etc. on our local IDEs and machines.
Why isn't standard CLI authentication enough? Impact of explicit command deprecation: The alternative for our CICD to hold on to the SF CLI's cache for log-in information, aliases, etc. would obviously open up a myriad of new potential security nightmares. For passwords generated it would be less of an issue at this moment since the command to generate a password also immedaitely outputs the generated password, which can be safely stored from there. But then, if the goal is zero-exposure of credentials, a case could be made whether that command should even output the generated password to begin with. Impact of a 30/45-day refresh token window: Additional thoughts & concerns: I'd also like to second the thoughts of @akruvi here regarding this current change. The recent flurry of security-related changes that has been pushed across the broader line of Salesforce products with short time frames is a lot to keep up with, the timing of this change alongside only a 7-day implementation window (lest your entire integration with Salesforce breaks) on top of all those other security changes that are already keeping teams scrambling. Why the need to have a run-through time between announcement and enforcement of this breaking change of only a week for something that has existed as it has for years? |
Beta Was this translation helpful? Give feedback.
-
|
Can I ask why a breaking change was announced with a week of warning? Lots of your customers will discover tools and pipelines broke out of the blue some random day after next Wednesday (the next time they update the CLI). It appears this is going to happen between 2.135.7 and 2.136.8, which from the version number change looks like a minor (i.e. not breaking) release. And why is this being rolled out in a single release with no overlap? There will apparently be no CLI version where This doesn't feel like how feature deprecation is supposed to go. |
Beta Was this translation helpful? Give feedback.
-
|
Artifact used: SFDX Auth URL My 2 cents: HoweverA JWT authenticated CI user is not able to generate SFDX Auth URLs for scratch orgs. This is because the DevHub's auth flow is propagated into each scratch org it provisions. A JWT-authed DevHub yields JWT-authed scratch-org AuthInfo with no refresh token, thus making it impossible to generate SFDX Auth URLs for them. A permanent solution would be needed for this first. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Overview
We recently announced upcoming CLI credential security changes where we will introduce a set of new, dedicated retrieval commands (
sf org auth show-*) designed to serve as an explicit way to fetch credentials when strictly necessary.However, our long-term goal is to lock down the CLI as tightly as possible. We want to better understand exactly why and how your workflows rely on raw access tokens, passwords, and SFDX Auth URLs today. Our target state is to eliminate raw secret exposure entirely; unless there is an unresolvable architectural dependency that requires a raw secret to be exposed, any command that outputs a plain-text credential is a candidate for deprecation in a future release.
How are you using these credentials today?
We need your feedback to ensure we don't inadvertently break your team’s critical workflows, and to evaluate future security mitigations we are considering. Please reply to this discussion sharing your current implementation details which would be impacted by this. We would like to know:
sf org login sfdx-url, could that secondary process instead utilize JWT auth directly?Proposal: Refresh token forced expiration window
In addition to removing secrets from outputs, we are considering hardening the security of SFDX Auth URLs by enforcing a strict expiration window on the underlying refresh tokens.
Today, users can store and reuse these URLs indefinitely. We are considering introducing a forced refresh token expiration window of 30 days or 45 days.
What would break in your environment if an SFDX Auth URL expired automatically after 30 or 45 days?
Please provide your feedback
Please drop a comment below detailing your workflow. You're free to engage in whatever manner you like, but to make things easer, you may want to consider using this format for your comments:
We value the input of the Salesforce community as we navigate these changes in the CLI. Thank you for helping us make the Salesforce DX ecosystem secure by default.
Beta Was this translation helpful? Give feedback.
All reactions