{"id":16800,"library":"dataverse-auth","title":"Dataverse On-Behalf-Of Authentication","description":"The `dataverse-auth` package provides on-behalf-of (OBO) authentication capabilities against Microsoft Dataverse environments, specifically designed for NodeJS applications. It facilitates the process of obtaining and securely storing access tokens locally, which can then be utilized by other applications, such as code generation tools (`dataverse-gen`) or API clients (`dataverse-ify`). The library primarily leverages OAuth 2.0 for its authentication flows, handling interactive logins. The current stable version on npm is 1.0.9. Despite this version being last published over five years ago, the author maintains related Dataverse ecosystem packages, suggesting a maintenance status for `1.x` while newer approaches or specific platform requirements (like for Apple Silicon, which mentions `dataverse-auth@2`) may exist outside of the npm `1.x` release line. Its key differentiator is simplifying the token management for Dataverse within Node.js applications, abstracting away some complexities of Microsoft Entra ID (formerly Azure AD) authentication flows.","status":"maintenance","version":"1.0.9","language":"javascript","source_language":"en","source_url":null,"tags":["javascript","typescript"],"install":[{"cmd":"npm install dataverse-auth","lang":"bash","label":"npm"},{"cmd":"yarn add dataverse-auth","lang":"bash","label":"yarn"},{"cmd":"pnpm add dataverse-auth","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core library for Microsoft Entra ID (Azure AD) authentication using OAuth 2.0 flows.","package":"@azure/msal-node","optional":false},{"reason":"Used for making HTTP requests to Microsoft Entra ID and Dataverse endpoints.","package":"axios","optional":false},{"reason":"Provides secure storage for credentials and tokens locally.","package":"keytar","optional":false},{"reason":"Used to open browser windows for interactive authentication flows.","package":"open","optional":false}],"imports":[{"note":"The primary authentication function is a default export, not a named one.","wrong":"import { auth } from 'dataverse-auth';","symbol":"auth","correct":"import auth from 'dataverse-auth';"},{"note":"Type imports should use 'import type' for clarity and tree-shaking benefits in TypeScript.","symbol":"AuthType","correct":"import type { AuthType } from 'dataverse-auth';"},{"note":"Type imports should use 'import type' for clarity and tree-shaking benefits in TypeScript.","symbol":"DeviceCode","correct":"import type { DeviceCode } from 'dataverse-auth';"}],"quickstart":{"code":"import auth from 'dataverse-auth';\nimport { TokenResponse } from '@azure/msal-node';\n\nconst DATAVERSE_URL = process.env.DATAVERSE_URL ?? 'https://yourorg.crm.dynamics.com';\nconst TENANT_ID = process.env.TENANT_ID;\nconst CLIENT_ID = process.env.CLIENT_ID;\nconst CLIENT_SECRET = process.env.CLIENT_SECRET; // Required for confidential client flows\n\nasync function authenticateAndGetToken(): Promise<TokenResponse | undefined> {\n  try {\n    console.log(`Attempting to authenticate against Dataverse: ${DATAVERSE_URL}`);\n\n    // This function can trigger an interactive browser login if needed,\n    // or use cached credentials if available.\n    // For automation, consider 'AuthType.ClientSecret' with CLIENT_ID/CLIENT_SECRET\n    // or 'AuthType.DeviceCode' with a callback for user interaction.\n    const tokenResponse = await auth(\n      DATAVERSE_URL,\n      TENANT_ID, // Optional: specify tenant ID\n      CLIENT_SECRET ? 'ClientSecret' : undefined, // Example: use ClientSecret if provided\n      CLIENT_ID,\n      CLIENT_SECRET,\n      // For 'DeviceCode' flow, you might provide a callback:\n      // undefined, undefined, (deviceCode) => {\n      //   console.log(`Open ${deviceCode.verificationUri} and enter code ${deviceCode.userCode}`);\n      // }\n    );\n\n    if (tokenResponse) {\n      console.log('Authentication successful!');\n      console.log('Access Token:', tokenResponse.accessToken.substring(0, 30) + '...');\n      console.log('Expires On:', new Date(tokenResponse.expiresOn! * 1000));\n      return tokenResponse;\n    } else {\n      console.log('Authentication flow completed, but no token response was returned.');\n      return undefined;\n    }\n  } catch (error) {\n    console.error('Authentication failed:', error);\n    throw error;\n  }\n}\n\nauthenticateAndGetToken()\n  .then(token => {\n    if (token) {\n      console.log('\\nReady to use the token for Dataverse API calls.');\n      // Example: Use the token with another Dataverse client library\n      // const dataverseClient = new DataverseClient(token.accessToken, DATAVERSE_URL);\n    }\n  })\n  .catch(err => {\n    console.error('An unhandled error occurred:', err);\n    process.exit(1);\n  });\n","lang":"typescript","description":"Demonstrates how to programmatically authenticate with Dataverse and retrieve an access token using the `dataverse-auth` library, handling various authentication types."},"warnings":[{"fix":"For Apple Silicon, check for official `dataverse-auth` v2 releases on npm or GitHub. Alternatively, consider running Node.js in Rosetta 2 compatibility mode, or explore alternative Dataverse authentication libraries that explicitly support Apple Silicon.","message":"The `dataverse-auth` package version 1.x does not officially support MacOS with Apple Silicon (M1/M2 chips). Users on these platforms may need to use `npx dataverse-auth@2` if a `v2` version of the CLI tool or an updated library is available, or encounter compatibility issues. The version 2 mention on GitHub appears to be for CLI usage and does not correspond to a `dataverse-auth@2` npm package.","severity":"breaking","affected_versions":"<2.0.0"},{"fix":"Ensure the application registration in Microsoft Entra ID is configured to support the required authentication flows (e.g., public client flows for interactive logins). For unattended scenarios, consider using Service Principals with client secrets or certificates, or Managed Identities, which are better suited for MFA-enabled environments. Consult Microsoft Entra ID and Dataverse documentation for best practices with MFA.","message":"Multi-factor Authentication (MFA) can cause authentication failures with an `InteractionRequiredAuthError: invalid_grant: AADSTS50076` if the Dataverse environment or Microsoft Entra ID (Azure AD) tenant has conditional access policies or security defaults enabled that require MFA. This is particularly problematic if device-code flow is disabled or not properly handled, as the library's interactive prompt may not satisfy all MFA requirements.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure that your Microsoft Entra ID application registration is correctly configured for OAuth 2.0, and that your `dataverse-auth` calls explicitly use modern authentication types (e.g., `ClientSecret`, `DeviceCode`). Avoid hardcoding usernames and passwords if using deprecated flows; switch to service principals or managed identities where possible.","message":"Microsoft has deprecated WS-Trust (Office365) authentication for Dataverse. While `dataverse-auth` uses OAuth 2.0, reliance on legacy authentication types or incorrect configuration can still lead to issues. Microsoft strongly recommends using modern OAuth 2.0 flows with MSAL.","severity":"deprecated","affected_versions":">=1.0.0"},{"fix":"Ensure that the runtime environment for applications using `dataverse-auth` has appropriate security measures, including file system permissions that restrict access to stored tokens and, where applicable, disk encryption. Do not expose machines with stored tokens to untrusted networks or users. Consider token revocation policies for enhanced security.","message":"The package stores tokens locally for reuse. While `keytar` is used for secure storage, improper handling of the environment where these tokens are stored (e.g., insecure file system permissions, lack of disk encryption) can expose sensitive access tokens.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"For multi-tenant applications, ensure that a service principal for your application is registered in each target Microsoft Entra ID tenant. Implement proper tenant consent flows or switch to explicit service principal authentication (client credentials flow) for automated, cross-tenant operations. Refer to Microsoft Entra ID documentation on multi-tenant applications and service principals.","message":"Starting October 2024, support for multi-tenant applications without a service principal in the Microsoft Entra ID tenant is being deprecated for Dataverse. This could impact on-behalf-of flows for applications operating across multiple tenants without explicit service principal registration in each target tenant.","severity":"deprecated","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Review Microsoft Entra ID Conditional Access policies and Security Defaults. If interactive login is intended, ensure the application registration supports interactive flows and users complete MFA prompts. For non-interactive scenarios (e.g., backend services), switch to service principal (client credentials flow) or managed identity authentication instead of user-based flows.","cause":"Your Microsoft Entra ID tenant or Dataverse environment requires Multi-factor Authentication (MFA), which the current authentication flow (or its configuration) is not satisfying.","error":"Authentication failed: InteractionRequiredAuthError: invalid_grant: AADSTS50076: Due to a configuration change made by your administrator, or because you moved to a new location, you must use multi-factor authentication to access '00000007-0000-0000-c000-000000000000'."},{"fix":"Verify that the user account or application user (for service principals) used for authentication has been assigned the appropriate security roles and privileges within the Dataverse environment. This often requires an administrator to grant specific read/write/create/delete permissions on relevant tables.","cause":"The authenticated user or service principal lacks the necessary security roles or privileges in Dataverse to perform the requested operation.","error":"Access Denied. Not enough privilege to access the Microsoft Dynamics CRM object or perform the requested operation."},{"fix":"If using a corporate proxy or self-signed certificates, configure Node.js to trust the necessary CA certificates by setting the `NODE_EXTRA_CA_CERTS` environment variable to the path of your CA certificate bundle. For example: `export NODE_EXTRA_CA_CERTS=/path/to/your/ca-certs.pem`.","cause":"Node.js cannot verify the SSL/TLS certificate of the Dataverse endpoint or an intermediate proxy, common in corporate environments with deep packet inspection or self-signed certificates.","error":"Error: unable to get local issuer certificate (for self-signed certs or corporate proxies)"}],"ecosystem":"npm","meta_description":null}