diff --git a/cdist/conf/type/__ssh_authorized_keys/explorer/entry b/cdist/conf/type/__ssh_authorized_keys/explorer/entry
new file mode 100755
index 00000000..9992d32d
--- /dev/null
+++ b/cdist/conf/type/__ssh_authorized_keys/explorer/entry
@@ -0,0 +1,45 @@
+#!/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 .
+#
+
+owner="$(cat "$__object/parameter/owner" 2>/dev/null || echo "$__object_id")"
+if [ -f "$__object/parameter/file" ]; then
+ file="$(cat "$__object/parameter/file")"
+else
+ home="$("$__type_explorer/passwd" | cut -d':' -f 6)"
+ file="$home/.ssh/authorized_keys"
+fi
+
+# no authorized_keys file, nothing we could do
+[ -f "$file" ] || exit 0
+
+# NOTE: keep variables in sync in manifest/explorer/gencode-*
+prefix="#cdist:$__object_name"
+suffix="#/cdist:$__object_name"
+awk -v prefix="$prefix" -v suffix="$suffix" '{
+ if (index($0,prefix)) {
+ triggered=1
+ }
+ if (triggered) {
+ if (index($0,suffix)) {
+ triggered=0
+ }
+ print
+ }
+}' "$file"
diff --git a/cdist/conf/type/__ssh_authorized_keys/explorer/passwd b/cdist/conf/type/__ssh_authorized_keys/explorer/passwd
new file mode 100755
index 00000000..e6352ee0
--- /dev/null
+++ b/cdist/conf/type/__ssh_authorized_keys/explorer/passwd
@@ -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 .
+#
+
+owner="$(cat "$__object/parameter/owner" 2>/dev/null || echo "$__object_id")"
+
+getent passwd "$owner" || true
diff --git a/cdist/conf/type/__ssh_authorized_keys/gencode-remote b/cdist/conf/type/__ssh_authorized_keys/gencode-remote
new file mode 100755
index 00000000..cc86cc19
--- /dev/null
+++ b/cdist/conf/type/__ssh_authorized_keys/gencode-remote
@@ -0,0 +1,82 @@
+#!/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 .
+#
+
+owner="$(cat "$__object/parameter/owner" 2>/dev/null || echo "$__object_id")"
+if [ -f "$__object/parameter/file" ]; then
+ file="$(cat "$__object/parameter/file")"
+else
+ home="$(cut -d':' -f 6 "$__object/explorer/passwd")"
+ file="$home/.ssh/authorized_keys"
+fi
+
+entry="$__object/files/entry"
+if [ ! -s "$__object/explorer/entry" ]; then
+ state_is='absent'
+else
+ state_is=$(diff -q "$entry" "$__object/explorer/entry" >/dev/null \
+ && echo present \
+ || echo changed
+ )
+fi
+
+state_should="$(cat "$__object/parameter/state" 2>/dev/null || echo present)"
+if [ "$state_should" = "$state_is" ]; then
+ # Nothing to do, move along
+ exit 0
+fi
+
+remove_entry() {
+ # NOTE: keep variables in sync in manifest/explorer/gencode-*
+ prefix="#cdist:$__object_name"
+ suffix="#/cdist:$__object_name"
+ cat << DONE
+tmpfile=\$(mktemp)
+awk -v prefix="$prefix" -v suffix="$suffix" '
+{
+ if (index(\$0,prefix)) {
+ triggered=1
+ }
+ if (triggered) {
+ if (index(\$0,suffix)) {
+ triggered=0
+ }
+ } else {
+ print
+ }
+}' "$file" > "\$tmpfile"
+mv -f "\$tmpfile" "$file"
+DONE
+}
+
+case "$state_should" in
+ present)
+ if [ "$state_is" = "changed" ]; then
+ remove_entry
+ fi
+ cat << DONE
+cat >> "$file" << ${__type##*/}_DONE
+$(cat "$entry")
+${__type##*/}_DONE
+DONE
+ ;;
+ absent)
+ remove_entry
+ ;;
+esac
diff --git a/cdist/conf/type/__ssh_authorized_keys/man.text b/cdist/conf/type/__ssh_authorized_keys/man.text
new file mode 100644
index 00000000..7177f26e
--- /dev/null
+++ b/cdist/conf/type/__ssh_authorized_keys/man.text
@@ -0,0 +1,101 @@
+cdist-type__ssh_authorized_keys(7)
+==================================
+Steven Armstrong
+
+
+NAME
+----
+cdist-type__ssh_authorized_keys - manage ssh authorized_keys files
+
+
+DESCRIPTION
+-----------
+Adds or removes ssh keys from a authorized_keys file.
+
+This type also manages the directory containing the authorized_keys
+file and sets strict ownership and permissions. You can disable this feature
+with the --noparent boolean parameter.
+
+The existence, ownership and permissions of the authorized_keys file itself are
+also managed. This can be disabled with the --nofile boolean parameter. It is
+then left to the user to ensure that the file exists and that ownership and
+permissions work with ssh.
+
+
+REQUIRED PARAMETERS
+-------------------
+key::
+ the ssh key which shall be added to this authorized_keys file.
+ Must be a string and can be specified multiple times.
+
+
+OPTIONAL PARAMETERS
+-------------------
+owner::
+ the user owning the authorized_keys file, defaults to object_id.
+
+state::
+ if the given keys should be 'present' or 'absent', defaults to 'present'.
+
+file::
+ an alternative destination file, defaults to ~$owner/.ssh/authorized_keys
+
+comment::
+ an optional comment
+
+
+BOOLEAN PARAMETERS
+------------------
+noparent::
+ don't create or change ownership and permissions of the directory containing
+ the authorized_keys file
+
+nofile::
+ don't manage existence, ownership and permissions of the the authorized_keys
+ file
+
+
+EXAMPLES
+--------
+
+--------------------------------------------------------------------------------
+# add your ssh key to remote root's authorized_keys file
+__ssh_authorized_keys root \
+ --key "$(cat ~/.ssh/id_rsa.pub)"
+
+# allow key to login as user-name
+__ssh_authorized_keys user-name \
+ --key "ssh-rsa AXYZAAB3NzaC1yc2..."
+
+# same as above, but with explicit owner, two keys and a comment
+__ssh_authorized_keys some-fancy-id \
+ --owner user-name \
+ --key "ssh-rsa AXYZAAB3NzaC1yc2..." \
+ --key "ssh-rsa AZXYAAB3NzaC1yc2..." \
+ --comment "allow the members of project foo to login"
+
+# same as above, but authorized_keys file in non standard location
+__ssh_authorized_keys some-fancy-id \
+ --file /etc/ssh/keys/user-name/authorized_keys \
+ --owner user-name \
+ --key "ssh-rsa AXYZAAB3NzaC1yc2..."
+
+# same as above, but directory and authorized_keys file is created elswhere
+__ssh_authorized_keys some-fancy-id \
+ --file /etc/ssh/keys/user-name/authorized_keys \
+ --owner user-name \
+ --noparent \
+ --nofile \
+ --key "ssh-rsa AXYZAAB3NzaC1yc2..."
+--------------------------------------------------------------------------------
+
+
+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/__ssh_authorized_keys/manifest b/cdist/conf/type/__ssh_authorized_keys/manifest
new file mode 100755
index 00000000..268b1fbe
--- /dev/null
+++ b/cdist/conf/type/__ssh_authorized_keys/manifest
@@ -0,0 +1,74 @@
+#!/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 .
+#
+
+owner="$(cat "$__object/parameter/owner" 2>/dev/null || echo "$__object_id")"
+state="$(cat "$__object/parameter/present" 2>/dev/null || echo "present")"
+if [ -f "$__object/parameter/file" ]; then
+ file="$(cat "$__object/parameter/file")"
+else
+ home="$(cut -d':' -f 6 "$__object/explorer/passwd")"
+ if [ -z "$home" ]; then
+ echo "Failed to get home directory from explorer." >&2
+ exit 1
+ fi
+ file="$home/.ssh/authorized_keys"
+fi
+
+if [ ! -f "$__object/parameter/noparent" -o ! -f "$__object/parameter/nofile" ]; then
+ group="$(cut -d':' -f 4 "$__object/explorer/passwd")"
+ if [ -z "$group" ]; then
+ echo "Failed to get owners group from explorer." >&2
+ exit 1
+ fi
+
+ if [ ! -f "$__object/parameter/noparent" ]; then
+ # Ensure that the directory in which the authorized_keys shall be exists and
+ # has the right permissions.
+ ssh_directory="${file%/*}"
+ __directory "$ssh_directory" --state present --parents \
+ --owner "$owner" --group "$group" --mode 0700
+ export require="__directory/$ssh_directory"
+ fi
+ if [ ! -f "$__object/parameter/nofile" ]; then
+ # Ensure that authorized_keys file exists and has the right permissions.
+ __file "$file" \
+ --owner "$owner" \
+ --group "$group" \
+ --mode 0600 \
+ --state exists
+ fi
+fi
+
+# NOTE: keep variables in sync in manifest/explorer/gencode-*
+prefix="#cdist:$__object_name"
+suffix="#/cdist:$__object_name"
+
+mkdir "$__object/files"
+
+# Generate entry for inclusion in authorized_keys file
+entry="$__object/files/entry"
+echo "$prefix" > "$entry"
+if [ -f "$__object/parameter/comment" ]; then
+ echo "# $(cat "$__object/parameter/comment")" >> "$entry"
+fi
+cat "$__object/parameter/key" >> "$entry"
+# ensure we have a newline after keys
+echo >> "$entry"
+echo "$suffix" >> "$entry"
diff --git a/cdist/conf/type/__ssh_authorized_keys/parameter/boolean b/cdist/conf/type/__ssh_authorized_keys/parameter/boolean
new file mode 100644
index 00000000..4bb126fe
--- /dev/null
+++ b/cdist/conf/type/__ssh_authorized_keys/parameter/boolean
@@ -0,0 +1,2 @@
+noparent
+nofile
diff --git a/cdist/conf/type/__ssh_authorized_keys/parameter/optional b/cdist/conf/type/__ssh_authorized_keys/parameter/optional
new file mode 100644
index 00000000..bfbd72ab
--- /dev/null
+++ b/cdist/conf/type/__ssh_authorized_keys/parameter/optional
@@ -0,0 +1,4 @@
+owner
+state
+file
+comment
diff --git a/cdist/conf/type/__ssh_authorized_keys/parameter/required_multiple b/cdist/conf/type/__ssh_authorized_keys/parameter/required_multiple
new file mode 100644
index 00000000..06bfde49
--- /dev/null
+++ b/cdist/conf/type/__ssh_authorized_keys/parameter/required_multiple
@@ -0,0 +1 @@
+key