diff --git a/core/modules/system/core.api.php b/core/modules/system/core.api.php
index 4b697a1..624426e 100644
--- a/core/modules/system/core.api.php
+++ b/core/modules/system/core.api.php
@@ -676,14 +676,71 @@
  */
 
 /**
- * @defgroup user_api User Accounts System
+ * @defgroup user_api User accounts, permissions, and roles
  * @{
  * API for user accounts, access checking, roles, and permissions.
  *
- * @todo write this
- *
- * Additional documentation paragraphs need to be written, and functions,
- * classes, and interfaces need to be added to this topic.
+ * @sec sec_overview Overview and terminology
+ * Drupal's permission system is based on the concepts of accounts, roles,
+ * and permissions.
+ *
+ * Users (site visitors) have accounts, which include a user name, an email
+ * address, a password (or some other means of authentication), and possibly
+ * other fields (if defined on the site). Anonymous users have an implicit
+ * account that does not have a real user name or any account information.
+ *
+ * Each user account is assigned one or more roles. The anonymous user account
+ * automatically has the anonymous user role; real user accounts
+ * automatically have the authenticated user role, plus any roles defined on
+ * the site that they have been assigned.
+ *
+ * Each role, including the special anonymous and authenticated user roles, is
+ * granted one or more named permissions, which allow them to perform certain
+ * tasks or view certain content on the site. It is possible to designate a
+ * role to be the "administrator" role; if this is set up, this role is
+ * automatically granted all available permissions whenever a module is
+ * enabled that defines permissions.
+ *
+ * All code in Drupal that allows users to perform tasks or view content must
+ * check that the current user has the correct permission before allowing the
+ * action. In the standard case, access checking consists of answering the
+ * question "Does the current user have permission 'foo'?", and allowing or
+ * denying access based on the answer. Note that access checking should nearly
+ * always be done at the permission level, not by checking for a particular role
+ * or user ID, so that site administrators can set up user accounts and roles
+ * appropriately for their particular sites.
+ *
+ * @sec sec_define Defining permissions
+ * Modules define permissions by implementing hook_permission(). The return
+ * value defines machine names, human-readable names, and optionally
+ * descriptions for each permission type. The machine names are the canonical
+ * way to refer to permissions for access checking.
+ *
+ * @sec sec_access Access permission checking
+ * Depending on the situation, there are several methods for ensuring that
+ * access checks are done properly in Drupal:
+ * - Routes: When you register a route, include a 'requirements' section that
+ *   either gives the machine name of the permission that is needed to visit the
+ *   URL of the route, or tells Drupal to use an access check method or service
+ *   to check access. See the @link menu Routing topic @endlink for more
+ *   information.
+ * - Entities: Access for various entity operations is designated either with
+ *   simple permissions or access controller classes in the entity annotation.
+ *   See the @link entity_api Entity API topic @endlink for more information.
+ * - Forms: Each element of a form array can have a Boolean '#access' property,
+ *   which determines whether that element is visible and/or usable. This is a
+ *   common need in forms, so method
+ *   \Drupal\Core\Form\FormBuilder::currentUser() on the default form builder
+ *   class can be used to retrieve a user object for the current user, and
+ *   then methods on \Drupal\user\UserInterface can be called to check
+ *   permissions.
+ *
+ * @sec sec_entities User and role objects
+ * User objects in Drupal are entity items, implementing
+ * \Drupal\user\UserInterface. Role objects in Drupal are also entity items,
+ * implementing \Drupal\user\RoleInterface. See the
+ * @link entity_api Entity API topic @endlink for more information about
+ * entities in general (including how to load, create, modify, and query them).
  * @}
  */
 
diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php
index a1e73a6..09663aa 100644
--- a/core/modules/system/system.api.php
+++ b/core/modules/system/system.api.php
@@ -969,6 +969,8 @@ function hook_system_info_alter(array &$info, \Drupal\Core\Extension\Extension $
  *     is specific to the permission you are defining.
  *
  * @see theme_user_permission_description()
+ *
+ * @ingroup user_api
  */
 function hook_permission() {
   return array(
diff --git a/core/modules/user/src/RoleInterface.php b/core/modules/user/src/RoleInterface.php
index 7160a8e..1cae601 100644
--- a/core/modules/user/src/RoleInterface.php
+++ b/core/modules/user/src/RoleInterface.php
@@ -11,6 +11,8 @@
 
 /**
  * Provides an interface defining a user role entity.
+ *
+ * @ingroup user_api
  */
 interface RoleInterface extends ConfigEntityInterface {
 
diff --git a/core/modules/user/src/UserInterface.php b/core/modules/user/src/UserInterface.php
index 8ea02e3..8b89dd4 100644
--- a/core/modules/user/src/UserInterface.php
+++ b/core/modules/user/src/UserInterface.php
@@ -12,6 +12,8 @@
 
 /**
  * Provides an interface defining a user entity.
+ *
+ * @ingroup user_api
  */
 interface UserInterface extends ContentEntityInterface, AccountInterface {
 
