diff --git a/README-hbacrule.md b/README-hbacrule.md
index d14692f9735cd95476122a0683b8b5a40b6338ed..a1b69877da2bb66e6b6ca54404258c8023ba060b 100644
--- a/README-hbacrule.md
+++ b/README-hbacrule.md
@@ -138,9 +138,9 @@ Variable | Description | Required
 `ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no
 `name` \| `cn` | The list of hbacrule name strings. | yes
 `description` | The hbacrule description string. | no
-`usercategory` \| `usercat` | User category the rule applies to. Choices: ["all"] | no
-`hostcategory` \| `hostcat` | Host category the rule applies to. Choices: ["all"] | no
-`servicecategory` \| `servicecat` | HBAC service category the rule applies to. Choices: ["all"] | no
+`usercategory` \| `usercat` | User category the rule applies to. Choices: ["all", ""] | no
+`hostcategory` \| `hostcat` | Host category the rule applies to. Choices: ["all", ""] | no
+`servicecategory` \| `servicecat` | HBAC service category the rule applies to. Choices: ["all", ""] | no
 `nomembers` | Suppress processing of membership attributes. (bool) | no
 `host` | List of host name strings assigned to this hbacrule. | no
 `hostgroup` | List of host group name strings assigned to this hbacrule. | no
diff --git a/README-sudorule.md b/README-sudorule.md
index 4bec5e65fde0b96ad1c7b7314ba57b187a50bdf8..daa6c0a384c78a9a4196cfede2da61fd7a879a07 100644
--- a/README-sudorule.md
+++ b/README-sudorule.md
@@ -122,11 +122,11 @@ Variable | Description | Required
 `ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no
 `name` \| `cn` | The list of sudorule name strings. | yes
 `description` | The sudorule description string. | no
-`usercategory` | User category the rule applies to. Choices: ["all"] | no
-`hostcategory` | Host category the rule applies to. Choices: ["all"] | no
-`cmdcategory` | Command category the rule applies to. Choices: ["all"] | no
-`runasusercategory` | RunAs User category the rule applies to. Choices: ["all"] | no
-`runasgroupcategory` | RunAs Group category the rule applies to. Choices: ["all"] | no
+`usercategory` \| `usercat` | User category the rule applies to. Choices: ["all", ""] | no
+`hostcategory` \| `hostcat` | Host category the rule applies to. Choices: ["all", ""] | no
+`cmdcategory` \| `cmdcat` | Command category the rule applies to. Choices: ["all", ""] | no
+`runasusercategory` \| `rusasusercat` | RunAs User category the rule applies to. Choices: ["all", ""] | no
+`runasgroupcategory` \| `runasgroupcat` | RunAs Group category the rule applies to. Choices: ["all", ""] | no
 `nomembers` | Suppress processing of membership attributes. (bool) | no
 `host` | List of host name strings assigned to this sudorule. | no
 `hostgroup` | List of host group name strings assigned to this sudorule. | no
diff --git a/plugins/modules/ipahbacrule.py b/plugins/modules/ipahbacrule.py
index 452f9f8c935c2c62b329843d84bce12731899fcc..a94758e9c90c8d0e6b71a98254799e7ceb26f52c 100644
--- a/plugins/modules/ipahbacrule.py
+++ b/plugins/modules/ipahbacrule.py
@@ -49,17 +49,17 @@ options:
     description: User category the rule applies to
     required: false
     aliases: ["usercat"]
-    choices: ["all"]
+    choices: ["all", ""]
   hostcategory:
     description: Host category the rule applies to
     required: false
     aliases: ["hostcat"]
-    choices: ["all"]
+    choices: ["all", ""]
   servicecategory:
     description: Service category the rule applies to
     required: false
     aliases: ["servicecat"]
-    choices: ["all"]
+    choices: ["all", ""]
   nomembers:
     description: Suppress processing of membership attributes
     required: false
@@ -208,11 +208,11 @@ def main():
             # present
             description=dict(type="str", default=None),
             usercategory=dict(type="str", default=None,
-                              aliases=["usercat"], choices=["all"]),
+                              aliases=["usercat"], choices=["all", ""]),
             hostcategory=dict(type="str", default=None,
-                              aliases=["hostcat"], choices=["all"]),
+                              aliases=["hostcat"], choices=["all", ""]),
             servicecategory=dict(type="str", default=None,
-                                 aliases=["servicecat"], choices=["all"]),
+                                 aliases=["servicecat"], choices=["all", ""]),
             nomembers=dict(required=False, type='bool', default=None),
             host=dict(required=False, type='list', default=None),
             hostgroup=dict(required=False, type='list', default=None),
