diff --git a/default.nix b/default.nix
index 3e33118f25b1e31833674edef9e90f8450146c1e..0a9c3cf10ec844c3e712aafcbc1e0a426f73b50c 100644
--- a/default.nix
+++ b/default.nix
@@ -1,2 +1,14 @@
 { pkgs ? import <nixpkgs> { } }:
-pkgs.python37Packages.callPackage ./secure-access-token-authorizer.nix { }
+let
+  eliot = pkgs.pythonPackages.callPackage ./eliot.nix { };
+
+  # tahoe-lafs in nixpkgs is packaged as an application!  so we have to
+  # re-package it ourselves as a library.
+  tahoe-lafs = pkgs.pythonPackages.callPackage ./tahoe-lafs.nix {
+    inherit eliot;
+  };
+
+in
+  pkgs.pythonPackages.callPackage ./secure-access-token-authorizer.nix {
+    inherit tahoe-lafs;
+  }
diff --git a/eliot.nix b/eliot.nix
new file mode 100644
index 0000000000000000000000000000000000000000..f6d6b3061b1ea635bac0e694be407ca8d1b6befb
--- /dev/null
+++ b/eliot.nix
@@ -0,0 +1,27 @@
+{ lib, buildPythonPackage, fetchPypi, zope_interface, pyrsistent, boltons
+, hypothesis, testtools, pytest }:
+buildPythonPackage rec {
+  pname = "eliot";
+  version = "1.7.0";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "0ylyycf717s5qsrx8b9n6m38vyj2k8328lfhn8y6r31824991wv8";
+  };
+
+  postPatch = ''
+    substituteInPlace setup.py \
+      --replace "boltons >= 19.0.1" boltons
+    # depends on eliot.prettyprint._main which we don't have here.
+    rm eliot/tests/test_prettyprint.py
+  '';
+
+  checkInputs = [ testtools pytest hypothesis ];
+  propagatedBuildInputs = [ zope_interface pyrsistent boltons ];
+
+  meta = with lib; {
+    homepage = https://github.com/itamarst/eliot/;
+    description = "Logging library that tells you why it happened";
+    license = licenses.asl20;
+  };
+}
diff --git a/secure-access-token-authorizer.nix b/secure-access-token-authorizer.nix
index 3b916b34997f45552dd8a4cacdad917935accdf6..be5fabe508d62a74a32234d1678709696a86c981 100644
--- a/secure-access-token-authorizer.nix
+++ b/secure-access-token-authorizer.nix
@@ -1,7 +1,24 @@
-{ buildPythonPackage, sphinx }:
+{ buildPythonPackage, sphinx, circleci-cli, pythonPackages, tahoe-lafs }:
 buildPythonPackage rec {
   version = "0.0";
   name = "secure-access-token-authorizer-${version}";
   src = ./.;
-  depsBuildBuild = [ sphinx ];
+  depsBuildBuild = [
+    sphinx
+    circleci-cli
+  ];
+
+  propagatedBuildInputs = with pythonPackages; [
+    zope_interface
+    twisted
+    tahoe-lafs
+  ];
+
+  checkInputs = with pythonPackages; [
+    testtools
+  ];
+
+  checkPhase = ''
+    ${pythonPackages.twisted}/bin/trial _secureaccesstokenauthorizer
+  '';
 }
diff --git a/shell.nix b/shell.nix
new file mode 100644
index 0000000000000000000000000000000000000000..168abb10b509c767145d4861c0d91c9375775ce5
--- /dev/null
+++ b/shell.nix
@@ -0,0 +1,7 @@
+{ pkgs ? import <nixpkgs> { } }:
+(pkgs.python27.buildEnv.override {
+  extraLibs = [
+    (pkgs.callPackage ./default.nix { })
+  ];
+  ignoreCollisions = true;
+}).env
diff --git a/tahoe-lafs.nix b/tahoe-lafs.nix
new file mode 100644
index 0000000000000000000000000000000000000000..da0f4e6c8f1d6a9de490dbd6c9e8ccbb1296c259
--- /dev/null
+++ b/tahoe-lafs.nix
@@ -0,0 +1,32 @@
+{ nettools, pythonPackages, buildPythonPackage, eliot }:
+buildPythonPackage rec {
+  version = "1.14.0.dev";
+  name = "tahoe-lafs-${version}";
+  src = ~/Work/python/tahoe-lafs;
+
+  postPatch = ''
+    sed -i "src/allmydata/util/iputil.py" \
+        -es"|_linux_path = '/sbin/ifconfig'|_linux_path = '${nettools}/bin/ifconfig'|g"
+
+    # Chroots don't have /etc/hosts and /etc/resolv.conf, so work around
+    # that.
+    for i in $(find src/allmydata/test -type f)
+    do
+      sed -i "$i" -e"s/localhost/127.0.0.1/g"
+    done
+
+    sed -i 's/"zope.interface.*"/"zope.interface"/' src/allmydata/_auto_deps.py
+    sed -i 's/"pycrypto.*"/"pycrypto"/' src/allmydata/_auto_deps.py
+  '';
+
+
+  propagatedBuildInputs = with pythonPackages; [
+    twisted foolscap nevow simplejson zfec pycryptopp darcsver
+    setuptoolsTrial setuptoolsDarcs pycrypto pyasn1 zope_interface
+    service-identity pyyaml magic-wormhole treq appdirs
+
+    eliot
+  ];
+
+  doCheck = false;
+}