Skip to main content
Identity management allows you to track users across different sessions, devices, and platforms by associating multiple identifiers (aliases) with a single user profile.

Overview

A user on a device is automatically allocated a unique device ID by the Permutive SDK on behalf of the publisher. This user ID is distinct across publishers, such that the same user who visits two different publishers' sites on their device will be assigned distinct IDs. As a first-party identity, it does not track users across domains or devices, and it has no reliance on third-party identifiers like cookies or mobile device IDs. The user ID is used in Permutive's cloud to generate accurate publisher-level audience insights, and on-device to store cohort information across sessions.It is also possible to assign users to other IDs, called identifiers, such as an email address the user has authenticated with on the publisher's site, or a third-party identity provided by a partner that the publisher has obtained user consent for. Identifiers can be used to unify the view of a user across multiple devices they use (such as segmenting a user based on their behavior on two different sites owned by the publisher which they are logged in to) or to connect auxiliary data about the user (such as augmenting the segmentation of users with a third-party audience that a partner provides information about). In the Android SDK, you can set aliases using the setIdentity() method or configure automatic identity providers like AAID at initialization.

Key Concepts

An identifier (formerly called an alias in some SDK and API references) is an alternative identity for a user. Each identifier has:
  • Tag - The type of identifier (e.g., "email_sha256", "internal_id", "aaid")
  • Identity - The actual identifier value
  • Priority - Ordering when multiple identifiers exist (lower number = higher priority)
  • Expiry - Optional expiration date/time
When you set an identifier:
  1. SDK sends the identifier to Permutive servers
  2. Server checks if this identifier is associated with an existing user
  3. If found, user profiles are merged
  4. SDK receives updated cohorts and state
  5. All future events are linked to the resolved identity
Priority determines which identifier is used for identity resolution:
  • Lower number = Higher priority (0 is the highest)
  • Identifiers are resolved in priority order
  • If the highest priority identifier resolves to a user, that identity is used
Priority 0 (Highest): Hashed email - Most reliable, persistent
Priority 1: Internal user ID - Reliable when user is logged in
Priority 2: Advertising ID - Less reliable, can be reset
Priority 3 (Lowest): Device ID - Least reliable

Setting Identity

For apps with only one type of user identifier:
// Set identity when user logs in
fun onUserLoggedIn(userId: String) {
    permutive.setIdentity(userId)
}
When using the single-parameter setIdentity(), the alias tag is automatically set to "default".

With Priority and Expiry

fun onUserLoggedIn(userId: String) {
    val expiryDate = Calendar.getInstance().apply {
        add(Calendar.YEAR, 1)  // Expire in 1 year
    }.time

    permutive.setIdentity(
        identity = userId,
        priority = 0,  // Highest priority
        expiry = expiryDate
    )
}

Security Best Practices

Always hash personally identifiable information like email addresses before sending to Permutive.
import java.security.MessageDigest

fun hashEmail(email: String): String {
    val normalized = email.trim().lowercase()
    val bytes = MessageDigest.getInstance("SHA-256").digest(normalized.toByteArray())
    return bytes.joinToString("") { "%02x".format(it) }
}

// Usage
val emailHash = hashEmail("[email protected]")
permutive.setIdentity(
    listOf(Alias.create("email_sha256", emailHash, priority = 0))
)

Standard Tag Names

Identifier TypeRecommended TagNotes
SHA-256 hashed emailemail_sha256Most common
Internal user IDinternal_id or user_idYour system’s ID
Advertising IDaaid (Android)Use AaidAliasProvider
Customer IDcustomer_idE-commerce systems
Subscriber IDsubscriber_idSubscription services

Automatic Identity Providers

AAID (Android Advertising ID)

Use the Google Ads add-on for automatic AAID identification:
1

Add Dependency

dependencies {
    implementation("com.permutive.android:core:1.10.0")
    implementation("com.permutive.android:google-ads:2.2.0")
}
2

Add Permission

In your AndroidManifest.xml:
<manifest>
    <uses-permission android:name="com.google.android.gms.permission.AD_ID"/>
</manifest>
From Android API 31+, the AD_ID permission is required to access the advertising ID.
3

Configure SDK

import com.permutive.android.aaid.AaidAliasProvider

val permutive = Permutive(
    context = this,
    workspaceId = YOUR_WORKSPACE_ID,
    apiKey = YOUR_API_KEY,
    aliasProviders = listOf(AaidAliasProvider(this))
)
The AAID will be automatically retrieved and set with the tag "aaid".

Common Patterns

class AuthActivity : AppCompatActivity() {

    private val permutive by lazy {
        (application as MyApplication).permutive
    }

    fun onLoginSuccess(userId: String, email: String) {
        val emailHash = hashEmail(email)

        val aliases = listOf(
            Alias.create("email_sha256", emailHash, priority = 0),
            Alias.create("internal_id", userId, priority = 1)
        )

        permutive.setIdentity(aliases)
        navigateToHome()
    }

    private fun hashEmail(email: String): String {
        val normalized = email.trim().lowercase()
        val bytes = MessageDigest.getInstance("SHA-256")
            .digest(normalized.toByteArray())
        return bytes.joinToString("") { "%02x".format(it) }
    }
}
fun onLogout() {
    // Clear all persistent data
    lifecycleScope.launch(Dispatchers.IO) {
        permutive.clearPersistentData()
            .onSuccess {
                withContext(Dispatchers.Main) {
                    navigateToLogin()
                }
            }
            .onFailure { error ->
                Log.e("Permutive", "Failed to clear data", error)
            }
    }
}
class UserManager(private val permutive: Permutive) {

    // User starts as guest (anonymous)
    fun onAppLaunch() {
        // SDK automatically creates anonymous ID
    }

    // User logs in or signs up
    fun onUserAuthenticated(userId: String, email: String) {
        val emailHash = hashEmail(email)

        // Permutive merges guest data with authenticated profile
        permutive.setIdentity(
            listOf(
                Alias.create("email_sha256", emailHash, priority = 0),
                Alias.create("internal_id", userId, priority = 1)
            )
        )
    }
}

Expiry

Aliases can expire automatically, useful for GDPR compliance, ad IDs, and session identifiers.
// Never expire (default)
Alias.create(tag = "email_sha256", identity = emailHash, expiry = Alias.NEVER_EXPIRE)

// Expire in 30 days
val expiry30Days = Calendar.getInstance().apply {
    add(Calendar.DAY_OF_YEAR, 30)
}.time
Alias.create(tag = "session_id", identity = sessionId, expiry = expiry30Days)

Troubleshooting

Problem: Setting identity doesn’t seem to merge user data.Solutions:
  • Check network connectivity
  • Verify alias has been used in other sessions/devices
  • Enable debug logging: permutive.setDeveloperMode(true)
  • Look for “Identified user with aliases” in logs
Problem: Same user appears as two different users.Solution: Use consistent alias tags and values. When user logs in on multiple devices, use the same alias (e.g., hashed email).
Problem: Worried about sending personally identifiable information.Solution:
  • Always hash emails and other PII with SHA-256
  • Normalize data before hashing (lowercase, trim whitespace)
  • Never send raw email addresses, phone numbers, or names

Best Practices

  • Hash PII (especially email addresses) before setting as identity
  • Use meaningful tag names that describe the identifier type
  • Set priorities based on reliability and persistence
  • Use expiry dates for temporary or less reliable identifiers
  • Set identity as early as possible in the user journey
  • Test identity resolution with debug logging enabled