| = Gerrit Code Review - Accounts | 
 |  | 
 | == Overview | 
 |  | 
 | Starting from 2.15 Gerrit accounts are fully stored in | 
 | link:note-db.html[NoteDb]. | 
 |  | 
 | The account data consists of a sequence number (account ID), account | 
 | properties (full name, preferred email, registration date, status, | 
 | inactive flag), preferences (general, diff and edit preferences), | 
 | project watches, SSH keys, external IDs, starred changes and reviewed | 
 | flags. | 
 |  | 
 | Most account data is stored in a special link:#all-users[All-Users] | 
 | repository, which has one branch per user. Within the user branch there | 
 | are Git config files for the link:#account-properties[ | 
 | account properties], the link:#preferences[account preferences] and the | 
 | link:#project-watches[project watches]. In addition there is an | 
 | `authorized_keys` file for the link:#ssh-keys[SSH keys] that follows | 
 | the standard OpenSSH file format. | 
 |  | 
 | The account data in the user branch is versioned and the Git history of | 
 | this branch serves as an audit log. | 
 |  | 
 | The link:#external-ids[external IDs] are stored as Git Notes inside the | 
 | `All-Users` repository in the `refs/meta/external-ids` notes branch. | 
 | Storing all external IDs in a notes branch ensures that each external | 
 | ID is only used once. | 
 |  | 
 | The link:#starred-changes[starred changes] are represented as | 
 | independent refs in the `All-Users` repository. They are not stored in | 
 | the user branch, since this data doesn't need versioning. | 
 |  | 
 | The link:#reviewed-flags[reviewed flags] are not stored in Git, but are | 
 | persisted in a database table. This is because there is a high volume | 
 | of reviewed flags and storing them in Git would be inefficient. | 
 |  | 
 | Since accessing the account data in Git is not fast enough for account | 
 | queries, e.g. when suggesting reviewers, Gerrit has a | 
 | link:#account-index[secondary index for accounts]. | 
 |  | 
 | [[all-users]] | 
 | == `All-Users` repository | 
 |  | 
 | The `All-Users` repository is a special repository that only contains | 
 | user-specific information. It contains one branch per user. The user | 
 | branch is formatted as `refs/users/CD/ABCD`, where `CD/ABCD` is the | 
 | link:access-control.html#sharded-user-id[sharded account ID], e.g. the | 
 | user branch for account `1000856` is `refs/users/56/1000856`. The | 
 | account IDs in the user refs are sharded so that there is a good | 
 | distribution of the Git data in the storage system. | 
 |  | 
 | A user branch must exist for each account, as it represents the | 
 | account. The files in the user branch are all optional. This means | 
 | having a user branch with a tree that is completely empty is also a | 
 | valid account definition. | 
 |  | 
 | Updates to the user branch are done through the | 
 | link:rest-api-accounts.html[Gerrit REST API], but users can also | 
 | manually fetch their user branch and push changes back to Gerrit. On | 
 | push the user data is evaluated and invalid user data is rejected. | 
 |  | 
 | To hide the implementation detail of the sharded account ID in the ref | 
 | name Gerrit offers a magic `refs/users/self` ref that is automatically | 
 | resolved to the user branch of the calling user. The user can then use | 
 | this ref to fetch from and push to the own user branch. E.g. if user | 
 | `1000856` pushes to `refs/users/self`, the branch | 
 | `refs/users/56/1000856` is updated. In Gerrit `self` is an established | 
 | term to refer to the calling user (e.g. in change queries). This is why | 
 | the magic ref for the own user branch is called `refs/users/self`. | 
 |  | 
 | A user branch should only be readable and writeable by the user to whom | 
 | the account belongs. To assign permissions on the user branches the | 
 | normal branch permission system is used. In the permission system the | 
 | user branches are specified as `refs/users/${shardeduserid}`. The | 
 | `${shardeduserid}` variable is resolved to the sharded account ID. This | 
 | variable is used to assign default access rights on all user branches | 
 | that apply only to the owning user. The following permissions are set | 
 | by default when a Gerrit site is newly installed or upgraded to a | 
 | version which supports user branches: | 
 |  | 
 | .All-Users project.config | 
 | ---- | 
 | [access "refs/users/${shardeduserid}"] | 
 |   exclusiveGroupPermissions = read push submit | 
 |   read = group Registered Users | 
 |   push = group Registered Users | 
 |   label-Code-Review = -2..+2 group Registered Users | 
 |   submit = group Registered Users | 
 | ---- | 
 |  | 
 | The user branch contains several files with account data which are | 
 | described link:#account-data-in-user-branch[below]. | 
 |  | 
 | In addition to the user branches the `All-Users` repository also | 
 | contains a branch for the link:#external-ids[external IDs] and special | 
 | refs for the link:#starred-changes[starred changes]. | 
 |  | 
 | Also the next available value of the link:#account-sequence[account | 
 | sequence] is stored in the `All-Users` repository. | 
 |  | 
 | [[account-index]] | 
 | == Account Index | 
 |  | 
 | There are several situations in which Gerrit needs to query accounts, | 
 | e.g.: | 
 |  | 
 | * For sending email notifications to project watchers. | 
 | * For reviewer suggestions. | 
 |  | 
 | Accessing the account data in Git is not fast enough for account | 
 | queries, since it requires accessing all user branches and parsing | 
 | all files in each of them. To overcome this Gerrit has a secondary | 
 | index for accounts. The account index is either based on | 
 | link:config-gerrit.html#index.type[Lucene or Elasticsearch]. | 
 |  | 
 | Via the link:rest-api-accounts.html#query-account[Query Account] REST | 
 | endpoint link:user-search-accounts.html[generic account queries] are | 
 | supported. | 
 |  | 
 | Accounts are automatically reindexed on any update. The | 
 | link:rest-api-accounts.html#index-account[Index Account] REST endpoint | 
 | allows to reindex an account manually. In addition the | 
 | link:pgm-reindex.html[reindex] program can be used to reindex all | 
 | accounts offline. | 
 |  | 
 | [[account-data-in-user-branch]] | 
 | == Account Data in User Branch | 
 |  | 
 | A user branch contains several Git config files with the account data: | 
 |  | 
 | * `account.config`: | 
 | + | 
 | Stores the link:#account-properties[account properties]. | 
 |  | 
 | * `preferences.config`: | 
 | + | 
 | Stores the link:#preferences[user preferences] of the account. | 
 |  | 
 | * `watch.config`: | 
 | + | 
 | Stores the link:#project-watches[project watches] of the account. | 
 |  | 
 | In addition it contains an | 
 | link:https://en.wikibooks.org/wiki/OpenSSH/Client_Configuration_Files#.7E.2F.ssh.2Fauthorized_keys[ | 
 | authorized_keys] file with the link:#ssh-keys[SSH keys] of the account. | 
 |  | 
 | [[account-properties]] | 
 | === Account Properties | 
 |  | 
 | The account properties are stored in the user branch in the | 
 | `account.config` file: | 
 |  | 
 | ---- | 
 | [account] | 
 |   fullName = John Doe | 
 |   preferredEmail = john.doe@example.com | 
 |   status = OOO | 
 |   active = false | 
 | ---- | 
 |  | 
 | For active accounts the `active` parameter can be omitted. | 
 |  | 
 | The registration date is not contained in the `account.config` file but | 
 | is derived from the timestamp of the first commit on the user branch. | 
 |  | 
 | When users update their account properties by pushing to the user | 
 | branch, it is verified that the preferred email exists in the external | 
 | IDs. | 
 |  | 
 | Users are not allowed to flip the active value themselves; only | 
 | administrators and users with the | 
 | link:access-control.html#capability_modifyAccount[Modify Account] | 
 | global capability are allowed to change it. | 
 |  | 
 | Since all data in the `account.config` file is optional the | 
 | `account.config` file may be absent from some user branches. | 
 |  | 
 | [[preferences]] | 
 | === Preferences | 
 |  | 
 | The account properties are stored in the user branch in the | 
 | `preferences.config` file. There are separate sections for | 
 | link:intro-user.html#preferences[general], | 
 | link:user-review-ui.html#diff-preferences[diff] and edit preferences: | 
 |  | 
 | ---- | 
 | [general] | 
 |   showSiteHeader = false | 
 | [diff] | 
 |   hideTopMenu = true | 
 | [edit] | 
 |   lineLength = 80 | 
 | ---- | 
 |  | 
 | The parameter names match the names that are used in the preferences REST API: | 
 |  | 
 | * link:rest-api-accounts.html#preferences-info[General Preferences] | 
 | * link:rest-api-accounts.html#diff-preferences-info[Diff Preferences] | 
 | * link:rest-api-accounts.html#edit-preferences-info[Edit Preferences] | 
 |  | 
 | If the value for a preference is the same as the default value for this | 
 | preference, it can be omitted in the `preference.config` file. | 
 |  | 
 | Defaults for preferences that apply for all accounts can be configured | 
 | in the `refs/users/default` branch in the `All-Users` repository. | 
 |  | 
 | [[project-watches]] | 
 | === Project Watches | 
 |  | 
 | Users can configure watches on projects to receive email notifications | 
 | for changes of that project. | 
 |  | 
 | A watch configuration consists of the project name and an optional | 
 | filter query. If a filter query is specified, email notifications will | 
 | be sent only for changes of that project that match this query. | 
 |  | 
 | In addition, each watch configuration can contain a list of | 
 | notification types that determine for which events email notifications | 
 | should be sent. E.g. a user can configure that email notifications | 
 | should only be sent if a new patch set is uploaded and when the change | 
 | gets submitted, but not on other events. | 
 |  | 
 | Project watches are stored in a `watch.config` file in the user branch: | 
 |  | 
 | ---- | 
 | [project "foo"] | 
 |   notify = * [ALL_COMMENTS] | 
 |   notify = branch:master [ALL_COMMENTS, NEW_PATCHSETS] | 
 |   notify = branch:master owner:self [SUBMITTED_CHANGES] | 
 | ---- | 
 |  | 
 | The `watch.config` file has one project section for all project watches | 
 | of a project. The project name is used as subsection name and the | 
 | filters with the notification types, that decide for which events email | 
 | notifications should be sent, are represented as `notify` values in the | 
 | subsection. A `notify` value is formatted as | 
 | "<filter> [<comma-separated-list-of-notification-types>]". The | 
 | supported notification types are described in the | 
 | link:user-notify.html#notify.name.type[Email Notifications documentation]. | 
 |  | 
 | For a change event, a notification will be sent if any `notify` value | 
 | of the corresponding project has both a filter that matches the change | 
 | and a notification type that matches the event. | 
 |  | 
 | In order to send email notifications on change events, Gerrit needs to | 
 | find all accounts that watch the corresponding project. To make this | 
 | lookup fast the secondary account index is used. The account index | 
 | contains a repeated field that stores the projects that are being | 
 | watched by an account. After the accounts that watch the project have | 
 | been retrieved from the index, the complete watch configuration is | 
 | available from the account cache and Gerrit can check if any watch | 
 | matches the change and the event. | 
 |  | 
 | [[ssh-keys]] | 
 | === SSH Keys | 
 |  | 
 | SSH keys are stored in the user branch in an `authorized_keys` file, | 
 | which is the | 
 | link:https://en.wikibooks.org/wiki/OpenSSH/Client_Configuration_Files#.7E.2F.ssh.2Fauthorized_keys[ | 
 | standard OpenSSH file format] for storing SSH keys: | 
 |  | 
 | ---- | 
 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCgug5VyMXQGnem2H1KVC4/HcRcD4zzBqSuJBRWVonSSoz3RoAZ7bWXCVVGwchtXwUURD689wFYdiPecOrWOUgeeyRq754YWRhU+W28vf8IZixgjCmiBhaL2gt3wff6pP+NXJpTSA4aeWE5DfNK5tZlxlSxqkKOS8JRSUeNQov5Tw== john.doe@example.com | 
 | # DELETED | 
 | # INVALID ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDm5yP7FmEoqzQRDyskX+9+N0q9GrvZeh5RG52EUpE4ms/Ujm3ewV1LoGzc/lYKJAIbdcZQNJ9+06EfWZaIRA3oOwAPe1eCnX+aLr8E6Tw2gDMQOGc5e9HfyXpC2pDvzauoZNYqLALOG3y/1xjo7IH8GYRS2B7zO/Mf9DdCcCKSfw== john.doe@example.com | 
 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCaS7RHEcZ/zjl9hkWkqnm29RNr2OQ/TZ5jk2qBVMH3BgzPsTsEs+7ag9tfD8OCj+vOcwm626mQBZoR2e3niHa/9gnHBHFtOrGfzKbpRjTWtiOZbB9HF+rqMVD+Dawo/oicX/dDg7VAgOFSPothe6RMhbgWf84UcK5aQd5eP5y+tQ== john.doe@example.com | 
 | ---- | 
 |  | 
 | When the SSH API is used, Gerrit needs an efficient way to lookup SSH | 
 | keys by username. Since the username can be easily resolved to an | 
 | account ID (via the account cache), accessing the SSH keys in the user | 
 | branch is fast. | 
 |  | 
 | To identify SSH keys in the REST API Gerrit uses | 
 | link:rest-api-accounts.html#ssh-key-id[sequence numbers per account]. | 
 | This is why the order of the keys in the `authorized_keys` file is | 
 | used to determines the sequence numbers of the keys (the sequence | 
 | numbers start at 1). | 
 |  | 
 | To keep the sequence numbers intact when a key is deleted, a | 
 | '# DELETED' line is inserted at the position where the key was deleted. | 
 |  | 
 | Invalid keys are marked with the prefix '# INVALID'. | 
 |  | 
 | [[external-ids]] | 
 | == External IDs | 
 |  | 
 | External IDs are used to link external identities, such as an LDAP | 
 | account or an OAUTH identity, to an account in Gerrit. | 
 |  | 
 | External IDs are stored as Git Notes in the `All-Users` repository. The | 
 | name of the notes branch is `refs/meta/external-ids`. | 
 |  | 
 | As note key the SHA1 of the external ID key is used. This ensures that | 
 | an external ID is used only once (e.g. an external ID can never be | 
 | assigned to multiple accounts at a point in time). | 
 |  | 
 | The note content is a Git config file: | 
 |  | 
 | ---- | 
 | [externalId "username:jdoe"] | 
 |   accountId = 1003407 | 
 |   email = jdoe@example.com | 
 |   password = bcrypt:4:LCbmSBDivK/hhGVQMfkDpA==:XcWn0pKYSVU/UJgOvhidkEtmqCp6oKB7 | 
 | ---- | 
 |  | 
 | The config file has one `externalId` section. The external ID key which | 
 | consists of scheme and ID in the format '<scheme>:<id>' is used as | 
 | subsection name. | 
 |  | 
 | The `accountId` field is mandatory, the `email` and `password` fields | 
 | are optional. | 
 |  | 
 | The external IDs are maintained by Gerrit, this means users are not | 
 | allowed to manually edit their external IDs. Only users with the | 
 | link:access-control.html#capability_accessDatabase[Access Database] | 
 | global capability can push updates to the `refs/meta/external-ids` | 
 | branch. However Gerrit rejects pushes if: | 
 |  | 
 | * any external ID config file cannot be parsed | 
 | * if a note key does not match the SHA of the external ID key in the | 
 |   note content | 
 | * external IDs for non-existing accounts are contained | 
 | * invalid emails are contained | 
 | * any email is not unique (the same email is assigned to multiple | 
 |   accounts) | 
 | * hashed passwords of external IDs with scheme `username` cannot be | 
 |   decoded | 
 |  | 
 | [[starred-changes]] | 
 | == Starred Changes | 
 |  | 
 | link:dev-stars.html[Starred changes] allow users to mark changes as | 
 | favorites and receive email notifications for them. | 
 |  | 
 | Each starred change is a tuple of an account ID, a change ID and a | 
 | label. | 
 |  | 
 | To keep track of a change that is starred by an account, Gerrit creates | 
 | a `refs/starred-changes/YY/XXXX/ZZZZZZZ` ref in the `All-Users` | 
 | repository, where `YY/XXXX` is the sharded numeric change ID and | 
 | `ZZZZZZZ` is the account ID. | 
 |  | 
 | A starred-changes ref points to a blob that contains the list of labels | 
 | that the account set on the change. The label list is stored as UTF-8 | 
 | text with one label per line. | 
 |  | 
 | Since JGit has explicit optimizations for looking up refs by prefix | 
 | when the prefix ends with '/', this ref format is optimized to find | 
 | starred changes by change ID. Finding starred changes by change ID is | 
 | e.g. needed when a change is updated so that all users that have | 
 | the link:dev-stars.html#default-star[default star] on the change can be | 
 | notified by email. | 
 |  | 
 | Gerrit also needs an efficient way to find all changes that were | 
 | starred by an account, e.g. to provide results for the | 
 | link:user-search.html#is-starred[is:starred] query operator. With the | 
 | ref format as described above the lookup of starred changes by account | 
 | ID is expensive, as this requires a scan of the full | 
 | `refs/starred-changes/*` namespace. To overcome this the users that | 
 | have starred a change are stored in the change index together with the | 
 | star labels. | 
 |  | 
 | [[reviewed-flags]] | 
 | == Reviewed Flags | 
 |  | 
 | When reviewing a patch set in the Gerrit UI, the reviewer can mark | 
 | files in the patch set as reviewed. These markers are called ‘Reviewed | 
 | Flags’ and are private to the user. A reviewed flag is a tuple of patch | 
 | set ID, file and account ID. | 
 |  | 
 | Each user can have many thousands of reviewed flags and over time the | 
 | number can grow without bounds. | 
 |  | 
 | The high amount of reviewed flags makes a storage in Git unsuitable | 
 | because each update requires opening the repository and committing a | 
 | change, which is a high overhead for flipping a bit. Therefore the | 
 | reviewed flags are stored in a database table. By default they are | 
 | stored in a local H2 database, but there is an extension point that | 
 | allows to plug in alternate implementations for storing the reviewed | 
 | flags. To replace the storage for reviewed flags a plugin needs to | 
 | implement the link:dev-plugins.html#account-patch-review-store[ | 
 | AccountPatchReviewStore] interface. E.g. to support a multi-master | 
 | setup where reviewed flags should be replicated between the master | 
 | nodes one could implement a store for the reviewed flags that is | 
 | based on MySQL with replication. | 
 |  | 
 | [[account-sequence]] | 
 | == Account Sequence | 
 |  | 
 | The next available account sequence number is stored as UTF-8 text in a | 
 | blob pointed to by the `refs/sequences/accounts` ref in the `All-Users` | 
 | repository. | 
 |  | 
 | Multiple processes share the same sequence by incrementing the counter | 
 | using normal git ref updates. To amortize the cost of these ref | 
 | updates, processes increment the counter by a larger number and hand | 
 | out numbers from that range in memory until they run out. The size of | 
 | the account ID batch that each process retrieves at once is controlled | 
 | by the link:config-gerrit.html#notedb.accounts.sequenceBatchSize[ | 
 | notedb.accounts.sequenceBatchSize] parameter in the `gerrit.config` | 
 | file. | 
 |  | 
 | [[replication]] | 
 | == Replication | 
 |  | 
 | To replicate account data the following branches from the `All-Users` | 
 | repository must be replicated: | 
 |  | 
 | * `refs/users/*` (user branches) | 
 | * `refs/meta/external-ids` (external IDs) | 
 | * `refs/starred-changes/*` (star labels) | 
 | * `refs/sequences/accounts` (account sequence numbers, not needed for Gerrit | 
 |   slaves) | 
 |  | 
 | GERRIT | 
 | ------ | 
 | Part of link:index.html[Gerrit Code Review] | 
 |  | 
 | SEARCHBOX | 
 | --------- |