diff --git a/services/identity/Cargo.lock b/services/identity/Cargo.lock
--- a/services/identity/Cargo.lock
+++ b/services/identity/Cargo.lock
@@ -106,35 +106,6 @@
  "password-hash",
 ]
 
-[[package]]
-name = "async-io"
-version = "1.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af"
-dependencies = [
- "async-lock",
- "autocfg",
- "cfg-if",
- "concurrent-queue",
- "futures-lite",
- "log",
- "parking",
- "polling",
- "rustix 0.37.27",
- "slab",
- "socket2 0.4.10",
- "waker-fn",
-]
-
-[[package]]
-name = "async-lock"
-version = "2.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b"
-dependencies = [
- "event-listener",
-]
-
 [[package]]
 name = "async-stream"
 version = "0.3.5"
@@ -658,12 +629,6 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
 
-[[package]]
-name = "bytecount"
-version = "0.6.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205"
-
 [[package]]
 name = "byteorder"
 version = "1.5.0"
@@ -686,37 +651,6 @@
  "either",
 ]
 
-[[package]]
-name = "camino"
-version = "1.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "cargo-platform"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ceed8ef69d8518a5dda55c07425450b58a4e1946f4951eab6d7191ee86c2443d"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "cargo_metadata"
-version = "0.14.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa"
-dependencies = [
- "camino",
- "cargo-platform",
- "semver",
- "serde",
- "serde_json",
-]
-
 [[package]]
 name = "cc"
 version = "1.0.83"
@@ -829,15 +763,6 @@
  "wasm-bindgen",
 ]
 
-[[package]]
-name = "concurrent-queue"
-version = "2.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363"
-dependencies = [
- "crossbeam-utils",
-]
-
 [[package]]
 name = "const-oid"
 version = "0.9.6"
@@ -887,30 +812,6 @@
  "libc",
 ]
 
-[[package]]
-name = "crossbeam-channel"
-version = "0.5.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "176dc175b78f56c0f321911d9c8eb2b77a78a4860b9c19db83835fea1a46649b"
-dependencies = [
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-epoch"
-version = "0.9.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
-dependencies = [
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-utils"
-version = "0.8.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
-
 [[package]]
 name = "crypto-bigint"
 version = "0.2.5"
@@ -1166,21 +1067,6 @@
  "windows-sys 0.52.0",
 ]
 
-[[package]]
-name = "error-chain"
-version = "0.12.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc"
-dependencies = [
- "version_check",
-]
-
-[[package]]
-name = "event-listener"
-version = "2.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
-
 [[package]]
 name = "fastrand"
 version = "1.9.0"
@@ -1300,21 +1186,6 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
 
-[[package]]
-name = "futures-lite"
-version = "1.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce"
-dependencies = [
- "fastrand 1.9.0",
- "futures-core",
- "futures-io",
- "memchr",
- "parking",
- "pin-project-lite",
- "waker-fn",
-]
-
 [[package]]
 name = "futures-macro"
 version = "0.3.30"
@@ -1395,12 +1266,6 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
 
-[[package]]
-name = "glob"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
-
 [[package]]
 name = "group"
 version = "0.10.0"
@@ -1579,7 +1444,7 @@
  "httpdate",
  "itoa",
  "pin-project-lite",
- "socket2 0.5.5",
+ "socket2",
  "tokio",
  "tower-service",
  "tracing",
@@ -1682,7 +1547,6 @@
  "hyper",
  "hyper-tungstenite",
  "identity_search_messages",
- "moka",
  "once_cell",
  "prost",
  "rand 0.8.5",
@@ -1751,17 +1615,6 @@
  "cfg-if",
 ]
 
-[[package]]
-name = "io-lifetimes"
-version = "1.0.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
-dependencies = [
- "hermit-abi",
- "libc",
- "windows-sys 0.48.0",
-]
-
 [[package]]
 name = "ipnet"
 version = "2.9.0"
@@ -1834,43 +1687,18 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7"
 
-[[package]]
-name = "linux-raw-sys"
-version = "0.3.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
-
 [[package]]
 name = "linux-raw-sys"
 version = "0.4.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456"
 
