Migrate to Passwordless Endpoint from Confidential Applications
Auth0 is deprecating the use of the /passwordless/start
endpoint from confidential applications when Auth0 cannot authenticate that the call is made on behalf of the application.
OAuth uses the term 'confidential' for applications that can store secrets. In Auth0, those are 'Regular Web Applications', which serve web pages from a backend app. Single Page Applications and Native Applications are considered 'public' applications, and are not affected by this change.
Auth0 can authenticate calls to /passwordless/start
when they include a client_secret
as a parameter, or when the calls are made from the custom login page in Universal Login and forward the state
parameter.
Features affected
If any of your applications currently call the /passwordless/start
endpoint directly to begin passwordless authentication from a Web Application, and you are not sending the client_secret
as a parameter, this deprecation does affect you.
If you are implementing passwordless authentication through the Universal Login page and you changed the default way Auth0 libraries are initialized, it might also affect you too.
You can verify whether you are affected by checking the tenant logs, filtering by "Deprecation Notice" and check for logs saying "Enforce client authentication for passwordless connections". You can also perform this search directly with the following query: type:depnote AND description:*passwordless*
. Note that this specific query will only work for public cloud tenants, as private cloud logs cannot be searched on the description field.
Actions
If you are calling the /passwordless/start
endpoint without proper application authentication you should:
Follow the instructions described below to adjust the code to properly call
/passwordless/start
.Check your tenant logs to verify the change was made correctly and no deprecation logs are being generated for "Enforce client authentication for passwordless connections".
In the Migrations section of Advanced Tenant Settings, turn on the Enforce client authentication for passwordless connections toggle.
There are a few use cases that might be affected, but for each, the migration path is fairly straightforward:
API calls from backend
For any calls from your backend to the /passwordless/start
endpoint, your call must include the client secret as a parameter.
If making a POST request directly to /passwordless/start
, include the client_secret
as part of the payload:
POST https://{yourDomain}/passwordless/start
Content-Type: application/json
{
"client_id": "{yourClientId}",
"client_secret": "{yourClientSecret}",
"connection": "email|sms",
"email": "{userEmailAddress}", //set for connection=email
"phone_number": "{userPhoneNumber}", //set for connection=sms
"send": "link|code",
"authParams": {
"scope": "openid",
"state": "{yourState}"
}
}
Was this helpful?
If you are using an SDK, add the parameter to the method that initiates the passwordless flow. This is different for each SDK, and not all SDKs have been updated yet. If you are using an SDK that was not updated, you can make the HTTP call directly until that work is completed.
Auth0.js or Lock.js in the Universal Login page
If the Universal Login page is used for Passwordless Authentication for a Web Application, it will be making calls to the /passwordless/start
endpoint, by either using Lock.js or Auth0.js.
Given you can't store a client secret in a web page, the way to authenticate the call is by forwarding the state
parameter that is received in the Universal Login page to the /passwordless/start
endpoint. That parameter is stored in the config.internalOptions
field in the custom login page.
The default templates for customizing the login page use it in the following way when initializing Lock.js or auth0.js:
var lock = new Auth0Lock(
config.clientID,
config.auth0Domain,
{
auth: {
// .. other fields set
params: {
scope: config.internalOptions.scope,
_csrf: config.internalOptions._csrf,
state: config.internalOptions.state,
}
}
});
Was this helpful?
var params = Object.assign({
scope: config.internalOptions.scope,
_csrf: config.internalOptions._csrf,
state: config.internalOptions.state,
}, {
// ...auth params
});
var webAuth = new auth0.WebAuth(params);
Was this helpful?
Please check in your custom page implementation to verify that you have not removed that code.
Call /passwordless/start from the client in a web application
If you are calling the /passwordless/start
endpoint from a page using JavaScript (for example, using Auth0.js on the page) from regular web apps, you will not be able to specify a client secret in a call made using JavaScript. If this is the case for your application, you will need to change your apps so that /passwordless/start
is called from the backend of your web application, rather than from the frontend.
Rate Limits
A consequence of adding client authentication to /passwordless/start
is that Auth0 can trust the headers sent with the request. If you set the auth0-forwarded-for
header, the IP address will show in the logs and be used for attack protection purposes.
Authenticated /passwordless/start
requests will be treated as regular Authenticated API requests and the corresponding global Authentication API rate limit will apply.