diff --git a/LICENSE b/LICENSE
index 52ec1c16d8ce2612c024cdee8740c7506c37d036..47d69b957cd70dd890023ed0871f7a01ad94e010 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-   Copyright (c) 2013 Salt Stack Formulas
+   Copyright (c) 2013-2014 Salt Stack Formulas
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
diff --git a/README.rst b/README.rst
index e16ba66292fc21a472ae3fca9147f4ff1c3f74c7..d41cb55e2e1af04169f3f39279ca0cd67aa0f83f 100644
--- a/README.rst
+++ b/README.rst
@@ -18,20 +18,26 @@ Available states
 
 Installs the ``openssh`` server package and service.
 
-``openssh.config``
+``openssh.auth``
+-----------
+
+Manages SSH certificates for users.
+
+``openssh.banner``
 ------------------
 
-Installs the ssh daemon configuration file included in this formula
-(under "openssh/files"). This configuration file is populated
-by values from pillar. ``pillar.example`` results in the generation
-of the default ``sshd_config`` file on Debian Wheezy.
+Installs a banner that users see when SSH-ing in.
 
 ``openssh.client``
 ------------------
 
 Installs the openssh client package.
 
-``openssh.banner``
+``openssh.config``
 ------------------
 
-Installs a banner that users see when SSH-ing in.
+Installs the ssh daemon configuration file included in this formula
+(under "openssh/files"). This configuration file is populated
+by values from pillar. ``pillar.example`` results in the generation
+of the default ``sshd_config`` file on Debian Wheezy.
+
diff --git a/openssh/auth.sls b/openssh/auth.sls
new file mode 100644
index 0000000000000000000000000000000000000000..f7690b38a03a93ed587123597dda4b52007410a9
--- /dev/null
+++ b/openssh/auth.sls
@@ -0,0 +1,43 @@
+include:
+  - openssh
+
+{% from "openssh/map.jinja" import openssh with context %}
+{% set openssh_pillar = pillar.get('openssh', {}) %}
+{% set auth = openssh_pillar.get('auth', {}) %}
+{% for user,keys in auth.items() -%}
+  {% for key in keys -%}
+    {% if 'present' in key and key['present'] %}
+{{ key['name'] }}:
+  ssh_auth.present:
+    - user: {{ user }}
+      {% if 'source' in key %}
+    - source: {{ key['source'] }}
+      {% else %}
+        {% if 'enc' in key %}
+    - enc: {{ key['enc'] }}
+        {% endif %}
+        {% if 'comment' in key %}
+    - comment: {{ key['comment'] }}
+        {% endif %}
+        {% if 'options' in key %}
+    - options: {{ key['options'] }}
+        {% endif %}
+      {% endif %}
+    - require:
+      - service: {{ openssh.service }}
+    {% else %}
+{{ key['name'] }}:
+  ssh_auth.absent:
+    - user: {{ user }}
+      {% if 'enc' in key %}
+    - enc: {{ key['enc'] }}
+      {% endif %}
+      {% if 'comment' in key %}
+    - comment: {{ key['comment'] }}
+      {% endif %}
+      {% if 'options' in key %}
+    - options: {{ key['options'] }}
+      {% endif %}
+    {% endif %}
+  {% endfor %}
+{% endfor %}
diff --git a/openssh/files/sshd_config b/openssh/files/sshd_config
index 43e25666e6726566bfdaa8b5629aec2f5e705ab8..496f1e0074057dd22a847565d571ed8c5acc5d3b 100644
--- a/openssh/files/sshd_config
+++ b/openssh/files/sshd_config
@@ -1,4 +1,5 @@
-{% set sshd_config = pillar.get('sshd_config', {}) %}
+{% set openssh_pillar = pillar.get('openssh', {}) %}
+{% set sshd_config = openssh_pillar.get('sshd_config', {}) %}
 
 # This file is managed by salt. Manual changes risk being overwritten.
 # The contents of the original sshd_config are kept on the bottom for
diff --git a/pillar.example b/pillar.example
index 53db7c0e98a4f9ec3f60a8efc59b62028bc2848f..c8e4067827a1540359c1d32b498e43f70b832fe5 100644
--- a/pillar.example
+++ b/pillar.example
@@ -1,30 +1,43 @@
-sshd_config:
-  Port: 22
-  Protocol: 2
-  HostKey:
-    - /etc/ssh/ssh_host_rsa_key
-    - /etc/ssh/ssh_host_dsa_key
-    - /etc/ssh/ssh_host_ecdsa_key
-  UsePrivilegeSeparation: yes
-  KeyRegenerationInterval: 3600
-  ServerKeyBits: 768
-  SyslogFacility: AUTH
-  LogLevel: INFO
-  LoginGraceTime: 120
-  PermitRootLogin: yes
-  StrictModes: yes
-  RSAAuthentication: yes
-  PubkeyAuthentication: yes
-  IgnoreRhosts: yes
-  RhostsRSAAuthentication: no
-  HostbasedAuthentication: no
-  PermitEmptyPasswords: no
-  ChallengeResponseAuthentication: no
-  X11Forwarding: yes
-  X11DisplayOffset: 10
-  PrintMotd: no
-  PrintLastLog: yes
-  TCPKeepAlive: yes
-  AcceptEnv: "LANG LC_*"
-  Subsystem: "sftp /usr/lib/openssh/sftp-server"
-  UsePAM: yes
+openssh:
+  sshd_config:
+    Port: 22
+    Protocol: 2
+    HostKey:
+      - /etc/ssh/ssh_host_rsa_key
+      - /etc/ssh/ssh_host_dsa_key
+      - /etc/ssh/ssh_host_ecdsa_key
+    UsePrivilegeSeparation: yes
+    KeyRegenerationInterval: 3600
+    ServerKeyBits: 768
+    SyslogFacility: AUTH
+    LogLevel: INFO
+    LoginGraceTime: 120
+    PermitRootLogin: yes
+    StrictModes: yes
+    RSAAuthentication: yes
+    PubkeyAuthentication: yes
+    IgnoreRhosts: yes
+    RhostsRSAAuthentication: no
+    HostbasedAuthentication: no
+    PermitEmptyPasswords: no
+    ChallengeResponseAuthentication: no
+    X11Forwarding: yes
+    X11DisplayOffset: 10
+    PrintMotd: no
+    PrintLastLog: yes
+    TCPKeepAlive: yes
+    AcceptEnv: "LANG LC_*"
+    Subsystem: "sftp /usr/lib/openssh/sftp-server"
+    UsePAM: yes
+
+  auth:
+    joe:
+      - name: JOE_VALID_SSH_PUBLIC_KEY
+        present: True
+        enc: ssh-rsa
+        comment: main key
+      - name: JOE_NON_VALID_SSH_PUBLIC_KEY
+        present: False
+        enc: ssh-rsa
+        comment: obsolete key - removed
+