diff --git a/src/api/ssh_keys_delete.c b/src/api/ssh_keys_delete.c
new file mode 100644
index 0000000000000000000000000000000000000000..27874e7583443d8159f03ac09987cadbc232ec1b
--- /dev/null
+++ b/src/api/ssh_keys_delete.c
@@ -0,0 +1,54 @@
+/**
+ * Callback function that deletes an SSH key from the list of keys authorised
+ * for access to the initrd. The line will be left empty, because that keeps
+ * the ids if SSH keys in tact for ssh_keys_get
+ *
+ * Example output:
+ * {"ssh-keys":{"1":"ssh-rsa AAAAB3... example@example.com",
+ * "2":"ssh-rsa AAAAB3...","5":"command=\"/usr/bin/cryptops-client\" ssh-rsa
+ *  AAAAB3... cryptops-test@greenhost"}}
+ *
+ * The indices correspond to line numbers of the authorized_keys file.
+ * Missing indices (like 3 and 4 in the example) arise from empty lines in the
+ * file; those are creted when keys are deleted.
+ *
+ * @param[in]   request   incoming HTTP request
+ * @param[out]  response  HTTP response to the request
+ * @param[in]   user_data extra data to pass between main thread and callbacks
+ * @return                internal status code
+ */
+int callback_ssh_keys_delete(const struct _u_request * request,
+    struct _u_response * response, void * user_data)
+{
+    // Read ssh key id from request URI.
+    const char * id_string = u_map_get(request->map_url, "id");
+    if (id_string == NULL)
+    {
+        return send_simple_response(response, 400, "error",
+            "missing url parameter `id`");
+    }
+
+    int id;
+    int r = parse_int(id_string, &id);
+    if (r != 0)
+    {
+        printf("invalid url parameter `id`: %s\n", id_string);
+        return send_simple_response(response, 400, "error",
+            "invalid url parameter `id`");
+    }
+
+    // Replace the key at ID with ""
+    r = replace_ssh_key(id, "");
+    if(r < 0)
+    {
+        if(r == -1)
+            return send_simple_response(response, 500, "error",
+                "error opening authorized_keys");
+        if(r == -2)
+            return send_simple_response(response, 500, "error",
+                "error opening authorized_keys tmp file");
+        return send_simple_response(response, 500, "error",
+            "Unknown error while processing ssh keys");
+    }
+    return send_simple_response(response, 200, "status", "ok");
+}
diff --git a/src/api/ssh_keys_put.c b/src/api/ssh_keys_put.c
new file mode 100644
index 0000000000000000000000000000000000000000..4503e5dfd6b9a77e9d727052209d9d05204261d8
--- /dev/null
+++ b/src/api/ssh_keys_put.c
@@ -0,0 +1,66 @@
+
+
+/**
+ * Callback function that deletes an SSH key from the list of keys authorised
+ * for access to the initrd. The line will be left empty, because that keeps
+ * the ids if SSH keys in tact for ssh_keys_get
+ *
+ * Example output:
+ * {"ssh-keys":{"1":"ssh-rsa AAAAB3... example@example.com",
+ * "2":"ssh-rsa AAAAB3...","5":"command=\"/usr/bin/cryptops-client\" ssh-rsa
+ *  AAAAB3... cryptops-test@greenhost"}}
+ *
+ * The indices correspond to line numbers of the authorized_keys file.
+ * Missing indices (like 3 and 4 in the example) arise from empty lines in the
+ * file; those are creted when keys are deleted.
+ *
+ * @param[in]   request   incoming HTTP request
+ * @param[out]  response  HTTP response to the request
+ * @param[in]   user_data extra data to pass between main thread and callbacks
+ * @return                internal status code
+ */
+int callback_ssh_keys_put(const struct _u_request * request,
+    struct _u_response * response, void * user_data)
+{
+    // Read ssh key id from request URI.
+    const char * id_string = u_map_get(request->map_url, "id");
+    if (id_string == NULL)
+    {
+        return send_simple_response(response, 400, "error",
+            "missing url parameter `id`");
+    }
+
+    int id;
+    int r = parse_int(id_string, &id);
+    if (r != 0)
+    {
+        printf("invalid url parameter `id`: %s\n", id_string);
+        return send_simple_response(response, 400, "error",
+            "invalid url parameter `id`");
+    }
+
+    // Read in json request body.
+    json_t * json_input = ulfius_get_json_body_request(request, NULL);
+
+    // Read SSH key from request.
+    const char * ssh_key;
+    ssh_key = json_string_value(json_object_get(json_input, "ssh-key"));
+    if (ssh_key == NULL)
+    {
+        return send_simple_response(response, 400, "error", "missing ssh-key");
+    }
+
+    r = replace_ssh_key(id, ssh_key);
+    if(r < 0)
+    {
+        if(r == -1)
+            return send_simple_response(response, 500, "error",
+                "error opening authorized_keys");
+        if(r == -2)
+            return send_simple_response(response, 500, "error",
+                "error opening authorized_keys tmp file");
+        return send_simple_response(response, 500, "error",
+            "Unknown error while processing ssh keys");
+    }
+    return send_simple_response(response, 200, "status", "ok");
+}
diff --git a/src/auxiliary.c b/src/auxiliary.c
index c05da344af7476fe4e9bc36b8dcef94d062585ca..b5fcb2efab437781ef01b0456ecff4ed46649a38 100644
--- a/src/auxiliary.c
+++ b/src/auxiliary.c
@@ -191,3 +191,90 @@ int parse_int(const char * input, int * result)
     *result = l;
     return 0;
 }