diff --git a/plugins/modules/ipasudorule.py b/plugins/modules/ipasudorule.py
index 24d0d7eef8fddb0bef13ecaf6c08e3811235301f..72c5a73bf3c911f5c6d028eac11c48bca1513ce8 100644
--- a/plugins/modules/ipasudorule.py
+++ b/plugins/modules/ipasudorule.py
@@ -51,18 +51,21 @@ options:
   usercategory:
     description: User category the sudo rule applies to
     required: false
-    choices: ["all"]
+    choices: ["all", ""]
+    aliases: ["usercat"]
   usergroup:
     description: List of user groups assigned to the sudo rule.
     required: false
   runasgroupcategory:
     description: RunAs Group category applied to the sudo rule.
     required: false
-    choices: ["all"]
+    choices: ["all", ""]
+    aliases: ["runasgroupcat"]
   runasusercategory:
     description: RunAs User category applied to the sudorule.
     required: false
-    choices: ["all"]
+    choices: ["all", ""]
+    aliases: ["runasusercat"]
   nomembers:
     description: Suppress processing of membership attributes
     required: false
@@ -78,7 +81,8 @@ options:
   hostcategory:
     description: Host category the sudo rule applies to.
     required: false
-    choices: ["all"]
+    choices: ["all", ""]
+    aliases: ["hostcat"]
   allow_sudocmd:
     description: List of allowed sudocmds assigned to this sudorule.
     required: false
@@ -98,7 +102,8 @@ options:
   cmdcategory:
     description: Command category the sudo rule applies to
     required: false
-    choices: ["all"]
+    choices: ["all", ""]
+    aliases: ["cmdcat"]
   order:
     description: Order to apply this rule.
     required: false
@@ -241,9 +246,9 @@ def main():
             # present
             description=dict(required=False, type="str", default=None),
             usercategory=dict(required=False, type="str", default=None,
-                              choices=["all"]),
+                              choices=["all", ""], aliases=['usercat']),
             hostcategory=dict(required=False, type="str", default=None,
-                              choices=["all"]),
+                              choices=["all", ""], aliases=['hostcat']),
             nomembers=dict(required=False, type='bool', default=None),
             host=dict(required=False, type='list', default=None),
             hostgroup=dict(required=False, type='list', default=None),
@@ -254,11 +259,13 @@ def main():
             allow_sudocmdgroup=dict(required=False, type="list", default=None),
             deny_sudocmdgroup=dict(required=False, type="list", default=None),
             cmdcategory=dict(required=False, type="str", default=None,
-                             choices=["all"]),
+                             choices=["all", ""], aliases=['cmdcat']),
             runasusercategory=dict(required=False, type="str", default=None,
-                                   choices=["all"]),
+                                   choices=["all", ""],
+                                   aliases=['runasusercat']),
             runasgroupcategory=dict(required=False, type="str", default=None,
-                                    choices=["all"]),
+                                    choices=["all", ""],
+                                    aliases=['runasgroupcat']),
             runasuser=dict(required=False, type="list", default=None),
             runasgroup=dict(required=False, type="list", default=None),
             order=dict(type="int", required=False, aliases=['sudoorder']),