-[[package]]
-name = "lock_api"
-version = "0.4.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
-dependencies = [
- "autocfg",
- "scopeguard",
-]
-
 [[package]]
 name = "log"
 version = "0.4.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
 
-[[package]]
-name = "mach2"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709"
-dependencies = [
- "libc",
-]
-
 [[package]]
 name = "matchers"
 version = "0.1.0"
@@ -1924,32 +1752,6 @@
  "windows-sys 0.48.0",
 ]
 
-[[package]]
-name = "moka"
-version = "0.10.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0be0a3dd6fe7c99233c2b1476e703147fb7516c68dce585b19b51efc08fe93d8"
-dependencies = [
- "async-io",
- "async-lock",
- "crossbeam-channel",
- "crossbeam-epoch",
- "crossbeam-utils",
- "futures-util",
- "num_cpus",
- "once_cell",
- "parking_lot",
- "quanta",
- "rustc_version",
- "scheduled-thread-pool",
- "skeptic",
- "smallvec",
- "tagptr",
- "thiserror",
- "triomphe",
- "uuid",
-]
-
 [[package]]
 name = "multimap"
 version = "0.8.3"
@@ -2122,35 +1924,6 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
 
-[[package]]
-name = "parking"
-version = "2.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae"
-
-[[package]]
-name = "parking_lot"
-version = "0.12.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
-dependencies = [
- "lock_api",
- "parking_lot_core",
-]
-
-[[package]]
-name = "parking_lot_core"
-version = "0.9.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e"
-dependencies = [
- "cfg-if",
- "libc",
- "redox_syscall",
- "smallvec",
- "windows-targets 0.48.5",
-]
-
 [[package]]
 name = "password-hash"
 version = "0.4.2"
@@ -2216,22 +1989,6 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a"
 
-[[package]]
-name = "polling"
-version = "2.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce"
-dependencies = [
- "autocfg",
- "bitflags 1.3.2",
- "cfg-if",
- "concurrent-queue",
- "libc",
- "log",
- "pin-project-lite",
- "windows-sys 0.48.0",
-]
-
 [[package]]
 name = "powerfmt"
 version = "0.2.0"
@@ -2317,33 +2074,6 @@
  "prost",
 ]
 
-[[package]]
-name = "pulldown-cmark"
-version = "0.9.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77a1a2f1f0a7ecff9c31abbe177637be0e97a0aef46cf8738ece09327985d998"
-dependencies = [
- "bitflags 1.3.2",
- "memchr",
- "unicase",
-]
-
-[[package]]
-name = "quanta"
-version = "0.11.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a17e662a7a8291a865152364c20c7abc5e60486ab2001e8ec10b24862de0b9ab"
-dependencies = [
- "crossbeam-utils",
- "libc",
- "mach2",
- "once_cell",
- "raw-cpuid",
- "wasi 0.11.0+wasi-snapshot-preview1",
- "web-sys",
- "winapi",
-]
-
 [[package]]
 name = "quote"
 version = "1.0.35"
@@ -2424,15 +2154,6 @@
  "rand_core 0.5.1",
 ]
 
-[[package]]
-name = "raw-cpuid"
-version = "10.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332"
-dependencies = [
- "bitflags 1.3.2",
-]
-
 [[package]]
 name = "redox_syscall"
 version = "0.4.1"
@@ -2568,20 +2289,6 @@
  "semver",
 ]
 
-[[package]]
-name = "rustix"
-version = "0.37.27"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2"
-dependencies = [
- "bitflags 1.3.2",
- "errno",
- "io-lifetimes",
- "libc",
- "linux-raw-sys 0.3.8",
- "windows-sys 0.48.0",
-]
-
 [[package]]
 name = "rustix"
 version = "0.38.28"
@@ -2591,7 +2298,7 @@
  "bitflags 2.4.1",
  "errno",
  "libc",
- "linux-raw-sys 0.4.12",
+ "linux-raw-sys",
  "windows-sys 0.52.0",
 ]
 
@@ -2672,15 +2379,6 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
 
