User Identity Mapping#
DevLake resolves tool-specific identities (GitHub accounts, Jira accounts, GitLab users, etc.) to unified cross-tool users through a three-layer model: plugin-level tool accounts → domain accounts → domain users.
Core Identity Tables#
All three tables live under backend/core/models/domainlayer/crossdomain/:
| Table | Model | Key fields |
|---|---|---|
accounts | Account | Email, FullName, UserName, AvatarUrl, Organization — one row per tool identity, auto-populated by each plugin's converter task |
users | User (crossdomain/user.go) | Email, Name — one row per real person, populated manually via CSV |
user_accounts | UserAccount | AccountId → UserId join — the bridge that makes cross-tool attribution possible |
Domain ID Generation#
Every plugin converter calls DomainIdGenerator to produce a deterministic, globally-unique ID for each account. The format is {pluginName}:{EntityType}:{pk_fields...} — for example github:GithubAccount:1:1234 or jira:JiraAccount:1:629cdf . This ensures the same tool entity always resolves to the same domain ID regardless of when it is collected.
How Actor Fields Are Populated in Domain Records#
pull_requests#
The PullRequest domain table stores AuthorId, AuthorName, MergedById, and MergedByName — all set to generated domain Account.Id values, not raw user IDs.
The GitHub PR converter (pr_convertor.go) illustrates the pattern:
- An
accountIdGenis created frommodels.GithubAccount{}. AuthorIdis set viaaccountIdGen.Generate(connectionId, pr.AuthorId).MergedByIdfollows the same pattern .
cicd_deployments and cicd_deployment_commits#
Neither CICDDeployment nor CicdDeploymentCommit carries a dedicated deploying-user field. Deployment actor attribution is not directly stored in these domain tables.
Per-plugin behavior:
- GitHub (GraphQL deployments): The
GithubDeploymenttool-layer model has no creator/actor column. The GraphQL query does not request thecreatorfield, so there is no triggering-user data in the pipeline . The only person-related field available is the commit author from the deployed commit. - GitHub Actions (workflow runs): The
GithubRunmodel stores the triggering actor login from the API but thecicd_run_convertor.godoes not map it to anyAuthorId/ActorIdin the outputCICDPipelineorCiCDPipelineCommitrecords. - GitLab deployments: The tool-layer
GitlabDeploymentmodel stores rich user data: both the deployable user (DeployableUserID,DeployableUserName,DeployableUserUsername, etc.) and a top-level triggering user (UserID,UserUsername). However, thedeployment_convertor.godoes not map these fields intoCicdDeploymentCommit, so they remain in the tool layer only. - Azure DevOps builds: The
ci_cd_build_converter.goemitsCICDPipelineandCiCDPipelineCommitwith no actor fields populated.
Account-to-User Resolution#
Resolving accounts → users (populating user_accounts) occurs in two stages :
- Heuristic auto-mapping — The
orgplugin'sconnectUserAccountsExactsubtask matches accounts to users by email and name similarity. - Manual override — Operators download
user_account_mapping.csvvia the org plugin API, correct or add rows, and re-upload. See Team Configuration for the full walkthrough.
To join tool identities back to real people in SQL :
SELECT a.id AS account_id, a.email, a.user_name AS account_user_name,
u.id AS user_id, u.name AS real_name
FROM accounts a
JOIN user_accounts ua ON a.id = ua.account_id
JOIN users u ON ua.user_id = u.id
Architecture Overview#
Key Source Files#
| What | Where |
|---|---|
Account model | crossdomain/account.go |
UserAccount join table | crossdomain/user_account.go |
PullRequest domain model | code/pull_request.go |
CICDDeployment domain model | devops/cicd_deployment.go |
CicdDeploymentCommit domain model | devops/cicd_deployment_commit.go |
| GitHub PR converter (reference pattern) | github/tasks/pr_convertor.go |
| GitLab deployment model (rich actor data) | gitlab/models/deployment.go |
| GitLab deployment converter | gitlab/tasks/deployment_convertor.go |
| GitHub deployment model (no actor) | github/models/deployment.go |
| GitHub run model (actor present, not forwarded) | github/models/run.go |
| Team Configuration guide | docs/Configuration/TeamConfiguration.md |