diff --git a/tests/hbacrule/test_hbacrule_categories.yml b/tests/hbacrule/test_hbacrule_categories.yml
new file mode 100644
index 0000000000000000000000000000000000000000..5f1934bc8cb2a62b40de5b0c887d1ac4c3627628
--- /dev/null
+++ b/tests/hbacrule/test_hbacrule_categories.yml
@@ -0,0 +1,117 @@
+---
+- name: Test HBAC rule user category
+  hosts: ipaserver
+  become: true
+  gather_facts: false
+
+  tasks:
+
+  - name: Ensure HBAC rules are absent
+    ipahbacrule:
+      ipaadmin_password: SomeADMINpassword
+      name:
+      - testrule
+      state: absent
+
+  - name: Ensure HBAC rule is present, with usercategory 'all'
+    ipahbacrule:
+      ipaadmin_password: SomeADMINpassword
+      name: testrule
+      usercategory: all
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure HBAC rule is present, with usercategory 'all', again.
+    ipahbacrule:
+      ipaadmin_password: SomeADMINpassword
+      name: testrule
+      usercategory: all
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure HBAC rule is present, with no usercategory.
+    ipahbacrule:
+      ipaadmin_password: SomeADMINpassword
+      name: testrule
+      usercategory: ""
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure HBAC rule is present, with no usercategory, again.
+    ipahbacrule:
+      ipaadmin_password: SomeADMINpassword
+      name: testrule
+      usercategory: ""
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure HBAC rule is present, with hostcategory 'all'
+    ipahbacrule:
+      ipaadmin_password: SomeADMINpassword
+      name: testrule
+      hostcategory: all
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure HBAC rule is present, with hostcategory 'all', again.
+    ipahbacrule:
+      ipaadmin_password: SomeADMINpassword
+      name: testrule
+      hostcategory: all
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure HBAC rule is present, with no hostcategory.
+    ipahbacrule:
+      ipaadmin_password: SomeADMINpassword
+      name: testrule
+      hostcategory: ""
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure HBAC rule is present, with no hostcategory, again.
+    ipahbacrule:
+      ipaadmin_password: SomeADMINpassword
+      name: testrule
+      hostcategory: ""
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure HBAC rule is present, with servicecategory 'all'
+    ipahbacrule:
+      ipaadmin_password: SomeADMINpassword
+      name: testrule
+      servicecategory: all
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure HBAC rule is present, with servicecategory 'all', again.
+    ipahbacrule:
+      ipaadmin_password: SomeADMINpassword
+      name: testrule
+      servicecategory: all
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure HBAC rule is present, with no servicecategory.
+    ipahbacrule:
+      ipaadmin_password: SomeADMINpassword
+      name: testrule
+      servicecategory: ""
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure HBAC rule is present, with no servicecategory, again.
+    ipahbacrule:
+      ipaadmin_password: SomeADMINpassword
+      name: testrule
+      servicecategory: ""
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure HBAC rules are absent
+    ipahbacrule:
+      ipaadmin_password: SomeADMINpassword
+      name:
+      - testrule
+      state: absent
diff --git a/tests/sudorule/test_sudorule_categories.yml b/tests/sudorule/test_sudorule_categories.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c4aaeda6d6e6977b2b5fad09d3285ea38d4f363d
--- /dev/null
+++ b/tests/sudorule/test_sudorule_categories.yml
@@ -0,0 +1,182 @@
+---
+- name: Test sudorule user category
+  hosts: ipaserver
+  become: true
+  gather_facts: false
+
+  tasks:
+
+  - name: Ensure sudorules are absent
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name:
+      - allusers
+      state: absent
+
+  - name: Ensure sudorule is present, with usercategory 'all'
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      usercategory: all
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure sudorule is present, with usercategory 'all', again.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      usercategory: all
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure sudorule is present, with no usercategory.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      usercategory: ""
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure sudorule is present, with no usercategory, again.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      usercategory: ""
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure sudorule is present, with hostcategory 'all'
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      hostcategory: all
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure sudorule is present, with hostcategory 'all', again.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      hostcategory: all
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure sudorule is present, with no usercategory.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      hostcategory: ""
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure sudorule is present, with no hostcategory, again.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      hostcategory: ""
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure sudorule is present, with cmdcategory 'all'
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      cmdcategory: all
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure sudorule is present, with cmdcategory 'all', again.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      cmdcategory: all
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure sudorule is present, with no cmdcategory.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      cmdcategory: ""
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure sudorule is present, with no cmdcategory, again.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      cmdcategory: ""
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure sudorule is present, with runasusercategory 'all'
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      runasusercategory: all
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure sudorule is present, with runasusercategory 'all', again.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      runasusercategory: all
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure sudorule is present, with no runasusercategory.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      runasusercategory: ""
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure sudorule is present, with no runasusercategory, again.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      runasusercategory: ""
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure sudorule is present, with runasgroupcategory 'all'
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      runasgroupcategory: all
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure sudorule is present, with runasgroupcategory 'all', again.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      runasgroupcategory: all
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure sudorule is present, with no runasgroupcategory.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      runasgroupcategory: ""
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure sudorule is present, with no runasgroupcategory, again.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      runasgroupcategory: ""
+    register: result
+    failed_when: result.changed
+
+  # cleanup
+  - name: Ensure sudorules are absent
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name:
+      - allusers
+      state: absent