-[[package]]
-name = "same-file"
-version = "1.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
-dependencies = [
- "winapi-util",
-]
-
 [[package]]
 name = "schannel"
 version = "0.1.23"
@@ -2690,21 +2388,6 @@
  "windows-sys 0.52.0",
 ]
 
-[[package]]
-name = "scheduled-thread-pool"
-version = "0.2.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19"
-dependencies = [
- "parking_lot",
-]
-
-[[package]]
-name = "scopeguard"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
-
 [[package]]
 name = "sct"
 version = "0.7.1"
@@ -2756,9 +2439,6 @@
 version = "1.0.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0"
-dependencies = [
- "serde",
-]
 
 [[package]]
 name = "serde"
@@ -2885,21 +2565,6 @@
  "thiserror",
 ]
 
-[[package]]
-name = "skeptic"
-version = "0.13.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "16d23b015676c90a0f01c197bfdc786c20342c73a0afdda9025adb0bc42940a8"
-dependencies = [
- "bytecount",
- "cargo_metadata",
- "error-chain",
- "glob",
- "pulldown-cmark",
- "tempfile",
- "walkdir",
-]
-
 [[package]]
 name = "slab"
 version = "0.4.9"
@@ -2915,16 +2580,6 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
 
-[[package]]
-name = "socket2"
-version = "0.4.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d"
-dependencies = [
- "libc",
- "winapi",
-]
-
 [[package]]
 name = "socket2"
 version = "0.5.5"
@@ -3008,12 +2663,6 @@
  "libc",
 ]
 
-[[package]]
-name = "tagptr"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417"
-
 [[package]]
 name = "tempfile"
 version = "3.9.0"
@@ -3023,7 +2672,7 @@
  "cfg-if",
  "fastrand 2.0.1",
  "redox_syscall",
- "rustix 0.38.28",
+ "rustix",
  "windows-sys 0.52.0",
 ]
 
@@ -3112,7 +2761,7 @@
  "mio",
  "num_cpus",
  "pin-project-lite",
- "socket2 0.5.5",
+ "socket2",
  "tokio-macros",
  "windows-sys 0.48.0",
 ]
@@ -3383,12 +3032,6 @@
  "tracing-log",
 ]
 
-[[package]]
-name = "triomphe"
-version = "0.1.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3"
-
 [[package]]
 name = "try-lock"
 version = "0.2.5"
@@ -3429,15 +3072,6 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
 
-[[package]]
-name = "unicase"
-version = "2.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89"
-dependencies = [
- "version_check",
-]
-
 [[package]]
 name = "unicode-bidi"
 version = "0.3.14"
@@ -3552,22 +3186,6 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64"
 
-[[package]]
-name = "waker-fn"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690"
-
-[[package]]
-name = "walkdir"
-version = "2.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee"
-dependencies = [
- "same-file",
- "winapi-util",
-]
-
 [[package]]
 name = "want"
 version = "0.3.1"
@@ -3701,7 +3319,7 @@
  "either",
  "home",
  "once_cell",
- "rustix 0.38.28",
+ "rustix",
 ]
 
 [[package]]
@@ -3720,15 +3338,6 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
 
-[[package]]
-name = "winapi-util"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
-dependencies = [
- "winapi",
-]
-
 [[package]]
 name = "winapi-x86_64-pc-windows-gnu"
 version = "0.4.0"
diff --git a/services/identity/Cargo.toml b/services/identity/Cargo.toml
--- a/services/identity/Cargo.toml
+++ b/services/identity/Cargo.toml
@@ -33,7 +33,6 @@
 serde_json = "1.0.95"
 tunnelbroker_messages = { path = "../../shared/tunnelbroker_messages" }
 identity_search_messages = { path = "../../shared/identity_search_messages" }
-moka = { version = "0.10", features = ["future"] }
 uuid = { version = "1.3", features = ["v4"] }
 base64 = "0.21.2"
 regex = "1"
