Merge remote-tracking branch 'cos/cos-sdk' into master

BUG=b/277779682
TEST=presubmit
RELEASE_NOTE=None

Change-Id: I924152e1e62da1c144ef0c18e19832e05e9e2f91
diff --git a/OWNERS.security b/OWNERS.security
new file mode 100644
index 0000000..0300dc1
--- /dev/null
+++ b/OWNERS.security
@@ -0,0 +1 @@
+include chromiumos/overlays/chromiumos-overlay:/OWNERS.security
diff --git a/PRESUBMIT.cfg b/PRESUBMIT.cfg
index 450b7b9..d2adf6b 100644
--- a/PRESUBMIT.cfg
+++ b/PRESUBMIT.cfg
@@ -4,3 +4,4 @@
 
 [Hook Scripts]
 account_checks = profiles/base/accounts/display-accts.py --lint
+cros format = cros format --check --commit ${PRESUBMIT_COMMIT} ${PRESUBMIT_FILES}
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..1196dae
--- /dev/null
+++ b/README.md
@@ -0,0 +1,6 @@
+# CrOS eclass overlay
+
+This eclass overlay is used for 2 purposes:
+
+* [Eclass overrides for all overlays](https://chromium.googlesource.com/chromiumos/docs/+/HEAD/portage/overlay_faq.md#eclass_overlay).
+* [Account management (user & group)](https://chromium.googlesource.com/chromiumos/docs/+/HEAD/account_management.md).
diff --git a/acct-group/OWNERS b/acct-group/OWNERS
new file mode 100644
index 0000000..5a77185
--- /dev/null
+++ b/acct-group/OWNERS
@@ -0,0 +1 @@
+include /OWNERS.security
diff --git a/acct-group/audio/audio-0-r1.ebuild b/acct-group/audio/audio-0-r1.ebuild
new file mode 100644
index 0000000..ee02772
--- /dev/null
+++ b/acct-group/audio/audio-0-r1.ebuild
@@ -0,0 +1,8 @@
+# Copyright 2019-2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit acct-group
+
+ACCT_GROUP_ID=18
diff --git a/acct-group/audio/metadata.xml b/acct-group/audio/metadata.xml
new file mode 100644
index 0000000..31123d0
--- /dev/null
+++ b/acct-group/audio/metadata.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "https://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+	<maintainer type="project">
+		<email>systemd@gentoo.org</email>
+	</maintainer>
+</pkgmetadata>
diff --git a/acct-group/cdrom/cdrom-0-r1.ebuild b/acct-group/cdrom/cdrom-0-r1.ebuild
new file mode 100644
index 0000000..8d402a9
--- /dev/null
+++ b/acct-group/cdrom/cdrom-0-r1.ebuild
@@ -0,0 +1,8 @@
+# Copyright 2019-2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit acct-group
+
+ACCT_GROUP_ID=19
diff --git a/acct-group/cdrom/metadata.xml b/acct-group/cdrom/metadata.xml
new file mode 100644
index 0000000..31123d0
--- /dev/null
+++ b/acct-group/cdrom/metadata.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "https://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+	<maintainer type="project">
+		<email>systemd@gentoo.org</email>
+	</maintainer>
+</pkgmetadata>
diff --git a/acct-group/chronos/chronos-0.0.1.ebuild b/acct-group/chronos/chronos-0.0.1.ebuild
new file mode 100644
index 0000000..9d9ad46
--- /dev/null
+++ b/acct-group/chronos/chronos-0.0.1.ebuild
@@ -0,0 +1,11 @@
+# Copyright 2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit acct-group
+
+# NB: These settings are ignored in CrOS for now.
+# See the files in profiles/base/accounts/ instead.
+
+ACCT_GROUP_ID=1000
diff --git a/acct-group/cros_healthd/cros_healthd-0.0.1.ebuild b/acct-group/cros_healthd/cros_healthd-0.0.1.ebuild
new file mode 100644
index 0000000..642d9b5
--- /dev/null
+++ b/acct-group/cros_healthd/cros_healthd-0.0.1.ebuild
@@ -0,0 +1,11 @@
+# Copyright 2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit acct-group
+
+# NB: These settings are ignored in CrOS for now.
+# See the files in profiles/base/accounts/ instead.
+
+ACCT_GROUP_ID=20134
diff --git a/acct-group/dhcp/dhcp-0-r1.ebuild b/acct-group/dhcp/dhcp-0-r1.ebuild
new file mode 100644
index 0000000..5b54d2e
--- /dev/null
+++ b/acct-group/dhcp/dhcp-0-r1.ebuild
@@ -0,0 +1,8 @@
+# Copyright 2019-2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit acct-group
+
+ACCT_GROUP_ID=300
diff --git a/acct-group/dhcp/metadata.xml b/acct-group/dhcp/metadata.xml
new file mode 100644
index 0000000..65e1fc8
--- /dev/null
+++ b/acct-group/dhcp/metadata.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "https://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+	<maintainer type="project">
+		<email>base-system@gentoo.org</email>
+	</maintainer>
+</pkgmetadata>
diff --git a/acct-group/dialout/dialout-0-r1.ebuild b/acct-group/dialout/dialout-0-r1.ebuild
new file mode 100644
index 0000000..3c1316a
--- /dev/null
+++ b/acct-group/dialout/dialout-0-r1.ebuild
@@ -0,0 +1,8 @@
+# Copyright 2019-2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit acct-group
+
+ACCT_GROUP_ID=20
diff --git a/acct-group/dialout/metadata.xml b/acct-group/dialout/metadata.xml
new file mode 100644
index 0000000..31123d0
--- /dev/null
+++ b/acct-group/dialout/metadata.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "https://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+	<maintainer type="project">
+		<email>systemd@gentoo.org</email>
+	</maintainer>
+</pkgmetadata>
diff --git a/acct-group/disk/disk-0-r1.ebuild b/acct-group/disk/disk-0-r1.ebuild
new file mode 100644
index 0000000..a5568d6
--- /dev/null
+++ b/acct-group/disk/disk-0-r1.ebuild
@@ -0,0 +1,8 @@
+# Copyright 2019-2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit acct-group
+
+ACCT_GROUP_ID=6
diff --git a/acct-group/disk/metadata.xml b/acct-group/disk/metadata.xml
new file mode 100644
index 0000000..31123d0
--- /dev/null
+++ b/acct-group/disk/metadata.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "https://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+	<maintainer type="project">
+		<email>systemd@gentoo.org</email>
+	</maintainer>
+</pkgmetadata>
diff --git a/acct-group/docker/docker-0.0.1.ebuild b/acct-group/docker/docker-0.0.1.ebuild
index ca0e83f..bdde5aa 100644
--- a/acct-group/docker/docker-0.0.1.ebuild
+++ b/acct-group/docker/docker-0.0.1.ebuild
@@ -1,4 +1,4 @@
-# Copyright 2021 The Chromium OS Authors. All rights reserved.
+# Copyright 2021 The ChromiumOS Authors
 # Distributed under the terms of the GNU General Public License v2
 
 EAPI=7
diff --git a/acct-group/fwupd/fwupd-0.0.1.ebuild b/acct-group/fwupd/fwupd-0.0.1.ebuild
new file mode 100644
index 0000000..bc464b1
--- /dev/null
+++ b/acct-group/fwupd/fwupd-0.0.1.ebuild
@@ -0,0 +1,11 @@
+# Copyright 2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit acct-group
+
+# NB: These settings are ignored in CrOS for now.
+# See the files in profiles/base/accounts/ instead.
+
+ACCT_GROUP_ID=20130
diff --git a/acct-group/input/input-0-r1.ebuild b/acct-group/input/input-0-r1.ebuild
new file mode 100644
index 0000000..9ef06e8
--- /dev/null
+++ b/acct-group/input/input-0-r1.ebuild
@@ -0,0 +1,8 @@
+# Copyright 2019-2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit acct-group
+
+ACCT_GROUP_ID=97
diff --git a/acct-group/input/metadata.xml b/acct-group/input/metadata.xml
new file mode 100644
index 0000000..31123d0
--- /dev/null
+++ b/acct-group/input/metadata.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "https://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+	<maintainer type="project">
+		<email>systemd@gentoo.org</email>
+	</maintainer>
+</pkgmetadata>
diff --git a/acct-group/kmem/kmem-0-r1.ebuild b/acct-group/kmem/kmem-0-r1.ebuild
new file mode 100644
index 0000000..b07239c
--- /dev/null
+++ b/acct-group/kmem/kmem-0-r1.ebuild
@@ -0,0 +1,8 @@
+# Copyright 2019-2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit acct-group
+
+ACCT_GROUP_ID=9
diff --git a/acct-group/kmem/metadata.xml b/acct-group/kmem/metadata.xml
new file mode 100644
index 0000000..31123d0
--- /dev/null
+++ b/acct-group/kmem/metadata.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "https://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+	<maintainer type="project">
+		<email>systemd@gentoo.org</email>
+	</maintainer>
+</pkgmetadata>
diff --git a/acct-group/kvm/kvm-0.0.1.ebuild b/acct-group/kvm/kvm-0.0.1.ebuild
index 684b0cf..d93cb94 100644
--- a/acct-group/kvm/kvm-0.0.1.ebuild
+++ b/acct-group/kvm/kvm-0.0.1.ebuild
@@ -1,4 +1,4 @@
-# Copyright 2020 The Chromium OS Authors. All rights reserved.
+# Copyright 2020 The ChromiumOS Authors
 # Distributed under the terms of the GNU General Public License v2
 
 EAPI=7
diff --git a/acct-group/lp/lp-0-r1.ebuild b/acct-group/lp/lp-0-r1.ebuild
new file mode 100644
index 0000000..9af7c05
--- /dev/null
+++ b/acct-group/lp/lp-0-r1.ebuild
@@ -0,0 +1,8 @@
+# Copyright 2019-2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit acct-group
+
+ACCT_GROUP_ID=7
diff --git a/acct-group/lp/metadata.xml b/acct-group/lp/metadata.xml
new file mode 100644
index 0000000..ba8bc47
--- /dev/null
+++ b/acct-group/lp/metadata.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "https://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+	<maintainer type="project">
+		<email>systemd@gentoo.org</email>
+	</maintainer>
+	<maintainer type="project">
+		<email>printing@gentoo.org</email>
+	</maintainer>
+</pkgmetadata>
diff --git a/acct-group/node_exporter/node_exporter-0.0.1.ebuild b/acct-group/node_exporter/node_exporter-0.0.1.ebuild
new file mode 100644
index 0000000..394d901
--- /dev/null
+++ b/acct-group/node_exporter/node_exporter-0.0.1.ebuild
@@ -0,0 +1,11 @@
+# Copyright 2022 The ChromiumOS Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+SLOT="0"
+KEYWORDS="*"
+
+inherit acct-group
+
+ACCT_GROUP_ID=459
diff --git a/acct-group/openvpn/metadata.xml b/acct-group/openvpn/metadata.xml
new file mode 100644
index 0000000..bd6443d
--- /dev/null
+++ b/acct-group/openvpn/metadata.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "https://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+	<maintainer type="person">
+		<email>chutzpah@gentoo.org</email>
+		<name>Patrick McLean</name>
+	</maintainer>
+</pkgmetadata>
diff --git a/acct-group/openvpn/openvpn-0-r1.ebuild b/acct-group/openvpn/openvpn-0-r1.ebuild
new file mode 100644
index 0000000..0abedcd
--- /dev/null
+++ b/acct-group/openvpn/openvpn-0-r1.ebuild
@@ -0,0 +1,8 @@
+# Copyright 2019-2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit acct-group
+
+ACCT_GROUP_ID=394
diff --git a/acct-group/plugdev/OWNERS b/acct-group/plugdev/OWNERS
deleted file mode 100644
index ee122c0..0000000
--- a/acct-group/plugdev/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-include /OWNERS
diff --git a/acct-group/plugdev/plugdev-0.0.1.ebuild b/acct-group/plugdev/plugdev-0.0.1.ebuild
index 726a942..e650f7f 100644
--- a/acct-group/plugdev/plugdev-0.0.1.ebuild
+++ b/acct-group/plugdev/plugdev-0.0.1.ebuild
@@ -1,9 +1,8 @@
-# Copyright 2022 The Chromium OS Authors. All rights reserved.
+# Copyright 2022 The ChromiumOS Authors
 # Distributed under the terms of the GNU General Public License v2
 
 EAPI=7
 
-LICENSE="GPL-2"
 SLOT="0"
 KEYWORDS="*"
 
diff --git a/acct-group/sshd/metadata.xml b/acct-group/sshd/metadata.xml
new file mode 100644
index 0000000..bc93e52
--- /dev/null
+++ b/acct-group/sshd/metadata.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "https://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+  <maintainer type="project">
+    <email>base-system@gentoo.org</email>
+    <name>Gentoo Base System</name>
+  </maintainer>
+</pkgmetadata>
diff --git a/acct-group/sshd/sshd-0-r1.ebuild b/acct-group/sshd/sshd-0-r1.ebuild
new file mode 100644
index 0000000..c681ca3
--- /dev/null
+++ b/acct-group/sshd/sshd-0-r1.ebuild
@@ -0,0 +1,11 @@
+# Copyright 2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit acct-group
+
+# NB: These settings are ignored in CrOS for now.
+# See the files in profiles/base/accounts/ instead.
+
+ACCT_GROUP_ID=22
diff --git a/acct-group/sshd/sshd-0.0.1.ebuild b/acct-group/sshd/sshd-0.0.1.ebuild
deleted file mode 100644
index 6bac280..0000000
--- a/acct-group/sshd/sshd-0.0.1.ebuild
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2020 The Chromium OS Authors. All rights reserved.
-# Distributed under the terms of the GNU General Public License v2
-
-EAPI=7
-
-SLOT="0"
-KEYWORDS="*"
-
-inherit user
-
-# TODO(crbug/1026816): this is a placeholder (to satisfy Gentoo
-#  openssh dependencies) while acct-{group,user} are implemented.
-pkg_setup() {
-	enewgroup sshd
-}
diff --git a/acct-group/tape/metadata.xml b/acct-group/tape/metadata.xml
new file mode 100644
index 0000000..31123d0
--- /dev/null
+++ b/acct-group/tape/metadata.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "https://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+	<maintainer type="project">
+		<email>systemd@gentoo.org</email>
+	</maintainer>
+</pkgmetadata>
diff --git a/acct-group/tape/tape-0-r1.ebuild b/acct-group/tape/tape-0-r1.ebuild
new file mode 100644
index 0000000..e7aa561
--- /dev/null
+++ b/acct-group/tape/tape-0-r1.ebuild
@@ -0,0 +1,8 @@
+# Copyright 2019-2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit acct-group
+
+ACCT_GROUP_ID=26
diff --git a/acct-group/tty/metadata.xml b/acct-group/tty/metadata.xml
new file mode 100644
index 0000000..31123d0
--- /dev/null
+++ b/acct-group/tty/metadata.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "https://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+	<maintainer type="project">
+		<email>systemd@gentoo.org</email>
+	</maintainer>
+</pkgmetadata>
diff --git a/acct-group/tty/tty-0-r1.ebuild b/acct-group/tty/tty-0-r1.ebuild
new file mode 100644
index 0000000..2133d92
--- /dev/null
+++ b/acct-group/tty/tty-0-r1.ebuild
@@ -0,0 +1,8 @@
+# Copyright 2019-2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit acct-group
+
+ACCT_GROUP_ID=5
diff --git a/acct-group/video/metadata.xml b/acct-group/video/metadata.xml
new file mode 100644
index 0000000..31123d0
--- /dev/null
+++ b/acct-group/video/metadata.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "https://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+	<maintainer type="project">
+		<email>systemd@gentoo.org</email>
+	</maintainer>
+</pkgmetadata>
diff --git a/acct-group/video/video-0-r1.ebuild b/acct-group/video/video-0-r1.ebuild
new file mode 100644
index 0000000..3b06b5b
--- /dev/null
+++ b/acct-group/video/video-0-r1.ebuild
@@ -0,0 +1,8 @@
+# Copyright 2019-2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit acct-group
+
+ACCT_GROUP_ID=27
diff --git a/acct-user/OWNERS b/acct-user/OWNERS
new file mode 100644
index 0000000..5a77185
--- /dev/null
+++ b/acct-user/OWNERS
@@ -0,0 +1 @@
+include /OWNERS.security
diff --git a/acct-user/chronos/chronos-0.0.2.ebuild b/acct-user/chronos/chronos-0.0.2.ebuild
new file mode 100644
index 0000000..d27d77b
--- /dev/null
+++ b/acct-user/chronos/chronos-0.0.2.ebuild
@@ -0,0 +1,16 @@
+# Copyright 2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit acct-user
+
+DESCRIPTION="The user that all user-facing processes will run as"
+
+DEPEND="app-shells/bash"
+RDEPEND="${DEPEND}"
+
+# NB: These settings are ignored in CrOS for now.
+# See the files in profiles/base/accounts/ instead.
+
+ACCT_USER_ID=1000
diff --git a/acct-user/cros_healthd/cros_healthd-0.0.1.ebuild b/acct-user/cros_healthd/cros_healthd-0.0.1.ebuild
new file mode 100644
index 0000000..3b29036
--- /dev/null
+++ b/acct-user/cros_healthd/cros_healthd-0.0.1.ebuild
@@ -0,0 +1,13 @@
+# Copyright 2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit acct-user
+
+DESCRIPTION="User for diagnostics and telemetry services"
+
+# NB: These settings are ignored in CrOS for now.
+# See the files in profiles/base/accounts/ instead.
+
+ACCT_USER_ID=20134
diff --git a/acct-user/dhcp/dhcp-0-r1.ebuild b/acct-user/dhcp/dhcp-0-r1.ebuild
new file mode 100644
index 0000000..d27eca2
--- /dev/null
+++ b/acct-user/dhcp/dhcp-0-r1.ebuild
@@ -0,0 +1,12 @@
+# Copyright 2019-2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit acct-user
+
+DESCRIPTION="user for dhcp daemon"
+ACCT_USER_ID=300
+ACCT_USER_GROUPS=( dhcp )
+
+acct-user_add_deps
diff --git a/acct-user/dhcp/metadata.xml b/acct-user/dhcp/metadata.xml
new file mode 100644
index 0000000..65e1fc8
--- /dev/null
+++ b/acct-user/dhcp/metadata.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "https://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+	<maintainer type="project">
+		<email>base-system@gentoo.org</email>
+	</maintainer>
+</pkgmetadata>
diff --git a/acct-user/fwupd/fwupd-0.0.1.ebuild b/acct-user/fwupd/fwupd-0.0.1.ebuild
new file mode 100644
index 0000000..7124fa2
--- /dev/null
+++ b/acct-user/fwupd/fwupd-0.0.1.ebuild
@@ -0,0 +1,13 @@
+# Copyright 2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit acct-user
+
+DESCRIPTION="User for fwupd"
+
+# NB: These settings are ignored in CrOS for now.
+# See the files in profiles/base/accounts/ instead.
+
+ACCT_USER_ID=20130
diff --git a/acct-user/gpsd/OWNERS b/acct-user/gpsd/OWNERS
deleted file mode 100644
index 20818c7..0000000
--- a/acct-user/gpsd/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-aditin@google.com
diff --git a/acct-user/gpsd/gpsd-0.0.1.ebuild b/acct-user/gpsd/gpsd-0.0.1.ebuild
index bcb2ce6..d0590da 100644
--- a/acct-user/gpsd/gpsd-0.0.1.ebuild
+++ b/acct-user/gpsd/gpsd-0.0.1.ebuild
@@ -1,11 +1,10 @@
-# Copyright 2020 The Chromium OS Authors. All rights reserved.
+# Copyright 2020 The ChromiumOS Authors
 # Distributed under the terms of the GNU General Public License v2
 
 EAPI=7
 
 SLOT="0"
 KEYWORDS="*"
-LICENSE=BSD-Google
 
 inherit user
 
diff --git a/acct-user/node_exporter/node_exporter-0.0.1.ebuild b/acct-user/node_exporter/node_exporter-0.0.1.ebuild
new file mode 100644
index 0000000..0b836ea
--- /dev/null
+++ b/acct-user/node_exporter/node_exporter-0.0.1.ebuild
@@ -0,0 +1,15 @@
+# Copyright 2022 The ChromiumOS Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+SLOT="0"
+KEYWORDS="*"
+
+inherit acct-user
+
+DESCRIPTION="node_exporter User"
+ACCT_USER_ID=459
+ACCT_USER_GROUPS=( node_exporter )
+
+acct-user_add_deps
diff --git a/acct-user/openvpn/metadata.xml b/acct-user/openvpn/metadata.xml
new file mode 100644
index 0000000..bd6443d
--- /dev/null
+++ b/acct-user/openvpn/metadata.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "https://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+	<maintainer type="person">
+		<email>chutzpah@gentoo.org</email>
+		<name>Patrick McLean</name>
+	</maintainer>
+</pkgmetadata>
diff --git a/acct-user/openvpn/openvpn-0-r1.ebuild b/acct-user/openvpn/openvpn-0-r1.ebuild
new file mode 100644
index 0000000..006f421
--- /dev/null
+++ b/acct-user/openvpn/openvpn-0-r1.ebuild
@@ -0,0 +1,13 @@
+# Copyright 2019-2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit acct-user
+
+DESCRIPTION="User for net-vpn/openvpn"
+
+ACCT_USER_ID=394
+ACCT_USER_GROUPS=( openvpn )
+
+acct-user_add_deps
diff --git a/acct-user/sshd/metadata.xml b/acct-user/sshd/metadata.xml
new file mode 100644
index 0000000..bc93e52
--- /dev/null
+++ b/acct-user/sshd/metadata.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "https://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+  <maintainer type="project">
+    <email>base-system@gentoo.org</email>
+    <name>Gentoo Base System</name>
+  </maintainer>
+</pkgmetadata>
diff --git a/acct-user/sshd/sshd-0-r1.ebuild b/acct-user/sshd/sshd-0-r1.ebuild
new file mode 100644
index 0000000..de91a3d
--- /dev/null
+++ b/acct-user/sshd/sshd-0-r1.ebuild
@@ -0,0 +1,18 @@
+# Copyright 2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit acct-user
+
+DESCRIPTION="User for ssh"
+
+# NB: These settings are ignored in CrOS for now.
+# See the files in profiles/base/accounts/ instead.
+
+ACCT_USER_ID=22
+ACCT_USER_HOME=/var/empty
+ACCT_USER_HOME_OWNER=root:root
+ACCT_USER_GROUPS=( sshd )
+
+acct-user_add_deps
diff --git a/acct-user/sshd/sshd-0.0.1.ebuild b/acct-user/sshd/sshd-0.0.1.ebuild
deleted file mode 100644
index f76cefc..0000000
--- a/acct-user/sshd/sshd-0.0.1.ebuild
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2020 The Chromium OS Authors. All rights reserved.
-# Distributed under the terms of the GNU General Public License v2
-
-EAPI=7
-
-SLOT="0"
-KEYWORDS="*"
-
-inherit user
-
-# TODO(crbug/1026816): this is a placeholder (to satisfy Gentoo
-#  openssh dependencies) while acct-{group,user} are implemented.
-pkg_setup() {
-	enewuser sshd
-}
diff --git a/eclass/acct-group.eclass b/eclass/acct-group.eclass
new file mode 100644
index 0000000..b1a9ba5
--- /dev/null
+++ b/eclass/acct-group.eclass
@@ -0,0 +1,152 @@
+# Copyright 2019-2022 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+# @ECLASS: acct-group.eclass
+# @MAINTAINER:
+# Michał Górny <mgorny@gentoo.org>
+# Mike Gilbert <floppym@gentoo.org>
+# @AUTHOR:
+# Michael Orlitzky <mjo@gentoo.org>
+# Michał Górny <mgorny@gentoo.org>
+# @SUPPORTED_EAPIS: 7 8
+# @BLURB: Eclass used to create and maintain a single group entry
+# @DESCRIPTION:
+# This eclass represents and creates a single group entry.  The name
+# of the group is derived from ${PN}, while (preferred) GID needs to
+# be specified via ACCT_GROUP_ID.  Packages (and users) needing the group
+# in question should depend on the package providing it.
+#
+# Example:
+# If your package needs group 'foo', you create 'acct-group/foo' package
+# and add an ebuild with the following contents:
+#
+# @CODE
+# EAPI=8
+# inherit acct-group
+# ACCT_GROUP_ID=200
+# @CODE
+#
+# Then you add appropriate dependencies to your package.  Note that
+# the build system might need to resolve names, too.  The dependency
+# type(s) should be: BDEPEND if the group must be resolvable at build
+# time (e.g. 'fowners' uses it in src_install), IDEPEND if it must be
+# resolvable at install time (e.g. 'fowners' uses it in pkg_preinst),
+# and RDEPEND in every case.
+
+if [[ -z ${_ACCT_GROUP_ECLASS} ]]; then
+_ACCT_GROUP_ECLASS=1
+
+case ${EAPI:-0} in
+	7|8) ;;
+	*) die "EAPI=${EAPI:-0} not supported";;
+esac
+
+inherit user-info
+
+[[ ${CATEGORY} == acct-group ]] ||
+	die "Ebuild error: this eclass can be used only in acct-group category!"
+
+
+# << Eclass variables >>
+
+# @ECLASS_VARIABLE: ACCT_GROUP_NAME
+# @INTERNAL
+# @DESCRIPTION:
+# The name of the group.  This is forced to ${PN} and the policy
+# prohibits it from being changed.
+ACCT_GROUP_NAME=${PN}
+readonly ACCT_GROUP_NAME
+
+# @ECLASS_VARIABLE: ACCT_GROUP_ID
+# @REQUIRED
+# @DESCRIPTION:
+# Preferred GID for the new group.  This variable is obligatory, and its
+# value must be unique across all group packages.  This can be overriden
+# in make.conf through ACCT_GROUP_<UPPERCASE_USERNAME>_ID variable.
+#
+# Overlays should set this to -1 to dynamically allocate GID.  Using -1
+# in ::gentoo is prohibited by policy.
+
+# @ECLASS_VARIABLE: ACCT_GROUP_ENFORCE_ID
+# @DESCRIPTION:
+# If set to a non-null value, the eclass will require the group to have
+# specified GID.  If the group already exists with another GID, or
+# the GID is taken by another group, the install will fail.
+: ${ACCT_GROUP_ENFORCE_ID:=}
+
+
+# << Boilerplate ebuild variables >>
+: ${DESCRIPTION:="System group: ${ACCT_GROUP_NAME}"}
+: ${SLOT:=0}
+: "${KEYWORDS:=*}"
+S=${WORKDIR}
+
+
+# << Phase functions >>
+# CrOS: Disable most functions since we don't use them in CrOS.
+EXPORT_FUNCTIONS pkg_pretend pkg_preinst
+
+# @FUNCTION: acct-group_pkg_pretend
+# @DESCRIPTION:
+# Performs sanity checks for correct eclass usage, and early-checks
+# whether requested GID can be enforced.
+acct-group_pkg_pretend() {
+	debug-print-function ${FUNCNAME} "${@}"
+
+	# verify ACCT_GROUP_ID
+	[[ -n ${ACCT_GROUP_ID} ]] || die "Ebuild error: ACCT_GROUP_ID must be set!"
+	[[ ${ACCT_GROUP_ID} -ge -1 ]] || die "Ebuild error: ACCT_GROUP_ID=${ACCT_GROUP_ID} invalid!"
+	local group_id=${ACCT_GROUP_ID}
+
+	# check for the override
+	local override_name=${ACCT_GROUP_NAME^^}
+	local override_var=ACCT_GROUP_${override_name//-/_}_ID
+	if [[ -n ${!override_var} ]]; then
+		group_id=${!override_var}
+		[[ ${group_id} -ge -1 ]] || die "${override_var}=${group_id} invalid!"
+	fi
+
+	# CrOS: We don't need this logic.
+	return
+
+	# check for ACCT_GROUP_ID collisions early
+	if [[ ${group_id} -ne -1 && -n ${ACCT_GROUP_ENFORCE_ID} ]]; then
+		local group_by_id=$(egetgroupname "${group_id}")
+		local group_by_name=$(egetent group "${ACCT_GROUP_NAME}")
+		if [[ -n ${group_by_id} ]]; then
+			if [[ ${group_by_id} != ${ACCT_GROUP_NAME} ]]; then
+				eerror "The required GID is already taken by another group."
+				eerror "  GID: ${group_id}"
+				eerror "  needed for: ${ACCT_GROUP_NAME}"
+				eerror "  current group: ${group_by_id}"
+				die "GID ${group_id} taken already"
+			fi
+		elif [[ -n ${group_by_name} ]]; then
+			eerror "The requested group exists already with wrong GID."
+			eerror "  groupname: ${ACCT_GROUP_NAME}"
+			eerror "  requested GID: ${group_id}"
+			eerror "  current entry: ${group_by_name}"
+			die "Group ${ACCT_GROUP_NAME} exists with wrong GID"
+		fi
+	fi
+}
+
+# @FUNCTION: acct-group_src_install
+# @DESCRIPTION:
+# Installs sysusers.d file for the group.
+acct-group_src_install() {
+	debug-print-function ${FUNCNAME} "${@}"
+
+	# CrOS: We don't need this.
+}
+
+# @FUNCTION: acct-group_pkg_preinst
+# @DESCRIPTION:
+# Creates the group if it does not exist yet.
+acct-group_pkg_preinst() {
+	debug-print-function ${FUNCNAME} "${@}"
+
+	enewgroup "${ACCT_GROUP_NAME}"
+}
+
+fi
diff --git a/eclass/acct-user.eclass b/eclass/acct-user.eclass
new file mode 100644
index 0000000..d7c8045
--- /dev/null
+++ b/eclass/acct-user.eclass
@@ -0,0 +1,287 @@
+# Copyright 2019-2022 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+# @ECLASS: acct-user.eclass
+# @MAINTAINER:
+# Michał Górny <mgorny@gentoo.org>
+# Mike Gilbert <floppym@gentoo.org>
+# @AUTHOR:
+# Michael Orlitzky <mjo@gentoo.org>
+# Michał Górny <mgorny@gentoo.org>
+# @SUPPORTED_EAPIS: 7 8
+# @BLURB: Eclass used to create and maintain a single user entry
+# @DESCRIPTION:
+# This eclass represents and creates a single user entry.  The name
+# of the user is derived from ${PN}, while (preferred) UID needs to
+# be specified via ACCT_USER_ID.  Additional variables are provided
+# to override the default home directory, shell and add group
+# membership.  Packages needing the user in question should depend
+# on the package providing it.
+#
+# The ebuild needs to call acct-user_add_deps after specifying
+# ACCT_USER_GROUPS.
+#
+# Example:
+# If your package needs user 'foo' belonging to same-named group, you
+# create 'acct-user/foo' package and add an ebuild with the following
+# contents:
+#
+# @CODE
+# EAPI=8
+# inherit acct-user
+# ACCT_USER_ID=200
+# ACCT_USER_GROUPS=( foo )
+# acct-user_add_deps
+# @CODE
+#
+# Then you add appropriate dependencies to your package.  Note that
+# the build system might need to resolve names, too.  The dependency
+# type(s) should be: BDEPEND if the user must be resolvable at build
+# time (e.g. 'fowners' uses it in src_install), IDEPEND if it must be
+# resolvable at install time (e.g. 'fowners' uses it in pkg_preinst),
+# and RDEPEND in every case.
+
+if [[ -z ${_ACCT_USER_ECLASS} ]]; then
+_ACCT_USER_ECLASS=1
+
+case ${EAPI:-0} in
+	7|8) ;;
+	*) die "EAPI=${EAPI:-0} not supported";;
+esac
+
+inherit user user-info
+
+[[ ${CATEGORY} == acct-user ]] ||
+	die "Ebuild error: this eclass can be used only in acct-user category!"
+
+
+# << Eclass variables >>
+
+# @ECLASS_VARIABLE: ACCT_USER_NAME
+# @INTERNAL
+# @DESCRIPTION:
+# The name of the user.  This is forced to ${PN} and the policy prohibits
+# it from being changed.
+ACCT_USER_NAME=${PN}
+readonly ACCT_USER_NAME
+
+# @ECLASS_VARIABLE: ACCT_USER_ID
+# @REQUIRED
+# @DESCRIPTION:
+# Preferred UID for the new user.  This variable is obligatory, and its
+# value must be unique across all user packages.  This can be overriden
+# in make.conf through ACCT_USER_<UPPERCASE_USERNAME>_ID variable.
+#
+# Overlays should set this to -1 to dynamically allocate UID.  Using -1
+# in ::gentoo is prohibited by policy.
+
+# @ECLASS_VARIABLE: ACCT_USER_ENFORCE_ID
+# @DESCRIPTION:
+# If set to a non-null value, the eclass will require the user to have
+# specified UID.  If the user already exists with another UID, or
+# the UID is taken by another user, the install will fail.
+: ${ACCT_USER_ENFORCE_ID:=}
+
+# @ECLASS_VARIABLE: ACCT_USER_NO_MODIFY
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# If set to a non-null value, the eclass will not make any changes
+# to an already existing user.
+: ${ACCT_USER_NO_MODIFY:=}
+
+# @ECLASS_VARIABLE: ACCT_USER_COMMENT
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# The comment to use for the user.  If not specified, the package
+# DESCRIPTION will be used.  This can be overridden in make.conf through
+# ACCT_USER_<UPPERCASE_USERNAME>_COMMENT variable.
+
+# @ECLASS_VARIABLE: ACCT_USER_SHELL
+# @DESCRIPTION:
+# The shell to use for the user.  If not specified, a 'nologin' variant
+# for the system is used.  This can be overriden in make.conf through
+# ACCT_USER_<UPPERCASE_USERNAME>_SHELL variable.
+: ${ACCT_USER_SHELL:=/sbin/nologin}
+
+# @ECLASS_VARIABLE: ACCT_USER_HOME
+# @DESCRIPTION:
+# The home directory for the user.  If not specified, /dev/null is used.
+# The directory will be created with appropriate permissions if it does
+# not exist.  When updating, existing home directory will not be moved.
+# This can be overriden in make.conf through
+# ACCT_USER_<UPPERCASE_USERNAME>_HOME variable.
+: ${ACCT_USER_HOME:=/dev/null}
+
+# @ECLASS_VARIABLE: ACCT_USER_HOME_OWNER
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# The ownership to use for the home directory, in chown ([user][:group])
+# syntax.  Defaults to the newly created user, and its primary group.
+# This can be overriden in make.conf through
+# ACCT_USER_<UPPERCASE_USERNAME>_HOME_OWNER variable.
+
+# @ECLASS_VARIABLE: ACCT_USER_HOME_PERMS
+# @DESCRIPTION:
+# The permissions to use for the home directory, in chmod (octal
+# or verbose) form.  This can be overriden in make.conf through
+# ACCT_USER_<UPPERCASE_USERNAME>_HOME_PERMS variable.
+: ${ACCT_USER_HOME_PERMS:=0755}
+
+# @ECLASS_VARIABLE: ACCT_USER_GROUPS
+# @REQUIRED
+# @DESCRIPTION:
+# List of groups the user should belong to.  This must be a bash
+# array.  The first group specified is the user's primary group, while
+# the remaining groups (if any) become supplementary groups.
+#
+# This can be overriden in make.conf through
+# ACCT_USER_<UPPERCASE_USERNAME>_GROUPS variable, or appended to
+# via ACCT_USER_<UPPERCASE_USERNAME>_GROUPS_ADD.  Please note that
+# due to technical limitations, the override variables are not arrays
+# but space-separated lists.
+
+
+# << Boilerplate ebuild variables >>
+: ${DESCRIPTION:="System user: ${ACCT_USER_NAME}"}
+: ${SLOT:=0}
+: "${KEYWORDS:=*}"
+S=${WORKDIR}
+
+
+# << API functions >>
+
+# @FUNCTION: acct-user_add_deps
+# @DESCRIPTION:
+# Generate appropriate RDEPEND from ACCT_USER_GROUPS.  This must be
+# called if ACCT_USER_GROUPS are set.
+acct-user_add_deps() {
+	debug-print-function ${FUNCNAME} "${@}"
+
+	# ACCT_USER_GROUPS sanity check
+	if [[ $(declare -p ACCT_USER_GROUPS) != "declare -a"* ]]; then
+		die 'ACCT_USER_GROUPS must be an array.'
+	elif [[ ${#ACCT_USER_GROUPS[@]} -eq 0 ]]; then
+		die 'ACCT_USER_GROUPS must not be empty.'
+	fi
+
+	RDEPEND+=${ACCT_USER_GROUPS[*]/#/ acct-group/}
+	_ACCT_USER_ADD_DEPS_CALLED=1
+}
+
+
+# << Helper functions >>
+
+# @FUNCTION: eislocked
+# @USAGE: <user>
+# @INTERNAL
+# @DESCRIPTION:
+# Check whether the specified user account is currently locked.
+# Returns 0 if it is locked, 1 if it is not, 2 if the platform
+# does not support determining it.
+eislocked() {
+	[[ $# -eq 1 ]] || die "usage: ${FUNCNAME} <user>"
+
+	# Nothing uses this, so not clear we care.
+	die "Not implemented: please contact go/cros-build-help"
+}
+
+# << Phase functions >>
+# CrOS: Disable most functions since we don't use them in CrOS.
+EXPORT_FUNCTIONS pkg_pretend pkg_preinst
+
+# @FUNCTION: acct-user_pkg_pretend
+# @DESCRIPTION:
+# Performs sanity checks for correct eclass usage, and early-checks
+# whether requested UID can be enforced.
+acct-user_pkg_pretend() {
+	debug-print-function ${FUNCNAME} "${@}"
+
+	# verify that acct-user_add_deps() has been called
+	# (it verifies ACCT_USER_GROUPS itself)
+	if [[ -z ${_ACCT_USER_ADD_DEPS_CALLED} ]]; then
+		die "Ebuild error: acct-user_add_deps must have been called in global scope!"
+	fi
+
+	# verify ACCT_USER_ID
+	[[ -n ${ACCT_USER_ID} ]] || die "Ebuild error: ACCT_USER_ID must be set!"
+	[[ ${ACCT_USER_ID} -ge -1 ]] || die "Ebuild error: ACCT_USER_ID=${ACCT_USER_ID} invalid!"
+	local user_id=${ACCT_USER_ID}
+
+	# check for the override
+	local override_name=${ACCT_USER_NAME^^}
+	local override_var=ACCT_USER_${override_name//-/_}_ID
+	if [[ -n ${!override_var} ]]; then
+		user_id=${!override_var}
+		[[ ${user_id} -ge -1 ]] || die "${override_var}=${user_id} invalid!"
+	fi
+
+	# CrOS: We don't need this logic.
+	return
+
+	# check for ACCT_USER_ID collisions early
+	if [[ ${user_id} -ne -1 && -n ${ACCT_USER_ENFORCE_ID} ]]; then
+		local user_by_id=$(egetusername "${user_id}")
+		local user_by_name=$(egetent passwd "${ACCT_USER_NAME}")
+		if [[ -n ${user_by_id} ]]; then
+			if [[ ${user_by_id} != ${ACCT_USER_NAME} ]]; then
+				eerror "The required UID is already taken by another user."
+				eerror "  UID: ${user_id}"
+				eerror "  needed for: ${ACCT_USER_NAME}"
+				eerror "  current user: ${user_by_id}"
+				die "UID ${user_id} taken already"
+			fi
+		elif [[ -n ${user_by_name} ]]; then
+			eerror "The requested user exists already with wrong UID."
+			eerror "  username: ${ACCT_USER_NAME}"
+			eerror "  requested UID: ${user_id}"
+			eerror "  current entry: ${user_by_name}"
+			die "Username ${ACCT_USER_NAME} exists with wrong UID"
+		fi
+	fi
+}
+
+# @FUNCTION: acct-user_src_install
+# @DESCRIPTION:
+# Installs a keep-file into the user's home directory to ensure it is
+# owned by the package, and sysusers.d file.
+acct-user_src_install() {
+	debug-print-function ${FUNCNAME} "${@}"
+
+	# CrOS: We don't need this.
+}
+
+# @FUNCTION: acct-user_pkg_preinst
+# @DESCRIPTION:
+# Creates the user if it does not exist yet.  Sets permissions
+# of the home directory in install image.
+acct-user_pkg_preinst() {
+	debug-print-function ${FUNCNAME} "${@}"
+
+	enewuser "${ACCT_USER_NAME}"
+}
+
+# @FUNCTION: acct-user_pkg_postinst
+# @DESCRIPTION:
+# Updates user properties if necessary.  This needs to be done after
+# new home directory is installed.
+acct-user_pkg_postinst() {
+	debug-print-function ${FUNCNAME} "${@}"
+
+	# We don't care about deleting accounts in CrOS currently as images are
+	# created fresh everytime.  That might change in the future.
+}
+
+# @FUNCTION: acct-user_pkg_prerm
+# @DESCRIPTION:
+# Ensures that the user account is locked out when it is removed.
+acct-user_pkg_prerm() {
+	debug-print-function ${FUNCNAME} "${@}"
+
+	if [[ -n ${REPLACED_BY_VERSION} ]]; then
+		return
+	fi
+
+	# CrOS: We don't need this.
+}
+
+fi
diff --git a/eclass/app-alternatives.eclass b/eclass/app-alternatives.eclass
new file mode 100644
index 0000000..aa33d2d
--- /dev/null
+++ b/eclass/app-alternatives.eclass
@@ -0,0 +1,84 @@
+# Copyright 2022 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+# @ECLASS: app-alternatives.eclass
+# @MAINTAINER:
+# Michał Górny <mgorny@gentoo.org>
+# @AUTHOR:
+# Michał Górny <mgorny@gentoo.org>
+# @SUPPORTED_EAPIS: 7 8
+# @BLURB: Common logic for app-alternatives/*
+# @DESCRIPTION:
+# This eclass provides common logic shared by app-alternatives/*
+# ebuilds.  A global ALTERNATIVES variable needs to be declared
+# that lists available options and their respective dependencies.
+# HOMEPAGE, S, LICENSE, SLOT, IUSE, REQUIRED_USE and RDEPEND are set.
+# A get_alternative() function is provided that determines the selected
+# alternative and prints its respective flag name.
+
+case ${EAPI} in
+	7|8) ;;
+	*) die "${ECLASS}: EAPI ${EAPI:-0} unsupported."
+esac
+
+if [[ ! ${_APP_ALTERNATIVES_ECLASS} ]]; then
+_APP_ALTERNATIVES_ECLASS=1
+
+# @ECLASS_VARIABLE: ALTERNATIVES
+# @PRE_INHERIT
+# @REQUIRED
+# @DESCRIPTION:
+# Array of "flag:dependency" pairs specifying the available
+# alternatives.  The default provider must be listed first.
+
+# @FUNCTION: _app-alternatives_set_globals
+# @INTERNAL
+# @DESCRIPTION:
+# Set ebuild metadata variables.
+_app-alternatives_set_globals() {
+	debug-print-function ${FUNCNAME} "${@}"
+
+	if [[ ${ALTERNATIVES@a} != *a* ]]; then
+		die 'ALTERNATIVES must be an array.'
+	elif [[ ${#ALTERNATIVES[@]} -eq 0 ]]; then
+		die 'ALTERNATIVES must not be empty.'
+	fi
+
+	HOMEPAGE="https://wiki.gentoo.org/wiki/Project:Base/Alternatives"
+	S=${WORKDIR}
+
+	LICENSE="CC0-1.0"
+	SLOT="0"
+
+	# yep, that's a cheap hack adding '+' to the first flag
+	IUSE="+${ALTERNATIVES[*]%%:*}"
+	REQUIRED_USE="^^ ( ${ALTERNATIVES[*]%%:*} )"
+	RDEPEND=""
+
+	local flag dep
+	for flag in "${ALTERNATIVES[@]}"; do
+		[[ ${flag} != *:* ]] && die "Invalid ALTERNATIVES item: ${flag}"
+		dep=${flag#*:}
+		flag=${flag%%:*}
+		RDEPEND+="
+			${flag}? ( ${dep} )
+		"
+	done
+}
+_app-alternatives_set_globals
+
+# @FUNCTION: get_alternative
+# @DESCRIPTION:
+# Get the flag name for the selected alternative (i.e. the USE flag set).
+get_alternative() {
+	debug-print-function ${FUNCNAME} "${@}"
+
+	local flag
+	for flag in "${ALTERNATIVES[@]%%:*}"; do
+		usev "${flag}" && return
+	done
+
+	die "No selected alternative found (REQUIRED_USE ignored?!)"
+}
+
+fi
diff --git a/eclass/cros-constants.eclass b/eclass/cros-constants.eclass
index e734ebb..6a5e7b3 100644
--- a/eclass/cros-constants.eclass
+++ b/eclass/cros-constants.eclass
@@ -1,4 +1,4 @@
-# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Copyright 2013 The ChromiumOS Authors
 # Distributed under the terms of the GNU General Public License v2
 
 # @ECLASS: cros-constants.eclass
@@ -68,3 +68,7 @@
 # sysroot).
 ARC_ETC_DIR="/build/rootfs${ARC_PREFIX}/etc"
 
+# @ECLASS-VARIABLE: DEPOT_TOOLS
+# @DESCRIPTION:
+# In-chroot path to location of mounted depot_tools.
+DEPOT_TOOLS="/mnt/host/depot_tools"
diff --git a/eclass/font.eclass b/eclass/font.eclass
new file mode 100644
index 0000000..fab16f7
--- /dev/null
+++ b/eclass/font.eclass
@@ -0,0 +1,242 @@
+# Copyright 1999-2023 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+#
+# Chromium note: the Gentoo version of this eclass performs additional fc-cache
+# logic in pkg_postinst()/pkg_postrm(), to generate/clean cache files
+# respectively. We don't want to leave these cache files un-owned by packages,
+# and instead generate those caches in the chromeos-base/chromeos-fonts ebuild.
+# See also b/187790181.
+
+# @ECLASS: font.eclass
+# @MAINTAINER:
+# fonts@gentoo.org
+# @SUPPORTED_EAPIS: 7 8
+# @BLURB: Eclass to make font installation uniform
+
+case ${EAPI} in
+	7|8) ;;
+	*) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;;
+esac
+
+if [[ -z ${_FONT_ECLASS} ]]; then
+_FONT_ECLASS=1
+
+# @ECLASS_VARIABLE: FONT_SUFFIX
+# @DEFAULT_UNSET
+# @REQUIRED
+# @DESCRIPTION:
+# Space delimited list of font suffixes to install.
+FONT_SUFFIX=${FONT_SUFFIX:-}
+
+# @ECLASS_VARIABLE: FONT_S
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# Directory containing the fonts.  If unset, ${S} is used instead.
+# Can also be an array of several directories.
+
+# @ECLASS_VARIABLE: FONT_PN
+# @DESCRIPTION:
+# Font name (ie. last part of FONTDIR).
+FONT_PN=${FONT_PN:-${PN}}
+
+# @ECLASS_VARIABLE: FONTDIR
+# @DESCRIPTION:
+# Full path to installation directory.
+FONTDIR=${FONTDIR:-/usr/share/fonts/${FONT_PN}}
+
+# @ECLASS_VARIABLE: FONT_CONF
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# Array containing fontconfig conf files to install.
+FONT_CONF=( "" )
+
+# @ECLASS_VARIABLE: FONT_OPENTYPE_COMPAT
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# Determines whether detected BDF and PCF font files should be converted
+# to an SFNT wrapper, for use with newer Pango.
+
+if [[ ${CATEGORY}/${PN} != media-fonts/encodings ]]; then
+	IUSE="X"
+	BDEPEND="X? (
+			>=x11-apps/mkfontscale-1.2.0
+			media-fonts/encodings
+	)"
+fi
+
+if [[ -n ${FONT_OPENTYPE_COMPAT} ]] ; then
+	IUSE+=" +opentype-compat"
+	BDEPEND+=" opentype-compat? ( x11-apps/fonttosfnt )"
+fi
+
+# @FUNCTION: font_wrap_opentype_compat
+# @DESCRIPTION:
+# Converts .bdf and .pcf fonts detected within ${ED} to the OTB wrapper format
+# using x11-apps/fonttosfnt.  Handles optional .gz extension.
+font_wrap_opentype_compat() {
+	local file tmpfile
+
+	while IFS= read -rd '' file; do
+		if [[ ${file} == *.gz ]] ; then
+			tmpfile=${file%.*}
+
+			gzip -cd -- "${file}" > "${tmpfile}" \
+			&& fonttosfnt -v -o "${file%.*}.otb" -- "${tmpfile}" \
+			&& rm -- "${tmpfile}"
+		else
+			fonttosfnt -v -o "${file%.*}.otb" -- "${file}"
+		fi || ! break
+	done < <(find "${ED}" \( -name '*.bdf' -o -name '*.bdf.gz' -o -name '*.pcf' -o -name '*.pcf.gz' \) -type f ! -type l -print0) || die
+}
+
+# @FUNCTION: font_xfont_config
+# @DESCRIPTION:
+# Generate Xorg font files (mkfontscale/mkfontdir).
+font_xfont_config() {
+	local dir_name
+	if in_iuse X && use X ; then
+		dir_name="${1:-${FONT_PN}}"
+		rm -f "${ED}${FONTDIR}/${1//${S}/}"/{fonts.{dir,scale},encodings.dir} \
+			|| die "failed to prepare ${FONTDIR}/${1//${S}/}"
+		einfo "Creating fonts.scale & fonts.dir in ${dir_name##*/}"
+		mkfontscale "${ED}${FONTDIR}/${1//${S}/}" || eerror "failed to create fonts.scale"
+		mkfontdir \
+			-e "${EPREFIX}"/usr/share/fonts/encodings \
+			-e "${EPREFIX}"/usr/share/fonts/encodings/large \
+			"${ED}${FONTDIR}/${1//${S}/}" || eerror "failed to create fonts.dir"
+		[[ -e fonts.alias ]] && doins fonts.alias
+	fi
+}
+
+# @FUNCTION: font_fontconfig
+# @DESCRIPTION:
+# Install fontconfig conf files given in FONT_CONF.
+font_fontconfig() {
+	local conffile
+	if [[ -n ${FONT_CONF[@]} ]]; then
+		insinto /etc/fonts/conf.avail/
+		for conffile in "${FONT_CONF[@]}"; do
+			[[ -e ${conffile} ]] && doins "${conffile}"
+		done
+	fi
+}
+
+# @FUNCTION: font_cleanup_dirs
+# @DESCRIPTION:
+# Remove font directories containing only generated files.
+font_cleanup_dirs() {
+	local genfiles="encodings.dir fonts.alias fonts.cache-1 fonts.dir fonts.scale"
+	# fonts.alias isn't generated but it's a special case (see below).
+	local d f g generated candidate otherfile
+
+	ebegin "Cleaning up font directories"
+	while read -d $'\0' -r; do
+		candidate=false
+		otherfile=false
+		for f in "${d}"/*; do
+			generated=false
+			# make sure this is a file and not a subdir
+			[[ -e ${f} || -L ${f} ]] || continue
+			if has ${f##*/} ${genfiles}; then
+				# this is a generated file
+				generated=true
+				break
+			fi
+			# if the file is a generated file then we know this is a font dir (as
+			# opposed to something like encodings or util) and a candidate for
+			# removal.  if it's not generated then it's an "otherfile".
+			${generated} && candidate=true || otherfile=true
+			# if the directory is both a candidate for removal and contains at
+			# least one "otherfile" then don't remove it.
+			[[ ${candidate} == ${otherfile} ]] && break
+		done
+		# if in the end we only have generated files, purge the directory.
+		if [[ ${candidate} == true && ${otherfile} == false ]]; then
+			# we don't want to remove fonts.alias files that were installed by
+			# media-fonts/font-alias. any other fonts.alias files will have
+			# already been unmerged with their packages.
+			for g in ${genfiles}; do
+				if [[ ${g} != fonts.alias && ( -e ${d}/${g} || -L ${d}/${g} ) ]] ; then
+					rm "${d}"/${g} || eerror "failed to remove ${d}/${g}"
+				fi
+			done
+			# if there's nothing left remove the directory
+			find "${d}" -maxdepth 0 -type d -empty -delete || eerror "failed to purge ${d}"
+		fi
+	done < <(find -L "${EROOT}"/usr/share/fonts/ -type d -print0)
+	eend 0
+}
+
+# @FUNCTION: font_pkg_setup
+# @DESCRIPTION:
+# The font pkg_setup function.
+# Collision protection
+font_pkg_setup() {
+	# make sure we get no collisions
+	# setup is not the nicest place, but preinst doesn't cut it
+	if [[ -e "${EROOT}${FONTDIR}/fonts.cache-1" ]] ; then
+		rm "${EROOT}${FONTDIR}/fonts.cache-1" || die "failed to remove fonts.cache-1"
+	fi
+}
+
+# @FUNCTION: font_src_install
+# @DESCRIPTION:
+# The font src_install function.
+font_src_install() {
+	local dir suffix commondoc
+
+	if [[ -n ${FONT_OPENTYPE_COMPAT} ]] && in_iuse opentype-compat && use opentype-compat ; then
+		font_wrap_opentype_compat
+	fi
+
+	if [[ $(declare -p FONT_S 2>/dev/null) == "declare -a"* ]]; then
+		# recreate the directory structure if FONT_S is an array
+		for dir in "${FONT_S[@]}"; do
+			pushd "${dir}" > /dev/null || die "pushd ${dir} failed"
+			insinto "${FONTDIR}/${dir#"${S}"}"
+			for suffix in ${FONT_SUFFIX}; do
+				doins *.${suffix}
+			done
+			font_xfont_config "${dir}"
+			popd > /dev/null || die
+		done
+	else
+		pushd "${FONT_S:-${S}}" > /dev/null \
+			|| die "pushd ${FONT_S:-${S}} failed"
+		insinto "${FONTDIR}"
+		for suffix in ${FONT_SUFFIX}; do
+			doins *.${suffix}
+		done
+		font_xfont_config
+		popd > /dev/null || die
+	fi
+
+	font_fontconfig
+
+	einstalldocs
+
+	# install common docs
+	for commondoc in COPYRIGHT FONTLOG.txt; do
+		[[ -s ${commondoc} ]] && dodoc ${commondoc}
+	done
+}
+
+# @FUNCTION: font_pkg_postinst
+# @DESCRIPTION:
+# The font pkg_postinst function.
+# We've stubbed this out (see Chromium notes above) but leave its identifier,
+# so portage-stable ebuilds can still refer to it.
+font_pkg_postinst() {
+	:
+}
+
+# @FUNCTION: font_pkg_postrm
+# @DESCRIPTION:
+# The font pkg_postrm function.
+font_pkg_postrm() {
+	font_cleanup_dirs
+}
+
+fi
+
+EXPORT_FUNCTIONS pkg_setup src_install pkg_postinst pkg_postrm
diff --git a/eclass/python-utils-r1.eclass b/eclass/python-utils-r1.eclass
index c494e49..01836a6 100644
--- a/eclass/python-utils-r1.eclass
+++ b/eclass/python-utils-r1.eclass
@@ -40,8 +40,7 @@
 # All supported Python implementations, most preferred last.
 _PYTHON_ALL_IMPLS=(
 	pypy3
-	python2_7
-	python3_6 python3_7 python3_9 python3_8
+	python3_{19..6}
 )
 readonly _PYTHON_ALL_IMPLS
 
@@ -77,12 +76,9 @@
 	# keep in sync with _PYTHON_ALL_IMPLS!
 	# (not using that list because inline patterns shall be faster)
 	case "${impl}" in
-		python2_7|python3_[6789]|pypy3)
+		python3_[6-9]|python3_1[0-9]|pypy3)
 			return 0
 			;;
-		jython2_7|pypy|pypy1_[89]|pypy2_0|python2_[56]|python3_[12345])
-			return 1
-			;;
 		*)
 			[[ ${PYTHON_COMPAT_NO_STRICT} ]] && return 1
 			die "Invalid implementation in PYTHON_COMPAT: ${impl}"
@@ -1433,5 +1429,37 @@
 	die "${FUNCNAME}() is invalid for python-r1 suite"
 }
 
