diff --git a/Cargo.lock b/Cargo.lock
index 8ee6cc2..508b2f1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,12 +2,65 @@
 # It is not intended for manual editing.
 version = 4
 
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "deranged"
+version = "0.3.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
+dependencies = [
+ "powerfmt",
+]
+
+[[package]]
+name = "hostname"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f9c7c7c8ac16c798734b8a24560c1362120597c40d5e1459f09498f8f6c8f2ba"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "windows",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
+
 [[package]]
 name = "libc"
 version = "0.2.169"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
 
+[[package]]
+name = "log"
+version = "0.4.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
+
+[[package]]
+name = "num-conv"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
+
+[[package]]
+name = "num_threads"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9"
+dependencies = [
+ "libc",
+]
+
 [[package]]
 name = "pam-bindings"
 version = "0.1.1"
@@ -21,5 +74,196 @@ dependencies = [
 name = "pam-honeypot"
 version = "0.1.0"
 dependencies = [
+ "log",
  "pam-bindings",
+ "syslog",
 ]
+
+[[package]]
+name = "powerfmt"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.92"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.38"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "serde"
+version = "1.0.217"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.217"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.93"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syslog"
+version = "7.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "019f1500a13379b7d051455df397c75770de6311a7a188a699499502704d9f10"
+dependencies = [
+ "hostname",
+ "libc",
+ "log",
+ "time",
+]
+
+[[package]]
+name = "time"
+version = "0.3.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21"
+dependencies = [
+ "deranged",
+ "itoa",
+ "libc",
+ "num-conv",
+ "num_threads",
+ "powerfmt",
+ "serde",
+ "time-core",
+ "time-macros",
+]
+
+[[package]]
+name = "time-core"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
+
+[[package]]
+name = "time-macros"
+version = "0.2.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de"
+dependencies = [
+ "num-conv",
+ "time-core",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
+
+[[package]]
+name = "windows"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be"
+dependencies = [
+ "windows-core",
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-core"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_gnullvm",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
diff --git a/Cargo.toml b/Cargo.toml
index f303a78..126462b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -2,6 +2,8 @@
 name = "pam-honeypot"
 version = "0.1.0"
 edition = "2021"
+authors = [ "Tim Schubert <dadada@dadada.li>"]
+license = "MIT OR Apache-2.0"
 
 [lib]
 name = "pam_honeypot"
@@ -9,3 +11,5 @@ crate-type = ["cdylib"]
 
 [dependencies]
 pam-bindings = { version = "0.1.1" }
+log = "0"
+syslog = "7.0.0"
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..dac743a
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2024 Tim Schubert
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..240fc64
--- /dev/null
+++ b/README.md
@@ -0,0 +1,3 @@
+# PAM honeypot module
+
+Logs when a certain username and password is entered. The intended use-case are post-it notes with fake a username and password you can post around the office to check if anyone is attempting to log into machines that they should not have access to.
diff --git a/flake.nix b/flake.nix
index c4cb499..9fcb8f6 100644
--- a/flake.nix
+++ b/flake.nix
@@ -2,7 +2,7 @@
   description = "a653rs-router";
 
   inputs = {
-   flake-utils.url = "github:numtide/flake-utils";
+    flake-utils.url = "github:numtide/flake-utils";
   };
 
   outputs =
@@ -16,9 +16,9 @@
       let
         pkgs = import nixpkgs { inherit system; };
       in
-      {
+      rec {
         devShells.default = pkgs.mkShell {
-         nativeBuildInputs = [
+          nativeBuildInputs = [
             pkgs.cargo
             pkgs.clang
             pkgs.clippy
@@ -31,10 +31,25 @@
           ];
         };
         packages = {
-          default = pkgs.callPackage ./default.nix {};
+          default = pkgs.callPackage ./default.nix { };
+        };
+        checks = {
+          vm = nixpkgs.lib.nixos.runTest (
+            import ./test.nix {
+              pkgs = import nixpkgs {
+                inherit system;
+                overlays = [
+                  (final: prev: {
+                    pam_honeypot = packages.default;
+                  })
+                ];
+              };
+            }
+          );
         };
       }
-    ) // {
+    )
+    // {
       nixosModules = {
         default = ./module.nix;
       };
diff --git a/module.nix b/module.nix
index 744e664..4e4c7dd 100644
--- a/module.nix
+++ b/module.nix
@@ -1,6 +1,13 @@
-{ pkgs, ... }:
+{ config, pkgs, ... }:
 {
-  environment.etc."pam.d/pam_honeypot".text = ''
-    auth optional ${pkgs.pam_honeypot}/lib/pam_honeypot.so user=Admin password=AdminPwdQ1
-  '';
+  security.pam.services.login.rules.auth.pam_honeypot = {
+    enable = true;
+    order = config.security.pam.services.login.rules.auth.unix.order - 10;
+    control = "requisite";
+    modulePath = "${pkgs.pam_honeypot}/lib/libpam_honeypot.so";
+    args = [
+      "user=Admin"
+      "password=AdminPwdQ1"
+    ]; 
+  };
 }
diff --git a/src/lib.rs b/src/lib.rs
index dc03e9e..627e73e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,11 +1,14 @@
-use std::{collections::HashMap, env::temp_dir, ffi::CStr, fs::File};
+use std::{collections::HashMap, ffi::CStr};
 
+use log::{debug, info, trace, warn};
 use pam::{
-    constants::{PamResultCode, PAM_PROMPT_ECHO_ON},
+    constants::{PamResultCode, PAM_PROMPT_ECHO_OFF},
     conv::Conv,
+    items::User,
     module::PamHooks,
     pam_try,
 };
+use syslog::Facility;
 
 struct PamHoneypot;
 
@@ -15,12 +18,23 @@ impl PamHooks for PamHoneypot {
         args: Vec<&CStr>,
         _flags: pam::constants::PamFlag,
     ) -> pam::constants::PamResultCode {
+        let _ = syslog::init(
+            Facility::LOG_USER,
+            log::LevelFilter::Info,
+            Some("pam_honeypot"),
+        );
+
+        trace!("Running pam_honeypot");
         let args: Vec<_> = args.iter().map(|s| s.to_string_lossy()).collect();
+        debug!("args = {args:?}");
         let args: HashMap<&str, &str> = args
             .iter()
             .map(|s| {
                 let mut parts = s.splitn(2, '=');
-                (parts.next().unwrap(), parts.next().unwrap_or(""))
+                (
+                    parts.next().expect("Failed to parse arguments"),
+                    parts.next().unwrap_or(""),
+                )
             })
             .collect();
 
@@ -28,13 +42,16 @@ impl PamHooks for PamHoneypot {
             Some(user) => user,
             _ => return PamResultCode::PAM_IGNORE,
         };
+        debug!("honeypot user = {honey_user}");
         let honey_password = match args.get("password") {
             Some(password) => password,
             _ => return PamResultCode::PAM_IGNORE,
         };
 
-        let user = pam_try!(pamh.get_user(None));
-        if user != *honey_user {
+        trace!("Getting user from PAM");
+        let user: User = pam_try!(pamh.get_item()).unwrap_or(User(c""));
+        info!("Checking if entered username is honeypot user");
+        if user.to_string_lossy() != *honey_user {
             return PamResultCode::PAM_IGNORE;
         }
 
@@ -47,20 +64,21 @@ impl PamHooks for PamHoneypot {
                 return err;
             }
         };
-        let password = pam_try!(conv.send(PAM_PROMPT_ECHO_ON, "Password"));
+        trace!("Getting password from PAM");
+        let password = pam_try!(conv.send(PAM_PROMPT_ECHO_OFF, "Password: "));
         let password = match password {
             Some(password) => Some(pam_try!(password.to_str(), PamResultCode::PAM_AUTH_ERR)),
             _ => None,
         };
 
         if let Some(password) = password {
+            trace!("Checking if password is honeypot password");
             if *honey_password == password {
-                let mut tmp = temp_dir();
-                tmp.push("honeypot");
-                let _ = File::create(tmp);
-
-                return PamResultCode::PAM_AUTH_ERR;
+                warn!("Someone tried to log in with the honeypot credentials");
+            } else {
+                info!("Entered username is not the honeypot user")
             }
+            return PamResultCode::PAM_AUTH_ERR;
         }
 
         PamResultCode::PAM_IGNORE
diff --git a/test.nix b/test.nix
new file mode 100644
index 0000000..39c162b
--- /dev/null
+++ b/test.nix
@@ -0,0 +1,29 @@
+{
+  pkgs,
+  ...
+}:
+{
+  name = "pam_honeypot-test";
+  hostPkgs = pkgs;
+  node.pkgs = pkgs;
+  nodes.machine =
+    { ... }:
+    {
+      imports = [ ./module.nix ];
+    };
+  testScript = ''
+    machine.wait_for_unit("multi-user.target")
+    machine.send_key("alt-f2")
+    machine.wait_until_succeeds("[ $(fgconsole) = 2 ]")
+    machine.wait_for_unit("getty@tty2.service")
+    machine.wait_until_succeeds("pgrep -f 'agetty.*tty2'")
+    machine.wait_until_tty_matches("2", "login: ")
+    machine.send_chars("Admin\n")
+    machine.wait_until_tty_matches("2", "login: Admin")
+    machine.wait_until_succeeds("pgrep login")
+    machine.wait_until_tty_matches("2", "Password: ")
+    machine.send_chars("AdminPwdQ1\n")
+    machine.wait_until_tty_matches("2", "login: ")
+    machine.succeed("journalctl | grep 'log in with the honeypot credentials'")
+  '';
+}