diff --git a/services/identity/src/client_service.rs b/services/identity/src/client_service.rs
--- a/services/identity/src/client_service.rs
+++ b/services/identity/src/client_service.rs
@@ -5,7 +5,6 @@
 use comm_lib::aws::DynamoDBError;
 use comm_lib::shared::reserved_users::RESERVED_USERNAME_SET;
 use comm_opaque2::grpc::protocol_error_to_grpc_status;
-use moka::future::Cache;
 use rand::rngs::OsRng;
 use serde::{Deserialize, Serialize};
 use siwe::eip55;
@@ -33,7 +32,6 @@
 use crate::grpc_utils::{
   ChallengeResponse, DeviceKeyUploadActions, NonceChallenge,
 };
-use crate::id::generate_uuid;
 use crate::nonce::generate_nonce_data;
 use crate::reserved_users::{
   validate_account_ownership_message_and_get_user_id,
@@ -92,7 +90,6 @@
 #[derive(derive_more::Constructor)]
 pub struct ClientService {
   client: DatabaseClient,
-  cache: Cache<String, WorkflowInProgress>,
 }
 
 #[tonic::async_trait]
@@ -135,11 +132,12 @@
       )
       .map_err(protocol_error_to_grpc_status)?;
     let session_id = self
-      .cache
-      .insert_with_uuid_key(WorkflowInProgress::Registration(Box::new(
+      .client
+      .insert_workflow(WorkflowInProgress::Registration(Box::new(
         registration_state,
       )))
-      .await;
+      .await
+      .map_err(handle_db_error)?;
 
     let response = RegistrationStartResponse {
       session_id,
@@ -189,11 +187,12 @@
       .map_err(protocol_error_to_grpc_status)?;
 
     let session_id = self
-      .cache
-      .insert_with_uuid_key(WorkflowInProgress::Registration(Box::new(
+      .client
+      .insert_workflow(WorkflowInProgress::Registration(Box::new(
         registration_state,
       )))
-      .await;
+      .await
+      .map_err(handle_db_error)?;
 
     let response = RegistrationStartResponse {
       session_id,
@@ -209,11 +208,12 @@
     let code_version = get_code_version(&request);
     let message = request.into_inner();
 
-    if let Some(WorkflowInProgress::Registration(state)) =
-      self.cache.get(&message.session_id)
+    if let Some(WorkflowInProgress::Registration(state)) = self
+      .client
+      .get_workflow(message.session_id)
+      .await
+      .map_err(handle_db_error)?
     {
-      self.cache.invalidate(&message.session_id).await;
-
       let server_registration = comm_opaque2::server::Registration::new();
       let password_file = server_registration
         .finish(&message.opaque_registration_upload)
@@ -310,9 +310,10 @@
       construct_user_login_info(&message, user_id, server_login)?;
 
     let session_id = self
-      .cache
-      .insert_with_uuid_key(WorkflowInProgress::Login(Box::new(login_state)))
-      .await;
+      .client
+      .insert_workflow(WorkflowInProgress::Login(Box::new(login_state)))
+      .await
+      .map_err(handle_db_error)?;
 
     let response = Response::new(OpaqueLoginStartResponse {
       session_id,
@@ -328,11 +329,12 @@
     let code_version = get_code_version(&request);
     let message = request.into_inner();
 
-    if let Some(WorkflowInProgress::Login(state)) =
-      self.cache.get(&message.session_id)
+    if let Some(WorkflowInProgress::Login(state)) = self
+      .client
+      .get_workflow(message.session_id)
+      .await
+      .map_err(handle_db_error)?
     {
-      self.cache.invalidate(&message.session_id).await;
-
       let mut server_login = state.opaque_server_login.clone();
       server_login
         .finish(&message.opaque_login_upload)
@@ -896,23 +898,6 @@
   }
 }
 
-#[tonic::async_trait]
-pub trait CacheExt<T> {
-  async fn insert_with_uuid_key(&self, value: T) -> String;
-}
-
-#[tonic::async_trait]
-impl<T> CacheExt<T> for Cache<String, T>
-where
-  T: Clone + Send + Sync + 'static,
-{
-  async fn insert_with_uuid_key(&self, value: T) -> String {
-    let session_id = generate_uuid();
-    self.insert(session_id.clone(), value).await;
-    session_id
-  }
-}
-
 pub fn handle_db_error(db_error: DBError) -> tonic::Status {
   match db_error {
     DBError::AwsSdk(DynamoDBError::InternalServerError(_))
diff --git a/services/identity/src/grpc_services/authenticated.rs b/services/identity/src/grpc_services/authenticated.rs
--- a/services/identity/src/grpc_services/authenticated.rs
+++ b/services/identity/src/grpc_services/authenticated.rs
@@ -3,9 +3,7 @@
 use crate::config::CONFIG;
 use crate::database::{DeviceListRow, DeviceListUpdate};
 use crate::{
-  client_service::{
-    handle_db_error, CacheExt, UpdateState, WorkflowInProgress,
-  },
+  client_service::{handle_db_error, UpdateState, WorkflowInProgress},
   constants::request_metadata,
   database::DatabaseClient,
   ddb_utils::DateTimeExt,
@@ -13,7 +11,6 @@
 };
 use chrono::{DateTime, Utc};
 use comm_opaque2::grpc::protocol_error_to_grpc_status;
-use moka::future::Cache;
 use tonic::{Request, Response, Status};
 use tracing::{debug, error, warn};
 
@@ -31,7 +28,6 @@
 #[derive(derive_more::Constructor)]
 pub struct AuthenticatedService {
   db_client: DatabaseClient,
-  cache: Cache<String, WorkflowInProgress>,
 }
 
 fn get_auth_info(req: &Request<()>) -> Option<(String, String, String)> {
@@ -255,9 +251,10 @@
 
     let update_state = UpdateState { user_id };
     let session_id = self
-      .cache
-      .insert_with_uuid_key(WorkflowInProgress::Update(update_state))
-      .await;
+      .db_client
+      .insert_workflow(WorkflowInProgress::Update(update_state))
+      .await
+      .map_err(handle_db_error)?;
 
     let response = UpdateUserPasswordStartResponse {
       session_id,
@@ -272,14 +269,15 @@
   ) -> Result<tonic::Response<Empty>, tonic::Status> {
     let message = request.into_inner();
 
-    let Some(WorkflowInProgress::Update(state)) =
-      self.cache.get(&message.session_id)
+    let Some(WorkflowInProgress::Update(state)) = self
+      .db_client
+      .get_workflow(message.session_id)
+      .await
+      .map_err(handle_db_error)?
     else {
       return Err(tonic::Status::not_found("session not found"));
     };
 
-    self.cache.invalidate(&message.session_id).await;
-
     let server_registration = comm_opaque2::server::Registration::new();
     let password_file = server_registration
       .finish(&message.opaque_registration_upload)
diff --git a/services/identity/src/main.rs b/services/identity/src/main.rs
--- a/services/identity/src/main.rs
+++ b/services/identity/src/main.rs
@@ -1,9 +1,6 @@
-use std::time::Duration;
-
 use comm_lib::aws;
 use config::Command;
 use database::DatabaseClient;
-use moka::future::Cache;
 use tonic::transport::Server;
 use tonic_web::GrpcWebLayer;
 
@@ -57,17 +54,13 @@
       let addr = IDENTITY_SERVICE_SOCKET_ADDR.parse()?;
       let aws_config = aws::config::from_env().region("us-east-2").load().await;
       let database_client = DatabaseClient::new(&aws_config);
-      let workflow_cache = Cache::builder()
-        .time_to_live(Duration::from_secs(10))
-        .build();
-      let inner_client_service =
-        ClientService::new(database_client.clone(), workflow_cache.clone());
+      let inner_client_service = ClientService::new(database_client.clone());
       let client_service = IdentityClientServiceServer::with_interceptor(
         inner_client_service,
         grpc_services::shared::version_interceptor,
       );
       let inner_auth_service =
-        AuthenticatedService::new(database_client.clone(), workflow_cache);
+        AuthenticatedService::new(database_client.clone());
       let auth_service =
         AuthServer::with_interceptor(inner_auth_service, move |req| {
           grpc_services::authenticated::auth_interceptor(req, &database_client)