Skip to main content
dd-trace provides a tracer.setUser() method that links an authenticated user to the current trace. This lets you filter and search traces by user in the Datadog APM UI and enables user-based blocking with AppSec.

Basic usage

Call tracer.setUser() with a user object after a user is authenticated. The id field is the only required property.
const tracer = require('dd-trace').init()

function handleRequest(req, res) {
  tracer.setUser({
    id: '123456789' // Required: unique identifier of the user
  })

  // ... handle request
}

Full user object

The user object accepts the following standard fields in addition to id:
const tracer = require('dd-trace').init()

function handleRequest(req, res) {
  tracer.setUser({
    id: '123456789',              // *Required* Unique identifier of the user
    email: '[email protected]', // Email of the user
    name: 'Jane Doe',             // User-friendly name of the user
    session_id: '987654321',      // Session ID of the user
    role: 'admin',                // Role the user is making the request under
    scope: 'read:message, write:files' // Scopes or granted authorizations
  })
}

User field reference

FieldTypeRequiredDescription
idstringYesUnique identifier of the user.
emailstringNoEmail address of the user.
namestringNoHuman-readable name of the user.
session_idstringNoSession ID associated with the user.
rolestringNoRole the user is acting under for this request.
scopestringNoOAuth2 scopes or SAML granted authorizations.

Custom fields

Arbitrary string fields can be added to the user object to attach custom metadata:
tracer.setUser({
  id: '123456789',
  email: '[email protected]',
  name: 'Jane Doe',

  // Arbitrary custom fields
  custom_tag: 'custom data',
  tenant_id: 'acme-corp',
  subscription_plan: 'enterprise'
})
All custom field values must be strings.

Integration with AppSec

When AppSec is enabled, calling tracer.setUser() makes the user identity available to the AppSec engine. This enables:
  • User blocking: AppSec can block requests from specific user IDs based on configured rules or remote configuration.
  • User tracking: Suspicious activity is attributed to specific users in the Security Signals view.
Enable AppSec alongside user identification:
const tracer = require('dd-trace').init({
  appsec: {
    enabled: true
  }
})

app.post('/login', async (req, res) => {
  const user = await authenticate(req.body)

  if (user) {
    tracer.setUser({
      id: user.id,
      email: user.email,
      name: user.name,
      role: user.role
    })
  }

  res.json({ success: !!user })
})

Express middleware example

A common pattern is to call tracer.setUser() in an authentication middleware so every subsequent span in the request lifecycle is tagged with the user:
const tracer = require('dd-trace').init()
const express = require('express')
const app = express()

// Authentication middleware
async function authenticate(req, res, next) {
  const token = req.headers.authorization?.split(' ')[1]
  if (!token) return res.status(401).json({ error: 'Unauthorized' })

  const user = await verifyToken(token)
  if (!user) return res.status(401).json({ error: 'Invalid token' })

  // Link user to the current trace
  tracer.setUser({
    id: user.id,
    email: user.email,
    name: user.displayName,
    session_id: user.sessionId,
    role: user.role
  })

  req.user = user
  next()
}

app.get('/api/profile', authenticate, (req, res) => {
  res.json({ user: req.user })
})

app.listen(3000)
tracer.setUser() must be called within an active span context (i.e., during a request being traced). Calling it outside of any span context has no effect.

TypeScript usage

The User interface is exported from dd-trace types:
import tracer from 'dd-trace'

tracer.init()

function setCurrentUser(user: { id: string; email: string; role: string }) {
  tracer.setUser({
    id: user.id,
    email: user.email,
    role: user.role
  })
}

Build docs developers (and LLMs) love