+
+/**
+ * Write an ssh_key to a specific rule in the authorized_keys file.
+ *
+ * @param[in]   id      line number/ssh_key id
+ * @param[in]   ssh_key ssh key contents. If this string is empty, this is seen
+ *                      as deleting the key. Newline characters are ignored
+ */
+int replace_ssh_key(int id, const char * ssh_key)
+{
+    // Open file.
+    FILE * authorized_keys_in = fopen(AUTHORIZED_KEYS_PATH, "r");
+    // Check if that succeeded.
+    if (authorized_keys_in == NULL)
+    {
+        printf("Could not open authorized_keys file for reading\n");
+        return -1;
+    }
+
+    // Make tmp outfile for authorized keys
+    char * authorized_keys_out_name;
+    asprintf(&authorized_keys_out_name, "%s%s", AUTHORIZED_KEYS_PATH, ".tmp");
+
+    // Open file.
+    FILE * authorized_keys_out = fopen(authorized_keys_out_name, "w");
+    // Check if that succeeded.
+    if (authorized_keys_out == NULL)
+    {
+        printf("Could not open authorized_keys tmp file for writing\n");
+        return -2;
+    }
+
+    int line_number = 1;
+    char ch;
+
+    // Loop through all the characters in the input file
+    do {
+        ch = getc(authorized_keys_in);
+
+        if (ch == '\n')
+            line_number++;
+
+        if (line_number != id)
+        {
+            // Copy all lines that don't have id as line number
+            putc(ch, authorized_keys_out);
+        }
+        else
+        {
+            // Insert the new line first
+            putc(ch);
+
+            // Copy ssh_key to the line that has id as line number
+            // Some magic happens here, where *ssh_key++ returns the current
+            // index and moves the pointer to the next index of ssh_key
+            // TODO: prepend ssh_key with command= line
+            while(*ssh_key)
+            {
+                printf("inserting %c\n", *ssh_key);
+                if(*ssh_key != '\n' && *ssh_key != '\r')
+                {
+                    putc(*ssh_key++, authorized_keys_out);
+                }
+            }
+            printf("inserting new line %c\n", *ssh_key);
+            putc('\n', authorized_keys_out);
+            // Read characters until the next newline
+            do {
+                printf("not inserting %c\n", ch);
+                ch = getc(authorized_keys_in);
+            } while (ch != EOF && ch != '\n');
+            printf("increasing line number to %d\n", line_number + 1);
+            // Increment line_number because the next loop will read a new
+            // character
+            line_number++;
+        }
+    } while (ch != EOF);
+
+
+    fclose(authorized_keys_in);
+    fclose(authorized_keys_out);
+
+    // Remove old authorized_keys file and replace it with the new one
+    remove(AUTHORIZED_KEYS_PATH);
+    rename(authorized_keys_out_name, AUTHORIZED_KEYS_PATH);
+    return 0;
+}
diff --git a/src/cryptops-api.c b/src/cryptops-api.c
index faaf253e4f8d3df0db6f20b0a6eaba4e17726663..de28f6c4c48129e98d58bc8cadd8c99fe331c038 100644
--- a/src/cryptops-api.c
+++ b/src/cryptops-api.c
@@ -10,7 +10,9 @@
 #include <api/encryption_unlock.c>
 #include <api/encryption_keys_put.c>
 #include <api/ssh_keys_get.c>
+#include <api/ssh_keys_put.c>
 #include <api/ssh_keys_post.c>
+#include <api/ssh_keys_delete.c>
 
 int main(int argc, char ** argv)
 {
@@ -50,9 +52,15 @@ int main(int argc, char ** argv)
     ulfius_add_endpoint_by_val(&instance, "GET" , PREFIX,
         "/ssh/keys",
         0, &callback_ssh_keys_get, NULL);
+    ulfius_add_endpoint_by_val(&instance, "PUT" , PREFIX,
+        "/ssh/keys/:id",
+        0, &callback_ssh_keys_put, NULL);
     ulfius_add_endpoint_by_val(&instance, "POST" , PREFIX,
         "/ssh/keys",
         0, &callback_ssh_keys_post, NULL);
+    ulfius_add_endpoint_by_val(&instance, "DELETE" , PREFIX,
+        "/ssh/keys/:id",
+        0, &callback_ssh_keys_delete, NULL);
 
     // Add default endpoint.
     ulfius_set_default_endpoint(&instance, &callback_default, NULL);