+# @FUNCTION: python_has_version
+# @USAGE: [-b|-d|-r] <atom>...
+# @DESCRIPTION:
+# A convenience wrapper for has_version() with verbose output and better
+# defaults for use in python_check_deps().
+#
+# The wrapper accepts -b/-d/-r options to indicate the root to perform
+# the lookup on.  Unlike has_version, the default is -b.
+#
+# The wrapper accepts multiple package specifications.  For the check
+# to succeed, *all* specified atoms must match.
+python_has_version() {
+	debug-print-function ${FUNCNAME} "${@}"
+
+	local root_arg=( -b )
+	case ${1} in
+		-b|-d|-r)
+			root_arg=( "${1}" )
+			shift
+			;;
+	esac
+
+	local pkg
+	for pkg; do
+		ebegin "    ${pkg}"
+		has_version "${root_arg[@]}" "${pkg}"
+		eend ${?} || return
+	done
+
+	return 0
+}
+
 _PYTHON_UTILS_R1=1
 fi
diff --git a/eclass/user-info.eclass b/eclass/user-info.eclass
new file mode 100644
index 0000000..d6fc4fe
--- /dev/null
+++ b/eclass/user-info.eclass
@@ -0,0 +1,115 @@
+# Copyright 1999-2022 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+# @ECLASS: user-info.eclass
+# @MAINTAINER:
+# base-system@gentoo.org (Linux)
+# Michał Górny <mgorny@gentoo.org> (NetBSD)
+# @SUPPORTED_EAPIS: 6 7 8
+# @BLURB: Read-only access to user and group information
+
+case ${EAPI} in
+	6|7|8) ;;
+	*) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;;
+esac
+
+if [[ -z ${_USER_INFO_ECLASS} ]]; then
+_USER_INFO_ECLASS=1
+
+# TODO(b/187790077): Move user eclass APIs here that align w/Gentoo.
+inherit user
+
+# @FUNCTION: egetusername
+# @USAGE: <uid>
+# @DESCRIPTION:
+# Gets the username for given UID.
+egetusername() {
+	[[ $# -eq 1 ]] || die "usage: egetusername <uid>"
+
+	egetent passwd "$1" | cut -d: -f1
+}
+
+# @FUNCTION: egetgroupname
+# @USAGE: <gid>
+# @DESCRIPTION:
+# Gets the group name for given GID.
+egetgroupname() {
+	[[ $# -eq 1 ]] || die "usage: egetgroupname <gid>"
+
+	egetent group "$1" | cut -d: -f1
+}
+
+# @FUNCTION: egethome
+# @USAGE: <user>
+# @DESCRIPTION:
+# Gets the home directory for the specified user.
+egethome() {
+	local pos
+
+	[[ $# -eq 1 ]] || die "usage: egethome <user>"
+
+	case ${CHOST} in
+	*-freebsd*|*-dragonfly*)
+		pos=9
+		;;
+	*)	# Linux, NetBSD, OpenBSD, etc...
+		pos=6
+		;;
+	esac
+
+	egetent passwd "$1" | cut -d: -f${pos}
+}
+
+# @FUNCTION: egetshell
+# @USAGE: <user>
+# @DESCRIPTION:
+# Gets the shell for the specified user.
+egetshell() {
+	local pos
+
+	[[ $# -eq 1 ]] || die "usage: egetshell <user>"
+
+	case ${CHOST} in
+	*-freebsd*|*-dragonfly*)
+		pos=10
+		;;
+	*)	# Linux, NetBSD, OpenBSD, etc...
+		pos=7
+		;;
+	esac
+
+	egetent passwd "$1" | cut -d: -f${pos}
+}
+
+# @FUNCTION: egetcomment
+# @USAGE: <user>
+# @DESCRIPTION:
+# Gets the comment field for the specified user.
+egetcomment() {
+	local pos
+
+	[[ $# -eq 1 ]] || die "usage: egetcomment <user>"
+
+	case ${CHOST} in
+	*-freebsd*|*-dragonfly*)
+		pos=8
+		;;
+	*)	# Linux, NetBSD, OpenBSD, etc...
+		pos=5
+		;;
+	esac
+
+	egetent passwd "$1" | cut -d: -f${pos}
+}
+
+# @FUNCTION: egetgroups
+# @USAGE: <user>
+# @DESCRIPTION:
+# Gets all the groups user belongs to.  The primary group is returned
+# first, then all supplementary groups.  Groups are ','-separated.
+egetgroups() {
+	# Nothing uses this, so not clear we care.
+	die "Not implemented: please contact go/cros-build-help"
+}
+
+fi
diff --git a/eclass/user.eclass b/eclass/user.eclass
index 0837b1f..237acfb 100644
--- a/eclass/user.eclass
+++ b/eclass/user.eclass
@@ -1,16 +1,24 @@
-# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Copyright 2013 The ChromiumOS Authors
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 # @ECLASS: user.eclass
 # @MAINTAINER:
-# The Chromium OS Authors. <chromium-os-dev@chromium.org>
+# The ChromiumOS Authors <chromium-os-dev@chromium.org>
 # @BLURB: user management in ebuilds
 # @DESCRIPTION:
 # Replaces the upstream mechanism of managing users and groups with one that
 # manages the database in ${ROOT}, changing the sysroot database
 # only when the caller creates the user/group during setup.
 
+case ${EAPI} in
+5|6|7|8) ;;
+*) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;;
+esac
+
+if [[ -z ${_USER_ECLASS} ]]; then
+_USER_ECLASS=1
+
 # Before we manipulate users at all, we want to make sure that
 # passwd/group/shadow is initialized in the first place. That's
 # what baselayout does.
@@ -635,20 +643,4 @@
 	einfo "Done with group: '${egroup}'."
 }
 
-# @FUNCTION: egethome
-# @USAGE: <user>
-# @DESCRIPTION:
-# Gets the home directory for the specified user.
-egethome() {
-	[[ $# -eq 1 ]] || die "usage: egethome <user>"
-	egetent passwd "$1" | cut -d: -f6
-}
-
-# @FUNCTION: egetshell
-# @USAGE: <user>
-# @DESCRIPTION:
-# Gets the shell for the specified user.
-egetshell() {
-	[[ $# -eq 1 ]] || die "usage: egetshell <user>"
-	egetent passwd "$1" | cut -d: -f7
-}
+fi
diff --git a/metadata/OWNERS b/metadata/OWNERS
index 6bc6027..f6773ed 100644
--- a/metadata/OWNERS
+++ b/metadata/OWNERS
@@ -1,2 +1,2 @@
 # Bot that commits cache updates.
-chromeos-ci-prod@chromeos-bot.iam.gserviceaccount.com
+include chromiumos/owners:v1:/bots/OWNERS.metadata_cache
diff --git a/metadata/md5-cache/OWNERS b/metadata/md5-cache/OWNERS
new file mode 100644
index 0000000..1ae1238
--- /dev/null
+++ b/metadata/md5-cache/OWNERS
@@ -0,0 +1,2 @@
+# Contents in here are generated.
+*
diff --git a/metadata/md5-cache/acct-group/audio-0-r1 b/metadata/md5-cache/acct-group/audio-0-r1
new file mode 100644
index 0000000..683bb29
--- /dev/null
+++ b/metadata/md5-cache/acct-group/audio-0-r1
@@ -0,0 +1,9 @@
+DEFINED_PHASES=preinst pretend
+DEPEND=sys-apps/baselayout
+DESCRIPTION=System group: audio
+EAPI=7
+KEYWORDS=*
+RDEPEND=sys-apps/baselayout
+SLOT=0
+_eclasses_=acct-group	9c40b46ef2ec0290011028153e75287e	user	4e2ffee100481639425c80355dd60c7b	user-info	23cfd192154f4aeac3a0cff98113134e
+_md5_=3e8495e7dda7e82fb24d3085b5d5b043
diff --git a/metadata/md5-cache/acct-group/cdrom-0-r1 b/metadata/md5-cache/acct-group/cdrom-0-r1
new file mode 100644
index 0000000..8295801
--- /dev/null
+++ b/metadata/md5-cache/acct-group/cdrom-0-r1
@@ -0,0 +1,9 @@
+DEFINED_PHASES=preinst pretend
+DEPEND=sys-apps/baselayout
+DESCRIPTION=System group: cdrom
+EAPI=7
+KEYWORDS=*
+RDEPEND=sys-apps/baselayout
+SLOT=0
+_eclasses_=acct-group	9c40b46ef2ec0290011028153e75287e	user	4e2ffee100481639425c80355dd60c7b	user-info	23cfd192154f4aeac3a0cff98113134e
+_md5_=6220758de6cdd6054db6004a785f19aa
diff --git a/metadata/md5-cache/acct-group/chronos-0.0.1 b/metadata/md5-cache/acct-group/chronos-0.0.1
new file mode 100644
index 0000000..815f6e3
--- /dev/null
+++ b/metadata/md5-cache/acct-group/chronos-0.0.1
@@ -0,0 +1,9 @@
+DEFINED_PHASES=preinst pretend
+DEPEND=sys-apps/baselayout
+DESCRIPTION=System group: chronos
+EAPI=7
+KEYWORDS=*
+RDEPEND=sys-apps/baselayout
+SLOT=0
+_eclasses_=acct-group	9c40b46ef2ec0290011028153e75287e	user	4e2ffee100481639425c80355dd60c7b	user-info	23cfd192154f4aeac3a0cff98113134e
+_md5_=cc7499ca763fac9b2a949d5095323001
diff --git a/metadata/md5-cache/acct-group/cros_healthd-0.0.1 b/metadata/md5-cache/acct-group/cros_healthd-0.0.1
new file mode 100644
index 0000000..1a48ce5
--- /dev/null
+++ b/metadata/md5-cache/acct-group/cros_healthd-0.0.1
@@ -0,0 +1,9 @@
+DEFINED_PHASES=preinst pretend
+DEPEND=sys-apps/baselayout
+DESCRIPTION=System group: cros_healthd
+EAPI=7
+KEYWORDS=*
+RDEPEND=sys-apps/baselayout
+SLOT=0
+_eclasses_=acct-group	9c40b46ef2ec0290011028153e75287e	user	4e2ffee100481639425c80355dd60c7b	user-info	23cfd192154f4aeac3a0cff98113134e
+_md5_=ec7200a51c61c0129ac3d2009fac2a3d
diff --git a/metadata/md5-cache/acct-group/dhcp-0-r1 b/metadata/md5-cache/acct-group/dhcp-0-r1
new file mode 100644
index 0000000..df7e9a4
--- /dev/null
+++ b/metadata/md5-cache/acct-group/dhcp-0-r1
@@ -0,0 +1,9 @@
+DEFINED_PHASES=preinst pretend
+DEPEND=sys-apps/baselayout
+DESCRIPTION=System group: dhcp
+EAPI=7
+KEYWORDS=*
+RDEPEND=sys-apps/baselayout
+SLOT=0
+_eclasses_=acct-group	9c40b46ef2ec0290011028153e75287e	user	4e2ffee100481639425c80355dd60c7b	user-info	23cfd192154f4aeac3a0cff98113134e
+_md5_=a5b3357b396326f7db8c294bb55251fe
diff --git a/metadata/md5-cache/acct-group/dialout-0-r1 b/metadata/md5-cache/acct-group/dialout-0-r1
new file mode 100644
index 0000000..8389b6c
--- /dev/null
+++ b/metadata/md5-cache/acct-group/dialout-0-r1
@@ -0,0 +1,9 @@
+DEFINED_PHASES=preinst pretend
+DEPEND=sys-apps/baselayout
+DESCRIPTION=System group: dialout
+EAPI=7
+KEYWORDS=*
+RDEPEND=sys-apps/baselayout
+SLOT=0
+_eclasses_=acct-group	9c40b46ef2ec0290011028153e75287e	user	4e2ffee100481639425c80355dd60c7b	user-info	23cfd192154f4aeac3a0cff98113134e
+_md5_=91d0f007ab5cd5fbc52b3563502b37f2
diff --git a/metadata/md5-cache/acct-group/disk-0-r1 b/metadata/md5-cache/acct-group/disk-0-r1
new file mode 100644
index 0000000..7b9cd9f
--- /dev/null
+++ b/metadata/md5-cache/acct-group/disk-0-r1
@@ -0,0 +1,9 @@
+DEFINED_PHASES=preinst pretend
+DEPEND=sys-apps/baselayout
+DESCRIPTION=System group: disk
+EAPI=7
+KEYWORDS=*
+RDEPEND=sys-apps/baselayout
+SLOT=0
+_eclasses_=acct-group	9c40b46ef2ec0290011028153e75287e	user	4e2ffee100481639425c80355dd60c7b	user-info	23cfd192154f4aeac3a0cff98113134e
+_md5_=86dc41cb27e6be3cdbb56143bf74d9a5
diff --git a/metadata/md5-cache/acct-group/docker-0.0.1 b/metadata/md5-cache/acct-group/docker-0.0.1
index 4187ddc..2e5cf33 100644
--- a/metadata/md5-cache/acct-group/docker-0.0.1
+++ b/metadata/md5-cache/acct-group/docker-0.0.1
@@ -4,5 +4,5 @@
 KEYWORDS=*
 RDEPEND=sys-apps/baselayout
 SLOT=0
-_eclasses_=user	7c566af8c48023219fd63246e88d6621
-_md5_=f5cb9ce94ff461698f8f10576cec2cec
+_eclasses_=user	4e2ffee100481639425c80355dd60c7b
+_md5_=593868c358bec130a18934124524f004
diff --git a/metadata/md5-cache/acct-group/fwupd-0.0.1 b/metadata/md5-cache/acct-group/fwupd-0.0.1
new file mode 100644
index 0000000..c0579dd
--- /dev/null
+++ b/metadata/md5-cache/acct-group/fwupd-0.0.1
@@ -0,0 +1,9 @@
+DEFINED_PHASES=preinst pretend
+DEPEND=sys-apps/baselayout
+DESCRIPTION=System group: fwupd
+EAPI=7
+KEYWORDS=*
+RDEPEND=sys-apps/baselayout
+SLOT=0
+_eclasses_=acct-group	9c40b46ef2ec0290011028153e75287e	user	4e2ffee100481639425c80355dd60c7b	user-info	23cfd192154f4aeac3a0cff98113134e
+_md5_=095ff06fc4bddb17d63bb3ca156f3101
diff --git a/metadata/md5-cache/acct-group/input-0-r1 b/metadata/md5-cache/acct-group/input-0-r1
new file mode 100644
index 0000000..0c4e5b3
--- /dev/null
+++ b/metadata/md5-cache/acct-group/input-0-r1
@@ -0,0 +1,9 @@
+DEFINED_PHASES=preinst pretend
+DEPEND=sys-apps/baselayout
+DESCRIPTION=System group: input
+EAPI=7
+KEYWORDS=*
+RDEPEND=sys-apps/baselayout
+SLOT=0
+_eclasses_=acct-group	9c40b46ef2ec0290011028153e75287e	user	4e2ffee100481639425c80355dd60c7b	user-info	23cfd192154f4aeac3a0cff98113134e
+_md5_=98a31fab0bb705f662da004d6af750e4
diff --git a/metadata/md5-cache/acct-group/kmem-0-r1 b/metadata/md5-cache/acct-group/kmem-0-r1
new file mode 100644
index 0000000..7dc5e20
--- /dev/null
+++ b/metadata/md5-cache/acct-group/kmem-0-r1
@@ -0,0 +1,9 @@
+DEFINED_PHASES=preinst pretend
+DEPEND=sys-apps/baselayout
+DESCRIPTION=System group: kmem
+EAPI=7
+KEYWORDS=*
+RDEPEND=sys-apps/baselayout
+SLOT=0
+_eclasses_=acct-group	9c40b46ef2ec0290011028153e75287e	user	4e2ffee100481639425c80355dd60c7b	user-info	23cfd192154f4aeac3a0cff98113134e
+_md5_=fe0ca6a296e1cd2a7cc95b45e44992be
diff --git a/metadata/md5-cache/acct-group/kvm-0.0.1 b/metadata/md5-cache/acct-group/kvm-0.0.1
index ecbf62b..09f1b21 100644
--- a/metadata/md5-cache/acct-group/kvm-0.0.1
+++ b/metadata/md5-cache/acct-group/kvm-0.0.1
@@ -4,5 +4,5 @@
 KEYWORDS=*
 RDEPEND=sys-apps/baselayout
 SLOT=0
-_eclasses_=user	7c566af8c48023219fd63246e88d6621
-_md5_=f52112fdb0f2ab3584c95f147a1e2b24
+_eclasses_=user	4e2ffee100481639425c80355dd60c7b
+_md5_=0d4fd8837641f5a577cbf103cc8b47cb
diff --git a/metadata/md5-cache/acct-group/lp-0-r1 b/metadata/md5-cache/acct-group/lp-0-r1
new file mode 100644
index 0000000..03c4935
--- /dev/null
+++ b/metadata/md5-cache/acct-group/lp-0-r1
@@ -0,0 +1,9 @@
+DEFINED_PHASES=preinst pretend
+DEPEND=sys-apps/baselayout
+DESCRIPTION=System group: lp
+EAPI=7
+KEYWORDS=*
+RDEPEND=sys-apps/baselayout
+SLOT=0
+_eclasses_=acct-group	9c40b46ef2ec0290011028153e75287e	user	4e2ffee100481639425c80355dd60c7b	user-info	23cfd192154f4aeac3a0cff98113134e
+_md5_=34e277522a71e44dc5019512cda7a94d
diff --git a/metadata/md5-cache/acct-group/node_exporter-0.0.1 b/metadata/md5-cache/acct-group/node_exporter-0.0.1
new file mode 100644
index 0000000..b41e11e
--- /dev/null
+++ b/metadata/md5-cache/acct-group/node_exporter-0.0.1
@@ -0,0 +1,9 @@
+DEFINED_PHASES=preinst pretend
+DEPEND=sys-apps/baselayout
+DESCRIPTION=System group: node_exporter
+EAPI=7
+KEYWORDS=*
+RDEPEND=sys-apps/baselayout
+SLOT=0
+_eclasses_=acct-group	9c40b46ef2ec0290011028153e75287e	user	4e2ffee100481639425c80355dd60c7b	user-info	23cfd192154f4aeac3a0cff98113134e
+_md5_=5e5260607d9dbccd232a1400c9346be3
diff --git a/metadata/md5-cache/acct-group/openvpn-0-r1 b/metadata/md5-cache/acct-group/openvpn-0-r1
new file mode 100644
index 0000000..eddee3c
--- /dev/null
+++ b/metadata/md5-cache/acct-group/openvpn-0-r1
@@ -0,0 +1,9 @@
+DEFINED_PHASES=preinst pretend
+DEPEND=sys-apps/baselayout
+DESCRIPTION=System group: openvpn
+EAPI=7
+KEYWORDS=*
+RDEPEND=sys-apps/baselayout
+SLOT=0
+_eclasses_=acct-group	9c40b46ef2ec0290011028153e75287e	user	4e2ffee100481639425c80355dd60c7b	user-info	23cfd192154f4aeac3a0cff98113134e
+_md5_=54a060154a0e6cf7e576e88dd46e80c3
diff --git a/metadata/md5-cache/acct-group/plugdev-0.0.1 b/metadata/md5-cache/acct-group/plugdev-0.0.1
index 0c72174..bf5d2cb 100644
--- a/metadata/md5-cache/acct-group/plugdev-0.0.1
+++ b/metadata/md5-cache/acct-group/plugdev-0.0.1
@@ -2,8 +2,7 @@
 DEPEND=sys-apps/baselayout
 EAPI=7
 KEYWORDS=*
-LICENSE=GPL-2
 RDEPEND=sys-apps/baselayout
 SLOT=0
-_eclasses_=user	7c566af8c48023219fd63246e88d6621
-_md5_=266cc3d9228ef3caec94da5d574b302c
+_eclasses_=user	4e2ffee100481639425c80355dd60c7b
+_md5_=614aaae07bcfd31cc83447a068c47c9d
diff --git a/metadata/md5-cache/acct-group/sshd-0-r1 b/metadata/md5-cache/acct-group/sshd-0-r1
new file mode 100644
index 0000000..caf6fc1
--- /dev/null
+++ b/metadata/md5-cache/acct-group/sshd-0-r1
@@ -0,0 +1,9 @@
+DEFINED_PHASES=preinst pretend
+DEPEND=sys-apps/baselayout
+DESCRIPTION=System group: sshd
+EAPI=7
+KEYWORDS=*
+RDEPEND=sys-apps/baselayout
+SLOT=0
+_eclasses_=acct-group	9c40b46ef2ec0290011028153e75287e	user	4e2ffee100481639425c80355dd60c7b	user-info	23cfd192154f4aeac3a0cff98113134e
+_md5_=7a346fd53d47d4c394a6319ec92e3579
diff --git a/metadata/md5-cache/acct-group/sshd-0.0.1 b/metadata/md5-cache/acct-group/sshd-0.0.1
deleted file mode 100644
index 9d81ae6..0000000
--- a/metadata/md5-cache/acct-group/sshd-0.0.1
+++ /dev/null
@@ -1,8 +0,0 @@
-DEFINED_PHASES=setup
-DEPEND=sys-apps/baselayout
-EAPI=7
-KEYWORDS=*
-RDEPEND=sys-apps/baselayout
-SLOT=0
-_eclasses_=user	7c566af8c48023219fd63246e88d6621
-_md5_=3e2179fc58433049b2d6cd269ab8a799
diff --git a/metadata/md5-cache/acct-group/tape-0-r1 b/metadata/md5-cache/acct-group/tape-0-r1
new file mode 100644
index 0000000..a53218a
--- /dev/null
+++ b/metadata/md5-cache/acct-group/tape-0-r1
@@ -0,0 +1,9 @@
+DEFINED_PHASES=preinst pretend
+DEPEND=sys-apps/baselayout
+DESCRIPTION=System group: tape
+EAPI=7
+KEYWORDS=*
+RDEPEND=sys-apps/baselayout
+SLOT=0
+_eclasses_=acct-group	9c40b46ef2ec0290011028153e75287e	user	4e2ffee100481639425c80355dd60c7b	user-info	23cfd192154f4aeac3a0cff98113134e
+_md5_=86242ad94ac294b6bf673f2091c83e5a
diff --git a/metadata/md5-cache/acct-group/tty-0-r1 b/metadata/md5-cache/acct-group/tty-0-r1
new file mode 100644
index 0000000..270286a
--- /dev/null
+++ b/metadata/md5-cache/acct-group/tty-0-r1
@@ -0,0 +1,9 @@
+DEFINED_PHASES=preinst pretend
+DEPEND=sys-apps/baselayout
+DESCRIPTION=System group: tty
+EAPI=7
+KEYWORDS=*
+RDEPEND=sys-apps/baselayout
+SLOT=0
+_eclasses_=acct-group	9c40b46ef2ec0290011028153e75287e	user	4e2ffee100481639425c80355dd60c7b	user-info	23cfd192154f4aeac3a0cff98113134e
+_md5_=27b44f68d2a4849fe618b62c8a51f543
diff --git a/metadata/md5-cache/acct-group/video-0-r1 b/metadata/md5-cache/acct-group/video-0-r1
new file mode 100644
index 0000000..28734e0
--- /dev/null
+++ b/metadata/md5-cache/acct-group/video-0-r1
@@ -0,0 +1,9 @@
+DEFINED_PHASES=preinst pretend
+DEPEND=sys-apps/baselayout
+DESCRIPTION=System group: video
+EAPI=7
+KEYWORDS=*
+RDEPEND=sys-apps/baselayout
+SLOT=0
+_eclasses_=acct-group	9c40b46ef2ec0290011028153e75287e	user	4e2ffee100481639425c80355dd60c7b	user-info	23cfd192154f4aeac3a0cff98113134e
+_md5_=4b2e9a61d260463a29582ee18c48e1c5
diff --git a/metadata/md5-cache/acct-user/chronos-0.0.2 b/metadata/md5-cache/acct-user/chronos-0.0.2
new file mode 100644
index 0000000..eab399f
--- /dev/null
+++ b/metadata/md5-cache/acct-user/chronos-0.0.2
@@ -0,0 +1,9 @@
+DEFINED_PHASES=preinst pretend
+DEPEND=app-shells/bash sys-apps/baselayout
+DESCRIPTION=The user that all user-facing processes will run as
+EAPI=7
+KEYWORDS=*
+RDEPEND=app-shells/bash sys-apps/baselayout
+SLOT=0
+_eclasses_=acct-user	8947f6cba2bec018df20b595d4f12cb2	user	4e2ffee100481639425c80355dd60c7b	user-info	23cfd192154f4aeac3a0cff98113134e
+_md5_=905d751bfee2f9ef0b5ea2a16e18ef71
diff --git a/metadata/md5-cache/acct-user/cros_healthd-0.0.1 b/metadata/md5-cache/acct-user/cros_healthd-0.0.1
new file mode 100644
index 0000000..f198988
--- /dev/null
+++ b/metadata/md5-cache/acct-user/cros_healthd-0.0.1
@@ -0,0 +1,9 @@
+DEFINED_PHASES=preinst pretend
+DEPEND=sys-apps/baselayout
+DESCRIPTION=User for diagnostics and telemetry services
+EAPI=7
+KEYWORDS=*
+RDEPEND=sys-apps/baselayout
+SLOT=0
+_eclasses_=acct-user	8947f6cba2bec018df20b595d4f12cb2	user	4e2ffee100481639425c80355dd60c7b	user-info	23cfd192154f4aeac3a0cff98113134e
+_md5_=01687cece736ea893139a51dc2c72724
diff --git a/metadata/md5-cache/acct-user/dhcp-0-r1 b/metadata/md5-cache/acct-user/dhcp-0-r1
new file mode 100644
index 0000000..8051807
--- /dev/null
+++ b/metadata/md5-cache/acct-user/dhcp-0-r1
@@ -0,0 +1,9 @@
+DEFINED_PHASES=preinst pretend
+DEPEND=sys-apps/baselayout
+DESCRIPTION=user for dhcp daemon
+EAPI=7
+KEYWORDS=*
+RDEPEND=acct-group/dhcp sys-apps/baselayout
+SLOT=0
+_eclasses_=acct-user	8947f6cba2bec018df20b595d4f12cb2	user	4e2ffee100481639425c80355dd60c7b	user-info	23cfd192154f4aeac3a0cff98113134e
+_md5_=99676fd2e887a56cb54e592ffc4581ba
diff --git a/metadata/md5-cache/acct-user/fwupd-0.0.1 b/metadata/md5-cache/acct-user/fwupd-0.0.1
new file mode 100644
index 0000000..5870e5e
--- /dev/null
+++ b/metadata/md5-cache/acct-user/fwupd-0.0.1
@@ -0,0 +1,9 @@
+DEFINED_PHASES=preinst pretend
+DEPEND=sys-apps/baselayout
+DESCRIPTION=User for fwupd
+EAPI=7
+KEYWORDS=*
+RDEPEND=sys-apps/baselayout
+SLOT=0
+_eclasses_=acct-user	8947f6cba2bec018df20b595d4f12cb2	user	4e2ffee100481639425c80355dd60c7b	user-info	23cfd192154f4aeac3a0cff98113134e
+_md5_=75c0231acea98bbec472a8efda913d59
diff --git a/metadata/md5-cache/acct-user/gpsd-0.0.1 b/metadata/md5-cache/acct-user/gpsd-0.0.1
index b6d2872..9f227da 100644
--- a/metadata/md5-cache/acct-user/gpsd-0.0.1
+++ b/metadata/md5-cache/acct-user/gpsd-0.0.1
@@ -2,8 +2,7 @@
 DEPEND=sys-apps/baselayout
 EAPI=7
 KEYWORDS=*
-LICENSE=BSD-Google
 RDEPEND=sys-apps/baselayout
 SLOT=0
-_eclasses_=user	7c566af8c48023219fd63246e88d6621
-_md5_=326343dd19c21084018a9b870374ba3c
+_eclasses_=user	4e2ffee100481639425c80355dd60c7b
+_md5_=3ea54ad7f5b1ef099607c52b327ddc17
diff --git a/metadata/md5-cache/acct-user/node_exporter-0.0.1 b/metadata/md5-cache/acct-user/node_exporter-0.0.1
new file mode 100644
index 0000000..393b0db
--- /dev/null
+++ b/metadata/md5-cache/acct-user/node_exporter-0.0.1
@@ -0,0 +1,9 @@
+DEFINED_PHASES=preinst pretend
+DEPEND=sys-apps/baselayout
+DESCRIPTION=node_exporter User
+EAPI=7
+KEYWORDS=*
+RDEPEND=acct-group/node_exporter sys-apps/baselayout
+SLOT=0
+_eclasses_=acct-user	8947f6cba2bec018df20b595d4f12cb2	user	4e2ffee100481639425c80355dd60c7b	user-info	23cfd192154f4aeac3a0cff98113134e
+_md5_=01a71f9a5b72f7b9e61f32c17572c800
diff --git a/metadata/md5-cache/acct-user/openvpn-0-r1 b/metadata/md5-cache/acct-user/openvpn-0-r1
new file mode 100644
index 0000000..f7ad51c
--- /dev/null
+++ b/metadata/md5-cache/acct-user/openvpn-0-r1
@@ -0,0 +1,9 @@
+DEFINED_PHASES=preinst pretend
+DEPEND=sys-apps/baselayout
+DESCRIPTION=User for net-vpn/openvpn
+EAPI=7
+KEYWORDS=*
+RDEPEND=acct-group/openvpn sys-apps/baselayout
+SLOT=0
+_eclasses_=acct-user	8947f6cba2bec018df20b595d4f12cb2	user	4e2ffee100481639425c80355dd60c7b	user-info	23cfd192154f4aeac3a0cff98113134e
+_md5_=421c0ea56908184887566fb94caaa733
diff --git a/metadata/md5-cache/acct-user/sshd-0-r1 b/metadata/md5-cache/acct-user/sshd-0-r1
new file mode 100644
index 0000000..1aa70b8
--- /dev/null
+++ b/metadata/md5-cache/acct-user/sshd-0-r1
@@ -0,0 +1,9 @@
+DEFINED_PHASES=preinst pretend
+DEPEND=sys-apps/baselayout
+DESCRIPTION=User for ssh
+EAPI=7
+KEYWORDS=*
+RDEPEND=acct-group/sshd sys-apps/baselayout
+SLOT=0
+_eclasses_=acct-user	8947f6cba2bec018df20b595d4f12cb2	user	4e2ffee100481639425c80355dd60c7b	user-info	23cfd192154f4aeac3a0cff98113134e
+_md5_=93885e984c25269683ce9effeade6a21
diff --git a/metadata/md5-cache/acct-user/sshd-0.0.1 b/metadata/md5-cache/acct-user/sshd-0.0.1
deleted file mode 100644
index ff96362..0000000
--- a/metadata/md5-cache/acct-user/sshd-0.0.1
+++ /dev/null
@@ -1,8 +0,0 @@
-DEFINED_PHASES=setup
-DEPEND=sys-apps/baselayout
-EAPI=7
-KEYWORDS=*
-RDEPEND=sys-apps/baselayout
-SLOT=0
-_eclasses_=user	7c566af8c48023219fd63246e88d6621
-_md5_=9bb3cfa847dcd4a91d3b8e1c1eee0700
diff --git a/profiles/base/accounts/OWNERS b/profiles/base/accounts/OWNERS
index 8546c51..3f73dde 100644
--- a/profiles/base/accounts/OWNERS
+++ b/profiles/base/accounts/OWNERS
@@ -3,4 +3,4 @@
 per-file *.py = file: /OWNERS
 
 # The security team are domain experts in account isolation.
-include OWNERS.security
+include /OWNERS.security
diff --git a/profiles/base/accounts/OWNERS.security b/profiles/base/accounts/OWNERS.security
deleted file mode 100644
index 90b0934..0000000
--- a/profiles/base/accounts/OWNERS.security
+++ /dev/null
@@ -1,4 +0,0 @@
-allenwebb@chromium.org
-jorgelo@chromium.org
-mnissler@chromium.org
-vapier@chromium.org
diff --git a/profiles/base/accounts/README.md b/profiles/base/accounts/README.md
index f9af160..68060cc 100644
--- a/profiles/base/accounts/README.md
+++ b/profiles/base/accounts/README.md
@@ -1,126 +1 @@
-# Introduction
-
-In accordance with [Gentoo's GLEP 27](https://wiki.gentoo.org/wiki/GLEP:27),
-Chromium OS has implemented a mechanism that allows users and groups
-to be managed stably and centrally for a given build profile. Each
-user and group is defined in a file underneath the appropriate
-`profiles/base/accounts/` subdirectory.
-
-For example, the `chronos` user is defined as follows in a file at
-[`profiles/base/accounts/user/chronos`](./user/chronos):
-```
-user:chronos
-password:*
-uid:1000
-gid:1000
-gecos:system_user
-home:/home/chronos/user
-shell:/bin/bash
-```
-
-The `cras` group is defined in a similarly constructed file at
-[`profiles/base/accounts/group/cras`](./group/cras):
-```
-group:cras
-password:!
-gid:220
-users:chronos,power
-```
-
-Notice how the membership of the group is provided in the group
-definition, even though traditionally this is done at user-creation
-time.
-
-The password field can be set to one of the following:
-
-*   `!` - The account is locked and may not be logged into (this is the
-    default).
-*   `*` - No password yet, but the account has the ability to have one added,
-    so this should be used for accounts that people expect to have a password
-    set for, or want to otherwise login as remotely.
-*   `x` - The password is shadowed but the account is for an internal feature;
-    people should not set a password themselves.
-*   An encrypted password as per
-    [crypt(3)](http://man7.org/linux/man-pages/man3/crypt.3.html#NOTES).
-
-
-# Choosing UIDs and GIDs
-
-Every UID on CrOS has an associated GID with the same value. The
-opposite does not hold true, however.
-
-CrOS system daemon UIDs (and associated GIDs) range from 200-299 and
-from 20100-29999. If you're creating a new user, pick the first UID in
-the range 20100-29999 that is not currently used, and create both a user
-and a group with this ID.  To find the next available UID, invoke
-`./display-accts.py --show-free`.
-
-FUSE-based filesystem daemons have UID/GIDs that range from 300-399.
-If you're adding a daemon that will be talking to `cros-disks` and
-managing some kind of volumes (archives mounted as volumes, external
-disks, network-mounted storage, etc.) then you should create a user
-and group with IDs in this range.
-
-Groups that have no associated user should be given GIDs in the 400 range.
-
-Groups and users that are shared with programs running in different user
-namespaces should be in the 600-699 range.
-
-The `chronos` user, which all user-facing processes in CrOS run as, is
-UID/GID 1000.  There is also a special user/group that has access to
-many resources owned by `chronos`, called `chronos-access`, which has
-the UID/GID 1001.
-
-# Testing
-
-If a newly added group has users, it is necessary to also add matching
-information to [`cros/test/usergroup_baseline.py`](https://chromium.googlesource.com/chromiumos/chromite/+/HEAD/cros/test/usergroup_baseline.py):
-```
-GroupEntry(group='cras', gid=220, users={'chronos', 'power'}),
-```
-
-## Board/project-specific accounts
-
-For boards creating their own users, the 2000-4999 range is reserved for that.
-Boards must take care that they don't create conflicts amongst themselves or
-any project overlays they inherit.
-
-This space is not intended for mainline CrOS use.  Such projects should be
-integrated directly into this overlay instead.  This is only for boards/projects
-that are maintained by partners.
-
-# Creating users and groups in ebuilds
-
-The API implemented by the CrOS-specific [user.eclass](/eclass/user.eclass)
-is compatible with that provided by the upstream
-[user.eclass](https://gitweb.gentoo.org/repo/gentoo.git/tree/eclass/user.eclass).
-
-```sh
-enewuser cras   # Creates a user called 'cras' with the pre-specified UID.
-enewgroup cras  # Ditto for the group.
-```
-
-You can choose to specify other fields when calling the functions to create
-new users and groups, but the eclass will bail if the values you choose conflict
-with those in the DB.
-
-Calls to `enewuser` and `enewgroup` are allowed ONLY in three ebuild stanzas:
-
-*   `pkg_setup()`: Make the calls here if you need to chown/chgrp files using
-    the accounts you're creating.
-*   `pkg_preinst()`: Make the calls here if you just need the accounts to exist
-    at runtime.
-*   `pkg_postinst()`: Try to avoid making the calls here. If you need a failed
-    account creation to be non-fatal, then you can add them here.
-
-Bear in mind that when creating a new user, simply using `cros deploy` to
-install the new pacakge on the test system will **not** install the new user.
-This is currently being tracked in [crbug.com/402673]. You can build a new
-image (by using `emerge-$BOARD <package>` and `build_image`) to get the new
-user/group to show up in `/etc/passwd` and `/etc/group`.
-
-Alternatively you can `emerge-$BOARD` the package with the new user/group and
-then copy `/build/$BOARD/etc/{passwd,group}` over the device's
-`/etc/{passwd,group}`, via `scp` or some other mechanism.
-
-[crbug.com/402673]: https://bugs.chromium.org/p/chromium/issues/detail?id=402673
+Please see https://chromium.googlesource.com/chromiumos/docs/+/HEAD/account_management.md
diff --git a/profiles/base/accounts/display-accts.py b/profiles/base/accounts/display-accts.py
index 7c275de..0d04389 100755
--- a/profiles/base/accounts/display-accts.py
+++ b/profiles/base/accounts/display-accts.py
@@ -1,5 +1,5 @@
 #!/usr/bin/env python3
-# Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+# Copyright 2014 The ChromiumOS Authors
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
@@ -7,294 +7,316 @@
 
 import argparse
 import collections
-import glob
 import os
+from pathlib import Path
 import re
 import sys
+from typing import Dict, List, NamedTuple
 
 
-assert sys.version_info >= (3, 6), (
-    f'Python 3.6+ required, but found {sys.version_info}')
+assert sys.version_info >= (
+    3,
+    6,
+), f"Python 3.6+ required, but found {sys.version_info}"
 
 
 # Regex to match valid account names.
-VALID_ACCT_NAME_RE = re.compile(r'^[a-z][a-z0-9_-]*[a-z0-9]$')
+VALID_ACCT_NAME_RE = re.compile(r"^[a-z][a-z0-9_-]*[a-z0-9]$")
 
 
-# Objects to hold group/user accounts.
-Group = collections.namedtuple('Group', ('group', 'password', 'gid', 'users',
-                                         'defunct'))
-User = collections.namedtuple('User', ('user', 'password', 'uid', 'gid',
-                                       'gecos', 'home', 'shell', 'defunct'))
+class Group(NamedTuple):
+    """A group account."""
+
+    # NB: Order is not the same as /etc/group.  Don't rely on it.
+    group: str
+    gid: str
+    password: str = "!"
+    users: str = ""
+    defunct: str = ""
 
 
-def _ParseAccount(name, name_key, content, obj, defaults):
-  """Parse the raw data in |content| and return a new |obj|"""
-  d = defaults.copy()
+class User(NamedTuple):
+    """A user account."""
 
-  # Make sure files all have a trailing newline.
-  if not content.endswith('\n'):
-    raise ValueError('File needs a trailing newline')
+    # NB: Order is not the same as /etc/passwd.  Don't rely on it.
+    user: str
+    uid: str
+    gid: str
+    password: str = "!"
+    gecos: str = ""
+    home: str = "/dev/null"
+    shell: str = "/bin/false"
+    defunct: str = ""
 
-  # Disallow leading & trailing blank lines.
-  if content.startswith('\n'):
-    raise ValueError('Delete leading blank lines')
-  if content.endswith('\n\n'):
-    raise ValueError('Delete trailing blank lines')
 
-  for line in content.splitlines():
-    if not line or line.startswith('#'):
-      continue
+def _ParseAccount(name, name_key, content, obj):
+    """Parse the raw data in |content| and return a new |obj|."""
+    # Make sure files all have a trailing newline.
+    if not content.endswith("\n"):
+        raise ValueError("File needs a trailing newline")
 
-    # Disallow leading & trailing whitespace.
-    if line != line.strip():
-      raise ValueError('Trim leading/trailing whitespace: "%s"' % line)
+    # Disallow leading & trailing blank lines.
+    if content.startswith("\n"):
+        raise ValueError("Delete leading blank lines")
+    if content.endswith("\n\n"):
+        raise ValueError("Delete trailing blank lines")
 
-    key, val = line.split(':')
-    if key not in obj._fields:
-      raise ValueError('unknown key: %s' % key)
-    d[key] = val
+    d = {}
+    for line in content.splitlines():
+        if not line or line.startswith("#"):
+            continue
 
-  missing_keys = set(obj._fields) - set(d.keys())
-  if missing_keys:
-    raise ValueError('missing keys: %s' % ' '.join(missing_keys))
+        # Disallow leading & trailing whitespace.
+        if line != line.strip():
+            raise ValueError(f'Trim leading/trailing whitespace: "{line}"')
 
-  if d[name_key] != name:
-    raise ValueError('account "%s" has the %s field set to "%s"' %
-                     (name, name_key, d[name_key]))
+        key, val = line.split(":")
+        if key not in obj._fields:
+            raise ValueError(f"unknown key: {key}")
+        d[key] = val
 
-  return obj(**d)
+    unknown_keys = set(d.keys()) - set(obj._fields)
+    if unknown_keys:
+        raise ValueError(f'unknown keys: {" ".join(unknown_keys)}')
+
+    if d[name_key] != name:
+        raise ValueError(
+            f'account "{name}" has "{name_key}" field set to "{d[name_key]}"'
+        )
+
+    return obj(**d)
 
 
 def ParseGroup(name, content):
-  """Parse |content| as a Group object"""
-  defaults = {
-      'password': '!',
-      'users': '',
-      'defunct': '',
-  }
-  return _ParseAccount(name, 'group', content, Group, defaults)
+    """Parse |content| as a Group object."""
+    return _ParseAccount(name, "group", content, Group)
 
 
 def ParseUser(name, content):
-  """Parse |content| as a User object"""
-  defaults = {
-      'gecos': '',
-      'home': '/dev/null',
-      'password': '!',
-      'shell': '/bin/false',
-      'defunct': '',
-  }
-  return _ParseAccount(name, 'user', content, User, defaults)
+    """Parse |content| as a User object."""
+    return _ParseAccount(name, "user", content, User)
 
 
-def AlignWidths(arr):
-  """Calculate a set of widths for alignment
+def AlignWidths(arr: List[NamedTuple]) -> Dict:
+    """Calculate a set of widths for alignment.
 
-  Args:
-    arr: An array of collections.namedtuple objects
+    Args:
+        arr: An array of accounts.
 
-  Returns:
-    A dict whose fields have the max length
-  """
-  d = {}
-  for f in arr[0]._fields:
-    d[f] = 0
+    Returns:
+        A dict whose fields have the max length.
+    """
+    d = {}
+    for f in arr[0]._fields:
+        d[f] = 0
 
-  for a in arr:
-    for f in a._fields:
-      d[f] = max(d[f], len(getattr(a, f)))
+    for a in arr:
+        for f in a._fields:
+            d[f] = max(d[f], len(getattr(a, f)))
 
-  return d
+    return d
 
 
-def DisplayAccounts(accts, order):
-  """Display |accts| as a table using |order| for field ordering
+def DisplayAccounts(accts: List[NamedTuple], order):
+    """Display |accts| as a table using |order| for field ordering.
 
-  Args:
-    accts: An array of collections.namedtuple objects
-    order: The order in which to display the members
-  """
-  obj = type(accts[0])
-  header_obj = obj(**dict([(k, (v if v else k).upper()) for k, v in order]))
-  keys = [k for k, _ in order]
-  sorter = lambda x: int(getattr(x, keys[0]))
+    Args:
+        accts: An array of accounts.
+        order: The order in which to display the members.
+    """
+    obj = type(accts[0])
+    header_obj = obj(**dict([(k, (v if v else k).upper()) for k, v in order]))
+    keys = [k for k, _ in order]
+    sorter = lambda x: int(getattr(x, keys[0]))
 
-  widths = AlignWidths([header_obj] + accts)
-  def p(obj):
-    for k in keys:
-      print('%-*s ' % (widths[k], getattr(obj, k)), end='')
-    print()
+    widths = AlignWidths([header_obj] + accts)
 
-  for a in [header_obj] + sorted(accts, key=sorter):
-    p(a)
+    def p(obj):
+        for k in keys:
+            print(f"{getattr(obj, k):<{widths[k] + 1}}", end="")
+        print()
+
+    for a in [header_obj] + sorted(accts, key=sorter):
+        p(a)
 
 
 def CheckConsistency(groups, users):
-  """Run various consistency/sanity checks on the lists of groups/users.
+    """Run various consistency checks on the lists of groups/users.
 
-  This does not check for syntax/etc... errors on a per-account basis as the
-  main _ParseAccount function above took care of that.
+    This does not check for syntax/etc... errors on a per-account basis as the
+    main _ParseAccount function above took care of that.
 
-  Args:
-    groups: A list of Group objects.
-    users: A list of User objects.
+    Args:
+        groups: A list of Group objects.
+        users: A list of User objects.
 
-  Returns:
-    True if everything is consistent.
-  """
-  ret = True
+    Returns:
+        True if everything is consistent.
+    """
+    ret = True
 
-  gid_counts = collections.Counter(x.gid for x in groups)
-  for gid in [k for k, v in gid_counts.items() if v > 1]:
-    ret = False
-    dupes = ', '.join(x.group for x in groups if x.gid == gid)
-    print('error: duplicate gid found: %s: %s' % (gid, dupes), file=sys.stderr)
+    gid_counts = collections.Counter(x.gid for x in groups)
+    for gid in [k for k, v in gid_counts.items() if v > 1]:
+        ret = False
+        dupes = ", ".join(x.group for x in groups if x.gid == gid)
+        print(f"error: duplicate gid found: {gid}: {dupes}", file=sys.stderr)
 
-  uid_counts = collections.Counter(x.uid for x in users)
-  for uid in [k for k, v in uid_counts.items() if v > 1]:
-    ret = False
-    dupes = ', '.join(x.user for x in users if x.uid == uid)
-    print('error: duplicate uid found: %s: %s' % (uid, dupes), file=sys.stderr)
+    uid_counts = collections.Counter(x.uid for x in users)
+    for uid in [k for k, v in uid_counts.items() if v > 1]:
+        ret = False
+        dupes = ", ".join(x.user for x in users if x.uid == uid)
+        print(f"error: duplicate uid found: {uid}: {dupes}", file=sys.stderr)
 
-  for group in groups:
-    if not VALID_ACCT_NAME_RE.match(group.group):
-      print(f'error: invalid group account name: {group.group}')
-  for user in users:
-    if not VALID_ACCT_NAME_RE.match(user.user):
-      print(f'error: invalid user account name: {user.user}')
-
-  found_users = set(x.user for x in users)
-  want_users = set()
-  for group in groups:
-    if group.users:
-      want_users.update(group.users.split(','))
-
-  missing_users = want_users - found_users
-  if missing_users:
-    ret = False
-    print('error: group lists unknown users', file=sys.stderr)
     for group in groups:
-      for user in missing_users:
-        if user in group.users.split(','):
-          print('error: group "%s" wants missing user "%s"' %
-                (group.group, user), file=sys.stderr)
+        if not VALID_ACCT_NAME_RE.match(group.group):
+            print(f"error: invalid group account name: {group.group}")
+    for user in users:
+        if not VALID_ACCT_NAME_RE.match(user.user):
+            print(f"error: invalid user account name: {user.user}")
 
-  return ret
+    found_users = set(x.user for x in users)
+    want_users = set()
+    for group in groups:
+        if group.users:
+            want_users.update(group.users.split(","))
+
+    missing_users = want_users - found_users
+    if missing_users:
+        ret = False
+        print("error: group lists unknown users", file=sys.stderr)
+        for group in groups:
+            for user in missing_users:
+                if user in group.users.split(","):
+                    print(
+                        f'error: group "{group.group}" wants missing user '
+                        f'"{user}"',
+                        file=sys.stderr,
+                    )
+
+    return ret
 
 
 def _FindFreeIds(accts, key, low_id, high_id):
-  """Find all free ids in |accts| between |low_id| and |high_id| (inclusive).
+    """Find all free ids in |accts| between |low_id| and |high_id| (inclusive).
 
-  Args:
-    accts: An iterable of account objects.
-    key: The member of the account object holding the id.
-    low_id: The first id to look for.
-    high_id: The last id to look for.
+    Args:
+        accts: An iterable of account objects.
+        key: The member of the account object holding the id.
+        low_id: The first id to look for.
+        high_id: The last id to look for.
 
-  Returns:
-    A sorted list of free ids.
-  """
-  free_accts = set(range(low_id, high_id + 1))
-  used_accts = set(int(getattr(x, key)) for x in accts)
-  return sorted(free_accts - used_accts)
+    Returns:
+        A sorted list of free ids.
+    """
+    free_accts = set(range(low_id, high_id + 1))
+    used_accts = set(int(getattr(x, key)) for x in accts)
+    return sorted(free_accts - used_accts)
 
 
 def ShowNextFree(groups, users):
-  """Display next set of free groups/users."""
-  RANGES = (
-      ('CrOS daemons', 20100, 29999),
-      ('FUSE daemons', 300, 399),
-      ('Standalone', 400, 499),
-      ('Namespaces', 600, 699),
-  )
-  for name, low_id, high_id in RANGES:
-    print('%s:' % name)
-    for accts, key in ((groups, 'gid'), (users, 'uid')):
-      if accts:
-        free_accts = _FindFreeIds(accts, key, low_id, high_id)
-        if len(free_accts) > 10:
-          free_accts = free_accts[0:10] + ['...']
-        print('  %s: %s' % (key, free_accts))
-    print()
+    """Display next set of free groups/users."""
+    RANGES = (
+        ("CrOS daemons", 20100, 29999),
+        ("FUSE daemons", 300, 399),
+        ("Standalone", 400, 499),
+        ("Namespaces", 600, 699),
+    )
+    for name, low_id, high_id in RANGES:
+        print(f"{name}:")
+        for accts, key in ((groups, "gid"), (users, "uid")):
+            if accts:
+                free_accts = _FindFreeIds(accts, key, low_id, high_id)
+                if len(free_accts) > 10:
+                    free_accts = free_accts[0:10] + ["..."]
+                print(f"  {key}: {free_accts}")
+        print()
 
 
 def GetParser():
-  """Creates the argparse parser."""
-  parser = argparse.ArgumentParser(description=__doc__)
-  parser.add_argument('--show-free', default=False, action='store_true',
-                      help='Find next available UID/GID')
-  parser.add_argument('--lint', default=False, action='store_true',
-                      help='Validate all the user accounts')
-  parser.add_argument('account', nargs='*',
-                      help='Display these account files only')
-  return parser
+    """Creates the argparse parser."""
+    parser = argparse.ArgumentParser(description=__doc__)
+    parser.add_argument(
+        "--show-free",
+        default=False,
+        action="store_true",
+        help="Find next available UID/GID",
+    )
+    parser.add_argument(
+        "--lint",
+        default=False,
+        action="store_true",
+        help="Validate all the user accounts",
+    )
+    parser.add_argument(
+        "account", nargs="*", type=Path, help="Display these account files only"
+    )
+    return parser
 
 
 def main(argv):
-  parser = GetParser()
-  opts = parser.parse_args(argv)
+    parser = GetParser()
+    opts = parser.parse_args(argv)
 
-  accounts = opts.account
-  consistency_check = False
-  if not accounts:
-    accounts_dir = os.path.dirname(os.path.realpath(__file__))
-    accounts = (glob.glob(os.path.join(accounts_dir, 'group', '*')) +
-                glob.glob(os.path.join(accounts_dir, 'user', '*')))
-    consistency_check = True
+    accounts = opts.account
+    consistency_check = False
+    if not accounts:
+        accounts_dir = Path(__file__).resolve().parent
+        accounts = list((accounts_dir / "group").glob("*")) + list(
+            (accounts_dir / "user").glob("*")
+        )
+        consistency_check = True
 
-  groups = []
-  users = []
-  for f in accounts:
-    try:
-      content = open(f).read()
-      if not content:
-        raise ValueError('empty file')
-      if content[-1] != '\n':
-        raise ValueError('missing trailing newline')
+    groups = []
+    users = []
+    for f in accounts:
+        try:
+            content = f.read_text(encoding="utf-8")
+            if not content:
+                raise ValueError("empty file")
+            if content[-1] != "\n":
+                raise ValueError("missing trailing newline")
 
-      name = os.path.basename(f)
-      if 'group:' in content:
-        groups.append(ParseGroup(name, content))
-      else:
-        users.append(ParseUser(name, content))
-    except ValueError as e:
-      print('error: %s: %s' % (f, e), file=sys.stderr)
-      return os.EX_DATAERR
+            if "group:" in content:
+                groups.append(ParseGroup(f.name, content))
+            else:
+                users.append(ParseUser(f.name, content))
+        except ValueError as e:
+            print(f"error: {f}: {e}", file=sys.stderr)
+            return os.EX_DATAERR
 
-  if opts.show_free:
-    ShowNextFree(groups, users)
-    return
+    if opts.show_free:
+        ShowNextFree(groups, users)
+        return
 
-  if not opts.lint:
-    if groups:
-      order = (
-          ('gid', ''),
-          ('group', ''),
-          ('password', 'pass'),
-          ('users', ''),
-          ('defunct', ''),
-      )
-      DisplayAccounts(groups, order)
+    if not opts.lint:
+        if groups:
+            order = (
+                ("gid", ""),
+                ("group", ""),
+                ("password", "pass"),
+                ("users", ""),
+                ("defunct", ""),
+            )
+            DisplayAccounts(groups, order)
 
-    if users:
-      if groups:
-        print()
-      order = (
-          ('uid', ''),
-          ('gid', ''),
-          ('user', ''),
-          ('shell', ''),
-          ('home', ''),
-          ('password', 'pass'),
-          ('gecos', ''),
-          ('defunct', ''),
-      )
-      DisplayAccounts(users, order)
+        if users:
+            if groups:
+                print()
+            order = (
+                ("uid", ""),
+                ("gid", ""),
+                ("user", ""),
+                ("shell", ""),
+                ("home", ""),
+                ("password", "pass"),
+                ("gecos", ""),
+                ("defunct", ""),
+            )
+            DisplayAccounts(users, order)
 
-  if consistency_check and not CheckConsistency(groups, users):
-    return os.EX_DATAERR
+    if consistency_check and not CheckConsistency(groups, users):
+        return os.EX_DATAERR
 
 
-if __name__ == '__main__':
-  sys.exit(main(sys.argv[1:]))
+if __name__ == "__main__":
+    sys.exit(main(sys.argv[1:]))
diff --git a/profiles/base/accounts/group/arc-data-snapshotd b/profiles/base/accounts/group/arc-data-snapshotd
index 90f4aaf..3a72156 100644
--- a/profiles/base/accounts/group/arc-data-snapshotd
+++ b/profiles/base/accounts/group/arc-data-snapshotd
@@ -1,3 +1,4 @@
 group:arc-data-snapshotd
 gid:20153
 users:arc-data-snapshotd
+defunct:true
diff --git a/profiles/base/accounts/group/arcvm_data_migrator b/profiles/base/accounts/group/arcvm_data_migrator
new file mode 100644
index 0000000..e0a957b
--- /dev/null
+++ b/profiles/base/accounts/group/arcvm_data_migrator
@@ -0,0 +1,3 @@
+group:arcvm_data_migrator
+gid:20198
+users:arcvm_data_migrator
diff --git a/profiles/base/accounts/group/camera b/profiles/base/accounts/group/camera
new file mode 100644
index 0000000..7859eca
--- /dev/null
+++ b/profiles/base/accounts/group/camera
@@ -0,0 +1,3 @@
+group:camera
+gid:20042
+users:arc-camera,cfm-firmware-updaters
diff --git a/profiles/base/accounts/group/chronos-access b/profiles/base/accounts/group/chronos-access
index d973a71..a592d8c 100644
--- a/profiles/base/accounts/group/chronos-access
+++ b/profiles/base/accounts/group/chronos-access
@@ -6,4 +6,4 @@
 # This includes all users accessing opencryptoki database files.
 #
 # Processes running with chronos-access need enforcing SELinux domains.
-users:vpn,chronos,cros-disks,imageloaderd,crash,dlp,image-burner,spaced
+users:vpn,chronos,cros-disks,imageloaderd,crash,dlp,image-burner,seneschal,spaced
diff --git a/profiles/base/accounts/group/crosvm b/profiles/base/accounts/group/crosvm
index 5a53736..47d4ef5 100644
--- a/profiles/base/accounts/group/crosvm
+++ b/profiles/base/accounts/group/crosvm
@@ -1,3 +1,3 @@
 group:crosvm
 gid:299
-users:crosvm
+users:crosvm,shadercached
diff --git a/profiles/base/accounts/group/dcader b/profiles/base/accounts/group/dcader
new file mode 100644
index 0000000..fe5349c
--- /dev/null
+++ b/profiles/base/accounts/group/dcader
@@ -0,0 +1,3 @@
+group:dcader
+gid:20202
+users:dcader
diff --git a/profiles/base/accounts/group/dhcp b/profiles/base/accounts/group/dhcp
index ad4d80b..f4138a4 100644
--- a/profiles/base/accounts/group/dhcp
+++ b/profiles/base/accounts/group/dhcp
@@ -1,3 +1,3 @@
 group:dhcp
 gid:224
-users:
+users:shill
diff --git a/profiles/base/accounts/group/disco b/profiles/base/accounts/group/disco
index b9c2d50..dc5ec6e 100644
--- a/profiles/base/accounts/group/disco
+++ b/profiles/base/accounts/group/disco
@@ -1,3 +1,3 @@
 group:disco
-gid:20192
+gid:20193
 users:disco
diff --git a/profiles/base/accounts/group/disk-dlc b/profiles/base/accounts/group/disk-dlc
new file mode 100644
index 0000000..d92b8ea
--- /dev/null
+++ b/profiles/base/accounts/group/disk-dlc
@@ -0,0 +1,3 @@
+group:disk-dlc
+gid:20777
+users:root,dlcservice,imageloaderd
diff --git a/profiles/base/accounts/group/docker b/profiles/base/accounts/group/docker
index 7816a8b..91f72a7 100644
--- a/profiles/base/accounts/group/docker
+++ b/profiles/base/accounts/group/docker
@@ -1,3 +1,4 @@
 group:docker
 gid:412
 password:!
+users:chronos
diff --git a/profiles/base/accounts/group/faced b/profiles/base/accounts/group/faced
new file mode 100644
index 0000000..dd6d5ba
--- /dev/null
+++ b/profiles/base/accounts/group/faced
@@ -0,0 +1,3 @@
+group:faced
+gid:20194
+users:faced
diff --git a/profiles/base/accounts/group/fpdev b/profiles/base/accounts/group/fpdev
new file mode 100644
index 0000000..b9c112f
--- /dev/null
+++ b/profiles/base/accounts/group/fpdev
@@ -0,0 +1,5 @@
+group:fpdev
+gid:426
+# This group is to grant rw access of /dev/cros_fp to biod, healthd_fp, because
+# the binaries they run need access w/o being root.
+users:biod,healthd_fp
diff --git a/profiles/base/accounts/group/healthd_evdev b/profiles/base/accounts/group/healthd_evdev
new file mode 100644
index 0000000..4a70cb6
--- /dev/null
+++ b/profiles/base/accounts/group/healthd_evdev
@@ -0,0 +1,3 @@
+group:healthd_evdev
+gid:20199
+users:healthd_evdev
diff --git a/profiles/base/accounts/group/healthd_fp b/profiles/base/accounts/group/healthd_fp
new file mode 100644
index 0000000..e940476
--- /dev/null
+++ b/profiles/base/accounts/group/healthd_fp
@@ -0,0 +1,3 @@
+group:healthd_fp
+gid:20196
+users:healthd_fp
diff --git a/profiles/base/accounts/group/healthd_psr b/profiles/base/accounts/group/healthd_psr
new file mode 100644
index 0000000..ab1c92b
--- /dev/null
+++ b/profiles/base/accounts/group/healthd_psr
@@ -0,0 +1,3 @@
+group:healthd_psr
+gid:20200
+users:healthd_psr
diff --git a/profiles/base/accounts/group/hidraw b/profiles/base/accounts/group/hidraw
index 227a3bd..4eb9edc 100644
--- a/profiles/base/accounts/group/hidraw
+++ b/profiles/base/accounts/group/hidraw
@@ -1,4 +1,4 @@
 group:hidraw
 gid:403
-# fwupdate-hidraw: For firmware updater utilities that use the hidraw interface.
-users:fwupdate-hidraw
+# fwupd, fwupdate-hidraw: For fwupd & utilities that use the hidraw interface.
+users:fwupd,fwupdate-hidraw
diff --git a/profiles/base/accounts/group/input b/profiles/base/accounts/group/input
index 2830a26..dfdbb43 100644
--- a/profiles/base/accounts/group/input
+++ b/profiles/base/accounts/group/input
@@ -3,4 +3,9 @@
 # cras needs access to /dev/input/event*
 # power manager needs to read from /dev/input/event* to observe power
 # button and lid events.
-users:cras,power,chronos
+# cros_healthd needs to access telemetry information, event notifications, and
+# diagnostics under /dev/input/event*. For example:
+#   - Telemetry: Retrieve vendor name.
+#   - Event: HDMI plug-in/out, audio device plug-in/out.
+#   - Diagnostics: Volume button pressed or not.
+users:cras,power,chronos,healthd_evdev
diff --git a/profiles/base/accounts/group/lp b/profiles/base/accounts/group/lp
index 0e17761..63ea6dd 100644
--- a/profiles/base/accounts/group/lp
+++ b/profiles/base/accounts/group/lp
@@ -1,3 +1,3 @@
 group:lp
 gid:7
-users:lp,lpadmin,cups,chronos
+users:lp,lpadmin,cups,chronos,printscanmgr
diff --git a/profiles/base/accounts/group/lpadmin b/profiles/base/accounts/group/lpadmin
index c32e72c..728df0b 100644
--- a/profiles/base/accounts/group/lpadmin
+++ b/profiles/base/accounts/group/lpadmin
@@ -1,3 +1,3 @@
 group:lpadmin
 gid:269
-users:cups,lpadmin
+users:cups,lpadmin,printscanmgr
diff --git a/profiles/base/accounts/group/mei-access b/profiles/base/accounts/group/mei-access
new file mode 100644
index 0000000..604b655
--- /dev/null
+++ b/profiles/base/accounts/group/mei-access
@@ -0,0 +1,5 @@
+group:mei-access
+gid:427
+# This group is to grant rw access of /dev/mei0 to healthd_psr, because
+# they need access w/o being root.
+users:healthd_psr
diff --git a/profiles/base/accounts/group/missived_senders b/profiles/base/accounts/group/missived_senders
index 3c2594e..54e1fa8 100644
--- a/profiles/base/accounts/group/missived_senders
+++ b/profiles/base/accounts/group/missived_senders
@@ -1,4 +1,4 @@
 group:missived_senders
 password:!
 gid:20191
-users:cros_healthd,secanomaly
+users:cros_healthd,secagentd,secanomaly
diff --git a/profiles/base/accounts/group/ml-core b/profiles/base/accounts/group/ml-core
new file mode 100644
index 0000000..5587a38
--- /dev/null
+++ b/profiles/base/accounts/group/ml-core
@@ -0,0 +1,3 @@
+group:ml-core
+gid:612
+users:ml-core,arc-camera
diff --git a/profiles/base/accounts/group/node_exporter b/profiles/base/accounts/group/node_exporter
new file mode 100644
index 0000000..c2c48d5
--- /dev/null
+++ b/profiles/base/accounts/group/node_exporter
@@ -0,0 +1,2 @@
+group:node_exporter
+gid:459
diff --git a/profiles/base/accounts/group/policy-readers b/profiles/base/accounts/group/policy-readers
index 7371f2c..98cac49 100644
--- a/profiles/base/accounts/group/policy-readers
+++ b/profiles/base/accounts/group/policy-readers
@@ -1,4 +1,4 @@
 # Members have read access to the device policy in /var/lib/devicesettings.
 group:policy-readers
 gid:303
-users:attestation,authpolicyd,chronos,hardware_verifier,u2f,shill
+users:attestation,authpolicyd,chronos,hardware_verifier,secagentd,shill,u2f
diff --git a/profiles/base/accounts/group/printscanmgr b/profiles/base/accounts/group/printscanmgr
new file mode 100644
index 0000000..34ec883
--- /dev/null
+++ b/profiles/base/accounts/group/printscanmgr
@@ -0,0 +1,3 @@
+group:printscanmgr
+gid:20201
+users:printscanmgr
diff --git a/profiles/base/accounts/group/private_computing b/profiles/base/accounts/group/private_computing
new file mode 100644
index 0000000..e826eaa
--- /dev/null
+++ b/profiles/base/accounts/group/private_computing
@@ -0,0 +1,3 @@
+group:private_computing
+gid:20197
+users:private_computing
diff --git a/profiles/base/accounts/group/rgbkbd b/profiles/base/accounts/group/rgbkbd
index d7fb656..563f4e3 100644
--- a/profiles/base/accounts/group/rgbkbd
+++ b/profiles/base/accounts/group/rgbkbd
@@ -1,4 +1,4 @@
 group:rgbkbd
 gid:20186
 # power: For backlight control of a keyboard connected via USB.
-users:rgbkbd,power
+users:rgbkbd,power,fwupd
diff --git a/profiles/base/accounts/group/rmad-executor b/profiles/base/accounts/group/rmad-executor
new file mode 100644
index 0000000..d10ded0
--- /dev/null
+++ b/profiles/base/accounts/group/rmad-executor
@@ -0,0 +1,3 @@
+group:rmad-executor
+gid:20195
+users:rmad-executor
diff --git a/profiles/base/accounts/group/secagentd b/profiles/base/accounts/group/secagentd
new file mode 100644
index 0000000..8a4265d
--- /dev/null
+++ b/profiles/base/accounts/group/secagentd
@@ -0,0 +1,3 @@
+group:secagentd
+gid:20192
+users:secagentd
diff --git a/profiles/base/accounts/group/shadercached b/profiles/base/accounts/group/shadercached
new file mode 100644
index 0000000..b20668a
--- /dev/null
+++ b/profiles/base/accounts/group/shadercached
@@ -0,0 +1,4 @@
+group:shadercached
+password:!
+gid:333
+users:shadercached,crosvm
diff --git a/profiles/base/accounts/group/traced-consumer b/profiles/base/accounts/group/traced-consumer
index b06429d..5f31c5a 100644
--- a/profiles/base/accounts/group/traced-consumer
+++ b/profiles/base/accounts/group/traced-consumer
@@ -7,4 +7,4 @@
 #      trace using the Perfetto UI (ui.perfetto.dev).
 group:traced-consumer
 gid:20164
-users:traced,chronos
+users:traced,chronos,debugd
diff --git a/profiles/base/accounts/group/video b/profiles/base/accounts/group/video
index 6dc28b1..07026de 100644
--- a/profiles/base/accounts/group/video
+++ b/profiles/base/accounts/group/video
@@ -1,3 +1,3 @@
 group:video
 gid:27
-users:root,chronos,arc-camera,dlm,rtanalytics,crosvm,cfm-monitor,runtime_probe,smdisplay,cdm-oemcrypto,cros_healthd,nvpd
+users:root,chronos,arc-camera,dlm,rtanalytics,crosvm,cfm-monitor,smdisplay,cdm-oemcrypto,cros_healthd,nvpd,ml-core,runtime_probe
diff --git a/profiles/base/accounts/user/arc-data-snapshotd b/profiles/base/accounts/user/arc-data-snapshotd
index 45c17ef..e38d850 100644
--- a/profiles/base/accounts/user/arc-data-snapshotd
+++ b/profiles/base/accounts/user/arc-data-snapshotd
@@ -4,3 +4,4 @@
 gecos:User for arc-data-snapshotd service.
 home:/dev/null
 shell:/bin/false
+defunct:true
diff --git a/profiles/base/accounts/user/arcvm_data_migrator b/profiles/base/accounts/user/arcvm_data_migrator
new file mode 100644
index 0000000..f72a6fd
--- /dev/null
+++ b/profiles/base/accounts/user/arcvm_data_migrator
@@ -0,0 +1,6 @@
+user:arcvm_data_migrator
+uid:20198
+gid:20198
+gecos:ChromeOS ARCVM /data migrator
+home:/dev/null
+shell:/bin/false
diff --git a/profiles/base/accounts/user/dcader b/profiles/base/accounts/user/dcader
new file mode 100644
index 0000000..5a90040
--- /dev/null
+++ b/profiles/base/accounts/user/dcader
@@ -0,0 +1,6 @@
+user:dcader
+uid:20202
+gid:20202
+gecos:data collection app daemon
+home:/dev/null
+shell:/bin/false
diff --git a/profiles/base/accounts/user/disco b/profiles/base/accounts/user/disco
index 3a9d288..6b9a7d6 100644
--- a/profiles/base/accounts/user/disco
+++ b/profiles/base/accounts/user/disco
@@ -1,6 +1,6 @@
 user:disco
-uid:20192
-gid:20192
+uid:20193
+gid:20193
 gecos:Disk control daemon
 home:/dev/null
 shell:/bin/false
diff --git a/profiles/base/accounts/user/faced b/profiles/base/accounts/user/faced
new file mode 100644
index 0000000..48e8cfe
--- /dev/null
+++ b/profiles/base/accounts/user/faced
@@ -0,0 +1,6 @@
+user:faced
+uid:20194
+gid:20194
+gecos:CrOS face authentication daemon
+home:/dev/null
+shell:/bin/false
diff --git a/profiles/base/accounts/user/healthd_evdev b/profiles/base/accounts/user/healthd_evdev
new file mode 100644
index 0000000..eb622de
--- /dev/null
+++ b/profiles/base/accounts/user/healthd_evdev
@@ -0,0 +1,6 @@
+user:healthd_evdev
+uid:20199
+gid:20199
+gecos:Healthd user for accessing event device (evdev).
+home:/dev/null
+shell:/bin/false
diff --git a/profiles/base/accounts/user/healthd_fp b/profiles/base/accounts/user/healthd_fp
new file mode 100644
index 0000000..d3e39dc
--- /dev/null
+++ b/profiles/base/accounts/user/healthd_fp
@@ -0,0 +1,6 @@
+user:healthd_fp
+uid:20196
+gid:20196
+gecos:Healthd user for accessing fingerprint device.
+home:/dev/null
+shell:/bin/false
diff --git a/profiles/base/accounts/user/healthd_psr b/profiles/base/accounts/user/healthd_psr
new file mode 100644
index 0000000..fb5e825
--- /dev/null
+++ b/profiles/base/accounts/user/healthd_psr
@@ -0,0 +1,6 @@
+user:healthd_psr
+uid:20200
+gid:20200
+gecos:Healthd user for psr delegate.
+home:/dev/null
+shell:/bin/false
diff --git a/profiles/base/accounts/user/ml-core b/profiles/base/accounts/user/ml-core
new file mode 100644
index 0000000..c7e76f9
--- /dev/null
+++ b/profiles/base/accounts/user/ml-core
@@ -0,0 +1,6 @@
+user:ml-core
+uid:612
+gid:612
+gecos:CrOS ML services
+home:/dev/null
+shell:/bin/false
diff --git a/profiles/base/accounts/user/node_exporter b/profiles/base/accounts/user/node_exporter
new file mode 100644
index 0000000..4f31f69
--- /dev/null
+++ b/profiles/base/accounts/user/node_exporter
@@ -0,0 +1,6 @@
+user:node_exporter
+uid:459
+gid:459
+gecos:prometheus exporter for machine metrics
+home:/dev/null
+shell:/bin/false
diff --git a/profiles/base/accounts/user/printscanmgr b/profiles/base/accounts/user/printscanmgr
new file mode 100644
index 0000000..0bb9d7f
--- /dev/null
+++ b/profiles/base/accounts/user/printscanmgr
@@ -0,0 +1,6 @@
+user:printscanmgr
+uid:20201
+gid:20201
+gecos:User for printing and scanning daemon.
+home:/dev/null
+shell:/bin/false
diff --git a/profiles/base/accounts/user/private_computing b/profiles/base/accounts/user/private_computing
new file mode 100644
index 0000000..cbcbb9e
--- /dev/null
+++ b/profiles/base/accounts/user/private_computing
@@ -0,0 +1,6 @@
+user:private_computing
+uid:20197
+gid:20197
+gecos:ChromeOS Private Computing daemon
+home:/dev/null
+shell:/bin/false
diff --git a/profiles/base/accounts/user/rmad-executor b/profiles/base/accounts/user/rmad-executor
new file mode 100644
index 0000000..c4c4353
--- /dev/null
+++ b/profiles/base/accounts/user/rmad-executor
@@ -0,0 +1,6 @@
+user:rmad-executor
+uid:20195
+gid:20195
+gecos:CrOS RMA daemon executor for privileged tasks
+home:/dev/null
+shell:/bin/false
diff --git a/profiles/base/accounts/user/secagentd b/profiles/base/accounts/user/secagentd
new file mode 100644
index 0000000..f8a5745
--- /dev/null
+++ b/profiles/base/accounts/user/secagentd
@@ -0,0 +1,6 @@
+user:secagentd
+uid:20192
+gid:20192
+gecos: security event reporting daemon
+home:/dev/null
+shell:/bin/false
diff --git a/profiles/base/accounts/user/shadercached b/profiles/base/accounts/user/shadercached
new file mode 100644
index 0000000..a68ee74
--- /dev/null
+++ b/profiles/base/accounts/user/shadercached
@@ -0,0 +1,6 @@
+user:shadercached
+uid:333
+gid:333
+gecos:VM shader cache management user
+home:/dev/null
+shell:/bin/false