diff --git a/cdist/conf/type/__user_groups/explorer/group b/cdist/conf/type/__user_groups/explorer/group
new file mode 100755
index 00000000..a8cb63af
--- /dev/null
+++ b/cdist/conf/type/__user_groups/explorer/group
@@ -0,0 +1,23 @@
+#!/bin/sh
+#
+# 2012 Steven Armstrong (steven-cdist at armstrong.cc)
+#
+# This file is part of cdist.
+#
+# cdist is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# cdist is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with cdist. If not, see .
+#
+
+user="$(cat "$__object/parameter/user" 2>/dev/null || echo "$__object_id")"
+
+(id --groups --name "$user" | tr ' ' '\n' | sort) 2>/dev/null || true
diff --git a/cdist/conf/type/__user_groups/gencode-remote b/cdist/conf/type/__user_groups/gencode-remote
new file mode 100755
index 00000000..c5e4a35e
--- /dev/null
+++ b/cdist/conf/type/__user_groups/gencode-remote
@@ -0,0 +1,46 @@
+#!/bin/sh
+#
+# 2012 Steven Armstrong (steven-cdist at armstrong.cc)
+#
+# This file is part of cdist.
+#
+# cdist is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# cdist is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with cdist. If not, see .
+#
+
+user="$(cat "$__object/parameter/user" 2>/dev/null || echo "$__object_id")"
+state_should="$(cat "$__object/parameter/state" 2>/dev/null || echo "present")"
+
+mkdir "$__object/files"
+# file has to be sorted for comparison with `comm`
+sort "$__object/parameter/group" > "$__object/files/group.sorted"
+
+case "$state_should" in
+ present)
+ changed_groups="$(comm -13 "$__object/explorer/group" "$__object/files/group.sorted")"
+ action="-a"
+ ;;
+ absent)
+ changed_groups="$(comm -12 "$__object/explorer/group" "$__object/files/group.sorted")"
+ action="-d"
+ ;;
+esac
+
+if [ -z "$changed_groups" ]; then
+ # Nothing to do, move along
+ exit 0
+fi
+
+for group in $changed_groups; do
+ echo "gpasswd $action \"$user\" \"$group\""
+done
diff --git a/cdist/conf/type/__user_groups/man.text b/cdist/conf/type/__user_groups/man.text
new file mode 100644
index 00000000..d45784fe
--- /dev/null
+++ b/cdist/conf/type/__user_groups/man.text
@@ -0,0 +1,52 @@
+cdist-type__user_groups(7)
+==========================
+Steven Armstrong
+
+
+NAME
+----
+cdist-type__user_groups - manage user groups
+
+
+DESCRIPTION
+-----------
+Adds or removes a user from one or more groups.
+
+
+REQUIRED PARAMETERS
+-------------------
+group::
+ the group to which this user should be added or removed.
+ Can be specified multiple times.
+
+
+OPTIONAL PARAMETERS
+-------------------
+user::
+ the name of the user. Defaults to object_id
+
+state::
+ absent or present. Defaults to present.
+
+
+EXAMPLES
+--------
+
+--------------------------------------------------------------------------------
+__user_groups nginx --group webuser1 --group webuser2
+
+# remove user nginx from groups webuser2
+__user_groups nginx-webuser2 --user nginx \
+ --group webuser2 --state absent
+--------------------------------------------------------------------------------
+
+
+SEE ALSO
+--------
+- cdist-type(7)
+
+
+COPYING
+-------
+Copyright \(C) 2012 Steven Armstrong. Free use of this software is
+granted under the terms of the GNU General Public License version 3 (GPLv3).
diff --git a/cdist/conf/type/__user_groups/parameter/optional b/cdist/conf/type/__user_groups/parameter/optional
new file mode 100644
index 00000000..7d9ecf60
--- /dev/null
+++ b/cdist/conf/type/__user_groups/parameter/optional
@@ -0,0 +1,2 @@
+user
+state
diff --git a/cdist/conf/type/__user_groups/parameter/required_multiple b/cdist/conf/type/__user_groups/parameter/required_multiple
new file mode 100644
index 00000000..3a60ccec
--- /dev/null
+++ b/cdist/conf/type/__user_groups/parameter/required_multiple
@@ -0,0 +1 @@
+group