Device & systemSecurity & malware
Android Accounts: accounts_ce.db and accounts_de.db
Android's AccountManager databases: which Google, Samsung and app accounts are on the phone, CE and DE split, password entry times, debug history and tokens.
- Location
- /data/system_ce/<user>/accounts_ce.db and /data/system_de/<user>/accounts_de.db
- Proves
- Which accounts (Google, Samsung, Microsoft, messaging and social apps) were registered on the device per user, their account types, when a password was last entered, and recent account operations
- Timestamps
- accounts.last_password_entry_time_millis_epoch in Unix milliseconds (UTC); debug_table.time as a text date in device local time on AOSP
- Access
- Full file system (root, exploit or agent): accounts_de.db is device-encrypted (BFU readable by a privileged extraction), accounts_ce.db is credential-encrypted (AFU only). Logical and bugreport: dumpsys account lists accounts and recent history. Not in ADB backup.
- Retention
- Current state: an account removed from the device is deleted from both databases; the debug history keeps a small ring of recent operations
- Collection
- Full file system extraction, adb shell dumpsys account, adb bugreport
Tools
Compare all toolsWhat it is
AccountManagerService is Android's central registry of online accounts. When a user signs into Google, a Samsung account, Outlook, WhatsApp, Telegram or any app that uses the account framework, the app registers an account of its own type with the system. Contacts, calendar and sync adapters attach to those accounts, and apps use the stored tokens to call their services.
Since Android 7 the store is split across two SQLite databases per user: accounts_de.db in device-encrypted storage, available as soon as the phone boots, and accounts_ce.db in credential-encrypted storage, available only after the first unlock. For an investigator they answer early questions: who is this phone's user online, which services should legal process target, and when were accounts added or re-authenticated.
Where it lives
| Item | Path | Notes |
|---|---|---|
| DE database | /data/system_de/<user>/accounts_de.db | Account names and types, grants, visibility, debug history |
| CE database | /data/system_ce/<user>/accounts_ce.db | Passwords or tokens, auth tokens, extras |
| Pre-Android 7 | /data/system/users/<user>/accounts.db | Single database, found on very old upgrades only |
| Contacts per account | contacts2.db accounts table | Separate, contacts-provider view |
<user> is 0 for the owner; work profiles and secondary users (10, 11...) have their own pair.
What it proves
- Every account registered with the system, by name (often an email address or phone number) and type (
com.google,com.osp.app.signinfor Samsung account,com.whatsapp,org.telegram.messenger,com.microsoft.workaccountand so on). - The last time a password was entered for an account (
last_password_entry_time_millis_epoch), useful for spotting a recently added or re-authenticated account. - Previous account names after a rename (
previous_name). - Which apps were granted access to which accounts (
grants,visibility). - A short history of account operations with times and caller UIDs (
debug_table).
It does not prove the device user controls the account now, and it rarely includes passwords: modern apps store OAuth tokens, which are still sensitive and must be handled as live credentials.
Key fields
| Table | Columns | Meaning |
|---|---|---|
accounts (DE) | _id, name, type, previous_name, last_password_entry_time_millis_epoch | Account list |
accounts (CE) | _id, name, type, password | Secret or token per account |
authtokens (CE) | accounts_id, type, authtoken | Cached auth tokens by scope |
extras (CE) | accounts_id, key, value | App-specific account data |
grants (DE) | accounts_id, auth_token_type, uid | UIDs allowed to use a token type |
visibility (DE) | accounts_id, _package, value | Package visibility of an account |
debug_table (DE) | action_type, time, caller_uid, table_name, primary_key | Recent operations (add, remove, set password, update) |
Timestamps
last_password_entry_time_millis_epoch is Unix milliseconds in UTC. On AOSP, debug_table.time is a text string (2026-09-14 17:43:05) written in the device's local time: record the device time zone before converting.
-- accounts_de.db
SELECT _id, name, type, previous_name,
datetime(last_password_entry_time_millis_epoch/1000, 'unixepoch') AS last_pw_utc
FROM accounts;
SELECT time, action_type, caller_uid, table_name, primary_key
FROM debug_table ORDER BY time DESC;
Retention
Both databases reflect current state: removing an account deletes its rows (sometimes recoverable from free pages or the WAL for a while). debug_table is a small ring buffer (64 rows on AOSP), so on a busy phone it covers days or weeks. A factory reset removes everything, and the reset itself can often be dated from the device identifiers page.
Collection
- Full file system extraction: both databases with their journals. In BFU you still get
accounts_de.db, which lists the accounts. - Logical:
adb shell dumpsys accountprints accounts per user, recent account history and the services bound to them. It masks some names on recent releases. - Bugreport: includes the same dump.
Parsing
- ALEAPP reports accounts from both databases and joins types to friendly names.
sqlite3with the queries above.- Commercial suites list accounts in their device information section.
Investigator tips
- The Google account in
accounts_de.dbis the one to name in a request for cloud data such as Timeline backups, Photos or Drive. - An account type belonging to an app that is not in installed packages points to a recent uninstall.
- A fresh
last_password_entry_timejust before seizure may indicate someone re-added an account after a reset. - Treat
accounts_ce.dbas a credential store: restrict access, and never use its tokens. - The bugreport guide shows where
dumpsys accountoutput sits in a bugreport.