Security Best Practices

Using Descope for your authentication is a great start to implementing customizable and secure authentication in your applications. However, there are some best practices that you should be aware of when building out your application, to ensure that it is as secure as possible.

This guide includes a list of some of the most common vulnerabilities, as well as how to customize your Descope project and application to protect against them.

Topics

  1. How to Personalize Email Template
  2. Usage of Access Keys
  3. Scope of Descope Management Keys
  4. Using RBAC to Implement Resource Permissions
  5. Using Approved Domains
  6. Managing Descope Components Not in Use
  7. Using Custom Apps with OAuth
  8. Using SSR Frameworks

How to Personalize Email Template

You should make sure that emails being sent out to your users for things like OTP and Magic Link are using your specific website domain. You can do this by establishing a Sendgrid or SMTP Connector under the Authentication Methods page. That way, you have full control over both the email contents and restrictions imposed on your specific domain.

To create a Sendgrid Connector, sign up for Sendgrid here.

How to Use the Risk Calculator

When designing your flow, it is worth considering the use of our built-in risk calculator, to determine whether or not a user should re-authenticate. The risk calculator is baked into flows, as an Action called Fingerprint / Assess.

Descope Fingerprint / Assess action settings

This will return a risk score that can be applied to custom logic using a Condition block, like this:

Descope Fingerprint / Assess conditional

Typically speaking, an MFA auth flow will be attached to this block if the risk score is sufficiently high, like this:

Descope risk based MFA flow

The threat risk will be calculated via a variety of parameters, such as the duration between the current time and the last login, as well as various other factors. It is important to include this in your flow, to maintain total security between user sessions.

Usage of Access Keys

Access Keys are primarily used for OIDC provider integrations as well as M2M (machine-to-machine) authentication.

If you are utilizing access keys, make sure that you use the expiry mechanism and rotate the keys regularly, to make sure that your server and data are secure. Access Keys can be created by any one of our SDKs, or through the Descope Console here.

Descope access key generation

Scope of Descope Management Keys

When handling User Management requests with our SDKs or APIs, you will need a Management Key. You can read more about our management keys on our docs page.

When using these secret management keys, it's important to use best practices with these secret keys, such as not embedding them in your frontend and rotating them frequently. However, you should also make sure that they are scoped to a specific set of projects, rather than all of your projects, to limit access to the User Management requests if the key is uncovered by a malicious entity. You can set the scope of the management key in the Console:

Descope management key generation

Using RBAC to Implement Resource Permissions

When controlling resource permissions on your website, you will want to usually implement some kind of Authorization protocol, typically Role-Based Access Control (RBAC). RBAC is a mechanism that authorizes users to access protected resources based on their role within an organization. In order to implement RBAC with Descope, you will need to follow the steps in the guide, on our docs page.

Make sure that you have defined the tenants, roles, and permissions for each role explicitly. Doing so, will ensure that your website is secure and access to protected resources is properly controlled.

Using Approved Domains

Descope recommends that you configure a list of approved domains for redirects and verification URLs under Project Settings. If your application has a security vulnerability, this will prevent a malicious hacker from generating redirect links to unsafe websites.

Descope approved domains configuration

Managing Descope Components Not in Use

When you are not actively using a Flow or an authentication method in Descope, you can disable it from the Console.

To disable a flow, navigate to the Flows page, and select disable:

Descope disable components not in use flows

To disable an authentication method, navigate to the Authentication Methods page, and unselect Enable method at the top of the settings menu for each method you would like to disable:

Descope disable components not in use auth methods

You can also do this with the SDKs.

Using Custom Apps with OAuth

It is recommended by Descope that you create a custom login application if you're using OAuth as an authentication method.

For example, if you're using Facebook Social Login, rather than using our app, create a custom app with Facebook to handle the OAuth login, to avoid any potential differences between your specific implementation and app policies set by the generic app managers (such as Facebook).

Using SSR Frameworks

If you're using frameworks that use server-side rendering (SSR), such as Next.js, Nuxt, etc, you will need to be aware of some differences in how the Descope SDKs are used. The following items are things to keep in mind, as there are security concerns with SSR, as well as SDK component limitations:

  1. In a next-app, you will need both React and Node SDKs.
  2. The Descope Flow / Web component should only be rendered on the client side. There are two main ways you can do this, as shown below:

Next.js support dynamic imports, which allow you to import JavaScript modules dynamically and works collaboratively with SSR as well. With next/dynamic, you can use the ssr: false object to disable server-side rendering of your dynamically imported component:

component.tsx
const DescopeWC = dynamic(
  async () => {
    const { Descope } = await import("@descope/react-sdk");
    const EnhancedDescope = (props: React.ComponentProps<typeof Descope>) => (
      <Descope {...props} />
 
    )
    EnhancedDescope.displayName = "EnhancedDescope"
    return EnhancedDescope;
  },
  {
    ssr: false,
  }
);

If you're using Next 13, you can also use "use client" directive instead of dynamic imports at the top of your file:

component.tsx
"use client";
 
export function ... {
	return (
		<Descope
		flowId="sign-up-or-in"
		onSuccess = {(e) => console.log(e.detail.user)}
		onError={(e) => console.log('Could not log in!')}
		theme="light"
		/>
	)
}
  1. Manage your session tokens in cookies, as passing your tokens to the Next backend isn't necessary. You can do this by wrapping AuthProvider like so:
page.tsx
	<AuthProvider
		projectId={process.env.NEXT_PUBLIC_DESCOPE_PROJECT_ID!}
		// Use this option when you need to use session token in the SSR render cycle
		sessionTokenViaCookie
	>
		<Component {...pageProps} />
	</AuthProvider>

If you're interested on how we've implemented Descope with Next.js, we have a sample app on our GitHub page.


If you have any other questions about Descope or our flows, feel free to reach out to us!

Was this helpful?

On this page