diff --git a/services/identity/Cargo.lock b/services/identity/Cargo.lock
--- a/services/identity/Cargo.lock
+++ b/services/identity/Cargo.lock
@@ -86,6 +86,286 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
 
+[[package]]
+name = "aws-config"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a8c0628604c0a0afcd417548f085fd52e4ad54cacbf96437db4f45a27a47636"
+dependencies = [
+ "aws-http",
+ "aws-sdk-sso",
+ "aws-sdk-sts",
+ "aws-smithy-async",
+ "aws-smithy-client",
+ "aws-smithy-http",
+ "aws-smithy-http-tower",
+ "aws-smithy-json",
+ "aws-smithy-types",
+ "aws-types",
+ "bytes",
+ "hex",
+ "http",
+ "hyper",
+ "ring",
+ "tokio",
+ "tower",
+ "tracing",
+ "zeroize",
+]
+
+[[package]]
+name = "aws-endpoint"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8bae67aca7c551d061a06606ad445d717ee28ac08f70d0f2358096c70118bdfe"
+dependencies = [
+ "aws-smithy-http",
+ "aws-types",
+ "http",
+ "regex",
+ "tracing",
+]
+
+[[package]]
+name = "aws-http"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2145230145123a3308c09a9f8aac2e2213c5540dd0e3a77200c32b20575cbcb"
+dependencies = [
+ "aws-smithy-http",
+ "aws-smithy-types",
+ "aws-types",
+ "http",
+ "lazy_static",
+ "percent-encoding",
+ "tracing",
+]
+
+[[package]]
+name = "aws-sdk-dynamodb"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6dbcbb3375f25e6af3a8c6d62834156ac14234c76420a881547c7f82b9afd61"
+dependencies = [
+ "aws-endpoint",
+ "aws-http",
+ "aws-sig-auth",
+ "aws-smithy-async",
+ "aws-smithy-client",
+ "aws-smithy-http",
+ "aws-smithy-http-tower",
+ "aws-smithy-json",
+ "aws-smithy-types",
+ "aws-types",
+ "bytes",
+ "fastrand",
+ "http",
+ "tokio-stream",
+ "tower",
+]
+
+[[package]]
+name = "aws-sdk-sso"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d3df9fc9d07b0d1dc897a5e9aee924fd8527ff3d8a15677ca4dbb14969aacf0"
+dependencies = [
+ "aws-endpoint",
+ "aws-http",
+ "aws-sig-auth",
+ "aws-smithy-async",
+ "aws-smithy-client",
+ "aws-smithy-http",
+ "aws-smithy-http-tower",
+ "aws-smithy-json",
+ "aws-smithy-types",
+ "aws-types",
+ "bytes",
+ "http",
+ "tokio-stream",
+ "tower",
+]
+
+[[package]]
+name = "aws-sdk-sts"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "479f057a876f04ae8594d6f6633572ce7946fda5f1ae420cdfde653d61841bbe"
+dependencies = [
+ "aws-endpoint",
+ "aws-http",
+ "aws-sig-auth",
+ "aws-smithy-async",
+ "aws-smithy-client",
+ "aws-smithy-http",
+ "aws-smithy-http-tower",
+ "aws-smithy-query",
+ "aws-smithy-types",
+ "aws-smithy-xml",
+ "aws-types",
+ "bytes",
+ "http",
+ "tower",
+]
+
+[[package]]
+name = "aws-sig-auth"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ffea94eb16f7f14153d4ff086aa075e0725050ee89ac6c1538cc1b229c64b420"
+dependencies = [
+ "aws-sigv4",
+ "aws-smithy-http",
+ "aws-types",
+ "http",
+ "tracing",
+]
+
+[[package]]
+name = "aws-sigv4"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "543ad4870152e9850fcbbaec1e1c746c4905682053866848af99681227198cab"
+dependencies = [
+ "aws-smithy-http",
+ "form_urlencoded",
+ "hex",
+ "http",
+ "once_cell",
+ "percent-encoding",
+ "regex",
+ "ring",
+ "time 0.3.11",
+ "tracing",
+]
+
+[[package]]
+name = "aws-smithy-async"
+version = "0.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f5a05f0f76616a4495999f4132287b4a0ebbb4e733aedbae0e120294f336faf1"
+dependencies = [
+ "futures-util",
+ "pin-project-lite",
+ "tokio",
+ "tokio-stream",
+]
+
+[[package]]
+name = "aws-smithy-client"
+version = "0.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c7a1f41d103bc313190a2af4bb8ff67311ae2e673e3701202fe707fc9597da4c"
+dependencies = [
+ "aws-smithy-async",
+ "aws-smithy-http",
+ "aws-smithy-http-tower",
+ "aws-smithy-types",
+ "bytes",
+ "fastrand",
+ "http",
+ "http-body",
+ "hyper",
+ "hyper-rustls",
+ "lazy_static",
+ "pin-project-lite",
+ "tokio",
+ "tower",
+ "tracing",
+]
+
+[[package]]
+name = "aws-smithy-http"
+version = "0.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17bf583ba80ee4ef0fbae4fd1bce07567a03411ac2f82f80d2cfb41ea263c172"
+dependencies = [
+ "aws-smithy-types",
+ "bytes",
+ "bytes-utils",
+ "futures-core",
+ "http",
+ "http-body",
+ "hyper",
+ "once_cell",
+ "percent-encoding",
+ "pin-project-lite",
+ "tokio",
+ "tokio-util 0.7.1",
+ "tracing",
+]
+
+[[package]]
+name = "aws-smithy-http-tower"
+version = "0.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8845020b3875bcaf61c4174430975a07dc9ca9653f1029fcbbf61d197cbe593"
+dependencies = [
+ "aws-smithy-http",
+ "bytes",
+ "http",
+ "http-body",
+ "pin-project-lite",
+ "tower",
+ "tracing",
+]
+
+[[package]]
+name = "aws-smithy-json"
+version = "0.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "748702917f9c54f8300710cb7284152fdba6881741654880bfd5c11ecf230425"
+dependencies = [
+ "aws-smithy-types",
+]
+
+[[package]]
+name = "aws-smithy-query"
+version = "0.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ca90dfe7151841de25e9e0d1862605aec4fe63fbfdf81417d3dc4baef562350"
+dependencies = [
+ "aws-smithy-types",
+ "urlencoding",
+]
+
+[[package]]
+name = "aws-smithy-types"
+version = "0.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "83b74dbb59d20bf29d62772c99dfb8b32377a101c0b03879138f34b3e9b15bdc"
+dependencies = [
+ "itoa",
+ "num-integer",
+ "ryu",
+ "time 0.3.11",
+]
+
+[[package]]
+name = "aws-smithy-xml"
+version = "0.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4bff2d07dd531709cd1e9153c15a859ca394c9d6b2bb8e91d16960ea1fc8ae6"
+dependencies = [
+ "xmlparser",
+]
+
+[[package]]
+name = "aws-types"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "15d31c4af87ae335c41a1ce7d6d699ef274551444e920e93afca3e008aee8f89"
+dependencies = [
+ "aws-smithy-async",
+ "aws-smithy-client",
+ "aws-smithy-http",
+ "aws-smithy-types",
+ "http",
+ "rustc_version",
+ "tracing",
+ "zeroize",
+]
+
 [[package]]
 name = "base64"
 version = "0.13.0"
@@ -156,6 +436,16 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
 
+[[package]]
+name = "bytes-utils"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1934a3ef9cac8efde4966a92781e77713e1ba329f1d42e446c7d7eba340d8ef1"
+dependencies = [
+ "bytes",
+ "either",
+]
+
 [[package]]
 name = "cc"
 version = "1.0.73"
@@ -177,8 +467,7 @@
  "libc",
  "num-integer",
  "num-traits",
- "serde",
- "time",
+ "time 0.1.43",
  "winapi",
 ]
 
@@ -264,15 +553,6 @@
  "libc",
 ]
 
-[[package]]
-name = "crc32fast"
-version = "1.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
-dependencies = [
- "cfg-if",
-]
-
 [[package]]
 name = "crypto-bigint"
 version = "0.2.11"
@@ -305,11 +585,20 @@
  "subtle",
 ]
 
+[[package]]
+name = "ct-logs"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1a816186fa68d9e426e3cb4ae4dff1fcd8e4a2c34b781bf7a822574a0d0aac8"
+dependencies = [
+ "sct",
+]
+
 [[package]]
 name = "curve25519-dalek"
-version = "3.2.1"
+version = "3.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0"
+checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61"
 dependencies = [
  "byteorder",
  "digest 0.9.0",
@@ -357,27 +646,6 @@
  "subtle",
 ]
 
-[[package]]
-name = "dirs-next"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
-dependencies = [
- "cfg-if",
- "dirs-sys-next",
-]
-
-[[package]]
-name = "dirs-sys-next"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
-dependencies = [
- "libc",
- "redox_users",
- "winapi",
-]
-
 [[package]]
 name = "displaydoc"
 version = "0.2.3"
@@ -454,33 +722,13 @@
 checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
 
 [[package]]
-name = "foreign-types"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
-dependencies = [
- "foreign-types-shared",
-]
-
-[[package]]
-name = "foreign-types-shared"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
-
-[[package]]
-name = "futures"
-version = "0.3.21"
+name = "form_urlencoded"
+version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e"
+checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
 dependencies = [
- "futures-channel",
- "futures-core",
- "futures-executor",
- "futures-io",
- "futures-sink",
- "futures-task",
- "futures-util",
+ "matches",
+ "percent-encoding",
 ]
 
 [[package]]
@@ -490,7 +738,6 @@
 checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010"
 dependencies = [
  "futures-core",
- "futures-sink",
 ]
 
 [[package]]
@@ -499,23 +746,6 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3"
 
-[[package]]
-name = "futures-executor"
-version = "0.3.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6"
-dependencies = [
- "futures-core",
- "futures-task",
- "futures-util",
-]
-
-[[package]]
-name = "futures-io"
-version = "0.3.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b"
-
 [[package]]
 name = "futures-macro"
 version = "0.3.21"
@@ -545,13 +775,9 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a"
 dependencies = [
- "futures-channel",
  "futures-core",
- "futures-io",
  "futures-macro",
- "futures-sink",
  "futures-task",
- "memchr",
  "pin-project-lite",
  "pin-utils",
  "slab",
@@ -736,28 +962,32 @@
 ]
 
 [[package]]
-name = "hyper-timeout"
-version = "0.4.1"
+name = "hyper-rustls"
+version = "0.22.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1"
+checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64"
 dependencies = [
+ "ct-logs",
+ "futures-util",
  "hyper",
- "pin-project-lite",
+ "log",
+ "rustls",
+ "rustls-native-certs",
  "tokio",
- "tokio-io-timeout",
+ "tokio-rustls",
+ "webpki",
 ]
 
 [[package]]
-name = "hyper-tls"
-version = "0.5.0"
+name = "hyper-timeout"
+version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
+checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1"
 dependencies = [
- "bytes",
  "hyper",
- "native-tls",
+ "pin-project-lite",
  "tokio",
- "tokio-native-tls",
+ "tokio-io-timeout",
 ]
 
 [[package]]
@@ -765,6 +995,9 @@
 version = "0.1.0"
 dependencies = [
  "argon2",
+ "aws-config",
+ "aws-sdk-dynamodb",
+ "aws-types",
  "bytes",
  "chrono",
  "clap",
@@ -776,8 +1009,6 @@
  "opaque-ke",
  "prost",
  "rand",
- "rusoto_core",
- "rusoto_dynamodb",
  "sha2",
  "siwe",
  "tokio",
@@ -880,15 +1111,10 @@
 ]
 
 [[package]]
-name = "md-5"
-version = "0.9.1"
+name = "matches"
+version = "0.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b5a279bb9607f9f53c22d496eade00d138d1bdcccd07d74650387cf94942a15"
-dependencies = [
- "block-buffer 0.9.0",
- "digest 0.9.0",
- "opaque-debug",
-]
+checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
 
 [[package]]
 name = "memchr"
@@ -931,24 +1157,6 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a"
 
-[[package]]
-name = "native-tls"
-version = "0.2.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd7e2f3618557f980e0b17e8856252eee3c97fa12c54dff0ca290fb6266ca4a9"
-dependencies = [
- "lazy_static",
- "libc",
- "log",
- "openssl",
- "openssl-probe",
- "openssl-sys",
- "schannel",
- "security-framework",
- "security-framework-sys",
- "tempfile",
-]
-
 [[package]]
 name = "nom"
 version = "7.1.1"
@@ -997,6 +1205,15 @@
  "libc",
 ]
 
+[[package]]
+name = "num_threads"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
+dependencies = [
+ "libc",
+]
+
 [[package]]
 name = "once_cell"
 version = "1.10.0"
@@ -1028,51 +1245,12 @@
  "zeroize",
 ]
 
-[[package]]
-name = "openssl"
-version = "0.10.40"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fb81a6430ac911acb25fe5ac8f1d2af1b4ea8a4fdfda0f1ee4292af2e2d8eb0e"
-dependencies = [
- "bitflags",
- "cfg-if",
- "foreign-types",
- "libc",
- "once_cell",
- "openssl-macros",
- "openssl-sys",
-]
-
-[[package]]
-name = "openssl-macros"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
 [[package]]
 name = "openssl-probe"
 version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
 
-[[package]]
-name = "openssl-sys"
-version = "0.9.73"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d5fd19fb3e0a8191c1e34935718976a3e70c112ab9a24af6d7cadccd9d90bc0"
-dependencies = [
- "autocfg",
- "cc",
- "libc",
- "pkg-config",
- "vcpkg",
-]
-
 [[package]]
 name = "os_str_bytes"
 version = "6.0.0"
@@ -1138,12 +1316,6 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
 
-[[package]]
-name = "pkg-config"
-version = "0.3.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
-
 [[package]]
 name = "ppv-lite86"
 version = "0.2.16"
@@ -1293,17 +1465,6 @@
  "bitflags",
 ]
 
-[[package]]
-name = "redox_users"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
-dependencies = [
- "getrandom 0.2.6",
- "redox_syscall",
- "thiserror",
-]
-
 [[package]]
 name = "regex"
 version = "1.5.5"
@@ -1331,111 +1492,78 @@
 ]
 
 [[package]]
-name = "rusoto_core"
-version = "0.47.0"
+name = "ring"
+version = "0.16.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b4f000e8934c1b4f70adde180056812e7ea6b1a247952db8ee98c94cd3116cc"
+checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
 dependencies = [
- "async-trait",
- "base64",
- "bytes",
- "crc32fast",
- "futures",
- "http",
- "hyper",
- "hyper-tls",
- "lazy_static",
- "log",
- "rusoto_credential",
- "rusoto_signature",
- "rustc_version",
- "serde",
- "serde_json",
- "tokio",
- "xml-rs",
-]
-
-[[package]]
-name = "rusoto_credential"
-version = "0.47.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a46b67db7bb66f5541e44db22b0a02fed59c9603e146db3a9e633272d3bac2f"
-dependencies = [
- "async-trait",
- "chrono",
- "dirs-next",
- "futures",
- "hyper",
- "serde",
- "serde_json",
- "shlex",
- "tokio",
- "zeroize",
+ "cc",
+ "libc",
+ "once_cell",
+ "spin",
+ "untrusted",
+ "web-sys",
+ "winapi",
 ]
 
 [[package]]
-name = "rusoto_dynamodb"
-version = "0.47.0"
+name = "rustc_version"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7935e1f9ca57c4ee92a4d823dcd698eb8c992f7e84ca21976ae72cd2b03016e7"
+checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
 dependencies = [
- "async-trait",
- "bytes",
- "futures",
- "rusoto_core",
- "serde",
- "serde_json",
+ "semver",
 ]
 
 [[package]]
-name = "rusoto_signature"
-version = "0.47.0"
+name = "rustls"
+version = "0.19.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6264e93384b90a747758bcc82079711eacf2e755c3a8b5091687b5349d870bcc"
+checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7"
 dependencies = [
  "base64",
- "bytes",
- "chrono",
- "digest 0.9.0",
- "futures",
- "hex",
- "hmac",
- "http",
- "hyper",
  "log",
- "md-5",
- "percent-encoding",
- "pin-project-lite",
- "rusoto_credential",
- "rustc_version",
- "serde",
- "sha2",
- "tokio",
+ "ring",
+ "sct",
+ "webpki",
 ]
 
 [[package]]
-name = "rustc_version"
-version = "0.4.0"
+name = "rustls-native-certs"
+version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
+checksum = "5a07b7c1885bd8ed3831c289b7870b13ef46fe0e856d288c30d9cc17d75a2092"
 dependencies = [
- "semver",
+ "openssl-probe",
+ "rustls",
+ "schannel",
+ "security-framework",
 ]
 
 [[package]]
 name = "ryu"
-version = "1.0.9"
+version = "1.0.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
+checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695"
 
 [[package]]
 name = "schannel"
-version = "0.1.19"
+version = "0.1.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75"
+checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2"
 dependencies = [
  "lazy_static",
- "winapi",
+ "windows-sys",
+]
+
+[[package]]
+name = "sct"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce"
+dependencies = [
+ "ring",
+ "untrusted",
 ]
 
 [[package]]
@@ -1467,37 +1595,6 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8cb243bdfdb5936c8dc3c45762a19d12ab4550cdc753bc247637d4ec35a040fd"
 
-[[package]]
-name = "serde"
-version = "1.0.137"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
-dependencies = [
- "serde_derive",
-]
-
-[[package]]
-name = "serde_derive"
-version = "1.0.137"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "serde_json"
-version = "1.0.81"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c"
-dependencies = [
- "itoa",
- "ryu",
- "serde",
-]
-
 [[package]]
 name = "sha2"
 version = "0.9.9"
@@ -1532,21 +1629,6 @@
  "lazy_static",
 ]
 
-[[package]]
-name = "shlex"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
-
-[[package]]
-name = "signal-hook-registry"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
-dependencies = [
- "libc",
-]
-
 [[package]]
 name = "signature"
 version = "1.3.2"
@@ -1595,6 +1677,12 @@
  "winapi",
 ]
 
+[[package]]
+name = "spin"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
+
 [[package]]
 name = "strsim"
 version = "0.10.0"
@@ -1698,6 +1786,16 @@
  "winapi",
 ]
 
+[[package]]
+name = "time"
+version = "0.3.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72c91f41dcb2f096c05f0873d667dceec1087ce5bcf984ec8ffb19acddbb3217"
+dependencies = [
+ "libc",
+ "num_threads",
+]
+
 [[package]]
 name = "tokio"
 version = "1.18.1"
@@ -1711,7 +1809,6 @@
  "num_cpus",
  "once_cell",
  "pin-project-lite",
- "signal-hook-registry",
  "socket2",
  "tokio-macros",
  "winapi",
@@ -1739,13 +1836,14 @@
 ]
 
 [[package]]
-name = "tokio-native-tls"
-version = "0.3.0"
+name = "tokio-rustls"
+version = "0.22.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b"
+checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6"
 dependencies = [
- "native-tls",
+ "rustls",
  "tokio",
+ "webpki",
 ]
 
 [[package]]
@@ -1956,16 +2054,22 @@
 checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04"
 
 [[package]]
-name = "valuable"
-version = "0.1.0"
+name = "untrusted"
+version = "0.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
+checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
 
 [[package]]
-name = "vcpkg"
-version = "0.2.15"
+name = "urlencoding"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68b90931029ab9b034b300b797048cf23723400aa757e8a2bfb9d748102f9821"
+
+[[package]]
+name = "valuable"
+version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
+checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
 
 [[package]]
 name = "version_check"
@@ -2055,6 +2159,26 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744"
 
+[[package]]
+name = "web-sys"
+version = "0.3.57"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "webpki"
+version = "0.21.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea"
+dependencies = [
+ "ring",
+ "untrusted",
+]
+
 [[package]]
 name = "which"
 version = "4.2.5"
@@ -2098,16 +2222,59 @@
 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 
 [[package]]
-name = "xml-rs"
-version = "0.8.4"
+name = "windows-sys"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
+dependencies = [
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.36.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3"
+checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
+
+[[package]]
+name = "xmlparser"
+version = "0.13.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "114ba2b24d2167ef6d67d7d04c8cc86522b87f490025f39f0303b7db5bf5e3d8"
 
 [[package]]
 name = "zeroize"
-version = "1.3.0"
+version = "1.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd"
+checksum = "d68d9dcec5f9b43a30d38c49f91dfedfaac384cb8f085faca366c26207dd1619"
 dependencies = [
  "zeroize_derive",
 ]
diff --git a/services/identity/Cargo.toml b/services/identity/Cargo.toml
--- a/services/identity/Cargo.toml
+++ b/services/identity/Cargo.toml
@@ -16,8 +16,9 @@
 digest = "0.9"
 clap = { version = "3.1.12", features = ["derive"] }
 derive_more = "0.99"
-rusoto_core = "0.47.0"
-rusoto_dynamodb = "0.47.0"
+aws-config = "0.15.0"
+aws-sdk-dynamodb = "0.15.0"
+aws-types = "0.15.0"
 tracing = "0.1"
 tracing-subscriber = "0.3"
 chrono = "0.4.19"
diff --git a/services/identity/src/database.rs b/services/identity/src/database.rs
--- a/services/identity/src/database.rs
+++ b/services/identity/src/database.rs
@@ -1,14 +1,13 @@
 use std::collections::HashMap;
 use std::fmt::{Display, Formatter, Result as FmtResult};
 
-use bytes::Bytes;
+use aws_sdk_dynamodb::model::AttributeValue;
+use aws_sdk_dynamodb::output::{GetItemOutput, PutItemOutput};
+use aws_sdk_dynamodb::types::Blob;
+use aws_sdk_dynamodb::{Client, Error as DynamoDBError};
+use aws_types::sdk_config::SdkConfig;
 use chrono::{DateTime, Utc};
 use opaque_ke::{errors::ProtocolError, ServerRegistration};
-use rusoto_core::{Region, RusotoError};
-use rusoto_dynamodb::{
-  AttributeValue, DynamoDb, DynamoDbClient, GetItemError, GetItemInput,
-  GetItemOutput, PutItemError, PutItemInput, PutItemOutput,
-};
 use tracing::{error, info};
 
 use crate::constants::{
@@ -24,13 +23,13 @@
 
 #[derive(Clone)]
 pub struct DatabaseClient {
-  client: DynamoDbClient,
+  client: Client,
 }
 
 impl DatabaseClient {
-  pub fn new(region: Region) -> Self {
+  pub fn new(aws_config: &SdkConfig) -> Self {
     DatabaseClient {
-      client: DynamoDbClient::new(region),
+      client: Client::new(aws_config),
     }
   }
 
@@ -42,13 +41,14 @@
       PAKE_REGISTRATION_TABLE_PARTITION_KEY.to_string(),
       user_id.clone(),
     ));
-    let get_item_input = GetItemInput {
-      table_name: PAKE_REGISTRATION_TABLE.to_string(),
-      key: primary_key,
-      consistent_read: Some(true),
-      ..GetItemInput::default()
-    };
-    let get_item_result = self.client.get_item(get_item_input).await;
+    let get_item_result = self
+      .client
+      .get_item()
+      .table_name(PAKE_REGISTRATION_TABLE)
+      .set_key(Some(primary_key))
+      .consistent_read(true)
+      .send()
+      .await;
     match get_item_result {
       Ok(GetItemOutput {
         item: Some(mut item),
@@ -70,7 +70,7 @@
           "DynamoDB client failed to get registration data for user {}: {}",
           user_id, e
         );
-        Err(Error::RusotoGet(e))
+        Err(Error::AwsSdk(e.into()))
       }
     }
   }
@@ -79,28 +79,22 @@
     &self,
     user_id: String,
     registration: ServerRegistration<Cipher>,
-  ) -> Result<PutItemOutput, RusotoError<PutItemError>> {
-    let input = PutItemInput {
-      table_name: PAKE_REGISTRATION_TABLE.to_string(),
-      item: HashMap::from([
-        (
-          PAKE_REGISTRATION_TABLE_PARTITION_KEY.to_string(),
-          AttributeValue {
-            s: Some(user_id),
-            ..Default::default()
-          },
-        ),
-        (
-          PAKE_REGISTRATION_TABLE_DATA_ATTRIBUTE.to_string(),
-          AttributeValue {
-            b: Some(Bytes::from(registration.serialize())),
-            ..Default::default()
-          },
-        ),
-      ]),
-      ..PutItemInput::default()
-    };
-    self.client.put_item(input).await
+  ) -> Result<PutItemOutput, Error> {
+    self
+      .client
+      .put_item()
+      .table_name(PAKE_REGISTRATION_TABLE)
+      .item(
+        PAKE_REGISTRATION_TABLE_PARTITION_KEY,
+        AttributeValue::S(user_id),
+      )
+      .item(
+        PAKE_REGISTRATION_TABLE_DATA_ATTRIBUTE,
+        AttributeValue::B(Blob::new(registration.serialize())),
+      )
+      .send()
+      .await
+      .map_err(|e| Error::AwsSdk(e.into()))
   }
 
   pub async fn get_access_token_data(
@@ -115,13 +109,14 @@
       ),
       (ACCESS_TOKEN_SORT_KEY.to_string(), device_id.clone()),
     );
-    let get_item_input = GetItemInput {
-      table_name: ACCESS_TOKEN_TABLE.to_string(),
-      key: primary_key,
-      consistent_read: Some(true),
-      ..GetItemInput::default()
-    };
-    let get_item_result = self.client.get_item(get_item_input).await;
+    let get_item_result = self
+      .client
+      .get_item()
+      .table_name(ACCESS_TOKEN_TABLE)
+      .set_key(Some(primary_key))
+      .consistent_read(true)
+      .send()
+      .await;
     match get_item_result {
       Ok(GetItemOutput {
         item: Some(mut item),
@@ -160,7 +155,7 @@
           "DynamoDB client failed to get token for user {} on device {}: {}",
           user_id, device_id, e
         );
-        Err(Error::RusotoGet(e))
+        Err(Error::AwsSdk(e.into()))
       }
     }
   }
@@ -169,58 +164,43 @@
     &self,
     access_token_data: AccessTokenData,
   ) -> Result<PutItemOutput, Error> {
-    let input = PutItemInput {
-      table_name: ACCESS_TOKEN_TABLE.to_string(),
-      item: HashMap::from([
-        (
-          ACCESS_TOKEN_TABLE_PARTITION_KEY.to_string(),
-          AttributeValue {
-            s: Some(access_token_data.user_id),
-            ..Default::default()
-          },
-        ),
-        (
-          ACCESS_TOKEN_SORT_KEY.to_string(),
-          AttributeValue {
-            s: Some(access_token_data.device_id),
-            ..Default::default()
-          },
-        ),
-        (
-          ACCESS_TOKEN_TABLE_TOKEN_ATTRIBUTE.to_string(),
-          AttributeValue {
-            s: Some(access_token_data.access_token),
-            ..Default::default()
-          },
-        ),
-        (
-          ACCESS_TOKEN_TABLE_CREATED_ATTRIBUTE.to_string(),
-          AttributeValue {
-            s: Some(access_token_data.created.to_rfc3339()),
-            ..Default::default()
-          },
-        ),
-        (
-          ACCESS_TOKEN_TABLE_AUTH_TYPE_ATTRIBUTE.to_string(),
-          AttributeValue {
-            s: Some(match access_token_data.auth_type {
-              AuthType::Password => "password".to_string(),
-              AuthType::Wallet => "wallet".to_string(),
-            }),
-            ..Default::default()
-          },
-        ),
-        (
-          ACCESS_TOKEN_TABLE_VALID_ATTRIBUTE.to_string(),
-          AttributeValue {
-            bool: Some(access_token_data.valid),
-            ..Default::default()
-          },
-        ),
-      ]),
-      ..PutItemInput::default()
-    };
-    self.client.put_item(input).await.map_err(Error::RusotoPut)
+    let item = HashMap::from([
+      (
+        ACCESS_TOKEN_TABLE_PARTITION_KEY.into(),
+        AttributeValue::S(access_token_data.user_id),
+      ),
+      (
+        ACCESS_TOKEN_SORT_KEY.into(),
+        AttributeValue::S(access_token_data.device_id),
+      ),
+      (
+        ACCESS_TOKEN_TABLE_TOKEN_ATTRIBUTE.into(),
+        AttributeValue::S(access_token_data.access_token),
+      ),
+      (
+        ACCESS_TOKEN_TABLE_CREATED_ATTRIBUTE.into(),
+        AttributeValue::S(access_token_data.created.to_rfc3339()),
+      ),
+      (
+        ACCESS_TOKEN_TABLE_AUTH_TYPE_ATTRIBUTE.into(),
+        AttributeValue::S(match access_token_data.auth_type {
+          AuthType::Password => "password".to_string(),
+          AuthType::Wallet => "wallet".to_string(),
+        }),
+      ),
+      (
+        ACCESS_TOKEN_TABLE_VALID_ATTRIBUTE.into(),
+        AttributeValue::Bool(access_token_data.valid),
+      ),
+    ]);
+    self
+      .client
+      .put_item()
+      .table_name(ACCESS_TOKEN_TABLE)
+      .set_item(Some(item))
+      .send()
+      .await
+      .map_err(|e| Error::AwsSdk(e.into()))
   }
 }
 
@@ -229,9 +209,7 @@
 )]
 pub enum Error {
   #[display(...)]
-  RusotoGet(RusotoError<GetItemError>),
-  #[display(...)]
-  RusotoPut(RusotoError<PutItemError>),
+  AwsSdk(DynamoDBError),
   #[display(...)]
   Attribute(DBItemError),
 }
@@ -280,13 +258,7 @@
 fn create_simple_primary_key(
   partition_key: (AttributeName, String),
 ) -> HashMap<AttributeName, AttributeValue> {
-  HashMap::from([(
-    partition_key.0,
-    AttributeValue {
-      s: Some(partition_key.1),
-      ..Default::default()
-    },
-  )])
+  HashMap::from([(partition_key.0, AttributeValue::S(partition_key.1))])
 }
 
 fn create_composite_primary_key(
@@ -294,23 +266,14 @@
   sort_key: (AttributeName, String),
 ) -> HashMap<AttributeName, AttributeValue> {
   let mut primary_key = create_simple_primary_key(partition_key);
-  primary_key.insert(
-    sort_key.0,
-    AttributeValue {
-      s: Some(sort_key.1),
-      ..Default::default()
-    },
-  );
+  primary_key.insert(sort_key.0, AttributeValue::S(sort_key.1));
   primary_key
 }
 
 fn parse_created_attribute(
   attribute: Option<AttributeValue>,
 ) -> Result<DateTime<Utc>, DBItemError> {
-  if let Some(AttributeValue {
-    s: Some(created), ..
-  }) = &attribute
-  {
+  if let Some(AttributeValue::S(created)) = &attribute {
     created.parse().map_err(|e| {
       DBItemError::new(
         ACCESS_TOKEN_TABLE_CREATED_ATTRIBUTE,
@@ -330,10 +293,7 @@
 fn parse_auth_type_attribute(
   attribute: Option<AttributeValue>,
 ) -> Result<AuthType, DBItemError> {
-  if let Some(AttributeValue {
-    s: Some(auth_type), ..
-  }) = &attribute
-  {
+  if let Some(AttributeValue::S(auth_type)) = &attribute {
     match auth_type.as_str() {
       "password" => Ok(AuthType::Password),
       "wallet" => Ok(AuthType::Wallet),
@@ -356,9 +316,7 @@
   attribute: Option<AttributeValue>,
 ) -> Result<bool, DBItemError> {
   match attribute {
-    Some(AttributeValue {
-      bool: Some(valid), ..
-    }) => Ok(valid),
+    Some(AttributeValue::Bool(valid)) => Ok(valid),
     Some(_) => Err(DBItemError::new(
       ACCESS_TOKEN_TABLE_VALID_ATTRIBUTE,
       attribute,
@@ -376,7 +334,7 @@
   attribute: Option<AttributeValue>,
 ) -> Result<String, DBItemError> {
   match attribute {
-    Some(AttributeValue { s: Some(token), .. }) => Ok(token),
+    Some(AttributeValue::S(token)) => Ok(token),
     Some(_) => Err(DBItemError::new(
       ACCESS_TOKEN_TABLE_TOKEN_ATTRIBUTE,
       attribute,
@@ -394,12 +352,10 @@
   attribute: Option<AttributeValue>,
 ) -> Result<ServerRegistration<Cipher>, DBItemError> {
   match &attribute {
-    Some(AttributeValue {
-      b: Some(server_registration_bytes),
-      ..
-    }) => {
-      match ServerRegistration::<Cipher>::deserialize(server_registration_bytes)
-      {
+    Some(AttributeValue::B(server_registration_bytes)) => {
+      match ServerRegistration::<Cipher>::deserialize(
+        server_registration_bytes.as_ref(),
+      ) {
         Ok(server_registration) => Ok(server_registration),
         Err(e) => Err(DBItemError::new(
           PAKE_REGISTRATION_TABLE_DATA_ATTRIBUTE,
@@ -435,13 +391,7 @@
     assert_eq!(primary_key.len(), 1);
     let attribute = primary_key.remove(&partition_key_name);
     assert!(attribute.is_some());
-    assert_eq!(
-      attribute,
-      Some(AttributeValue {
-        s: Some(partition_key_value),
-        ..Default::default()
-      })
-    );
+    assert_eq!(attribute, Some(AttributeValue::S(partition_key_value)));
   }
 
   #[test]
@@ -459,19 +409,10 @@
     assert!(partition_key_attribute.is_some());
     assert_eq!(
       partition_key_attribute,
-      Some(AttributeValue {
-        s: Some(partition_key_value),
-        ..Default::default()
-      })
+      Some(AttributeValue::S(partition_key_value))
     );
     let sort_key_attribute = primary_key.remove(&sort_key_name);
     assert!(sort_key_attribute.is_some());
-    assert_eq!(
-      sort_key_attribute,
-      Some(AttributeValue {
-        s: Some(sort_key_value),
-        ..Default::default()
-      })
-    )
+    assert_eq!(sort_key_attribute, Some(AttributeValue::S(sort_key_value)))
   }
 }
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,6 +1,5 @@
 use clap::{Parser, Subcommand};
 use database::DatabaseClient;
-use rusoto_core::Region;
 use tonic::transport::Server;
 use tracing_subscriber::FmtSubscriber;
 
@@ -49,7 +48,8 @@
     Commands::Server => {
       let addr = IDENTITY_SERVICE_SOCKET_ADDR.parse()?;
       let config = Config::load()?;
-      let database_client = DatabaseClient::new(Region::UsEast2);
+      let aws_config = aws_config::from_env().region("us-east-2").load().await;
+      let database_client = DatabaseClient::new(&aws_config);
       let identity_service = MyIdentityService::new(config, database_client);
       Server::builder()
         .add_service(IdentityServiceServer::new(identity_service))
diff --git a/services/identity/src/service.rs b/services/identity/src/service.rs
--- a/services/identity/src/service.rs
+++ b/services/identity/src/service.rs
@@ -1,3 +1,4 @@
+use aws_sdk_dynamodb::Error as DynamoDBError;
 use chrono::Utc;
 use constant_time_eq::constant_time_eq;
 use futures_core::Stream;
@@ -9,8 +10,6 @@
 use opaque_ke::{RegistrationUpload, ServerRegistration};
 use rand::rngs::OsRng;
 use rand::{CryptoRng, Rng};
-use rusoto_core::RusotoError;
-use rusoto_dynamodb::{GetItemError, PutItemError};
 use siwe::Message;
 use std::pin::Pin;
 use tokio::sync::mpsc;
@@ -327,13 +326,11 @@
         message.access_token.as_bytes(),
       ),
       Ok(None) => false,
-      Err(Error::RusotoGet(RusotoError::Service(
-        GetItemError::ResourceNotFound(_),
-      )))
-      | Err(Error::RusotoGet(RusotoError::Credentials(_))) => {
-        return Err(Status::failed_precondition("internal error"))
-      }
-      Err(Error::RusotoGet(_)) => {
+      Err(Error::AwsSdk(DynamoDBError::InternalServerError(_)))
+      | Err(Error::AwsSdk(
+        DynamoDBError::ProvisionedThroughputExceededException(_),
+      ))
+      | Err(Error::AwsSdk(DynamoDBError::RequestLimitExceeded(_))) => {
         return Err(Status::unavailable("please retry"))
       }
       Err(e) => {
@@ -372,13 +369,13 @@
     .await
   {
     Ok(_) => Ok(access_token_data.access_token),
-    Err(Error::RusotoPut(RusotoError::Service(
-      PutItemError::ResourceNotFound(_),
-    )))
-    | Err(Error::RusotoPut(RusotoError::Credentials(_))) => {
-      Err(Status::failed_precondition("internal error"))
+    Err(Error::AwsSdk(DynamoDBError::InternalServerError(_)))
+    | Err(Error::AwsSdk(
+      DynamoDBError::ProvisionedThroughputExceededException(_),
+    ))
+    | Err(Error::AwsSdk(DynamoDBError::RequestLimitExceeded(_))) => {
+      Err(Status::unavailable("please retry"))
     }
-    Err(Error::RusotoPut(_)) => Err(Status::unavailable("please retry")),
     Err(e) => {
       error!("Encountered an unexpected error: {}", e);
       Err(Status::failed_precondition("unexpected error"))
@@ -487,21 +484,17 @@
       Ok(None) => {
         return Err(Status::not_found("user not found"));
       }
-      Err(e) => match e {
-        Error::RusotoGet(RusotoError::Service(
-          GetItemError::ResourceNotFound(_),
-        ))
-        | Error::RusotoGet(RusotoError::Credentials(_)) => {
-          return Err(Status::failed_precondition("internal error"));
-        }
-        Error::RusotoGet(_) => {
-          return Err(Status::unavailable("please retry"));
-        }
-        e => {
-          error!("Encountered an unexpected error: {}", e);
-          return Err(Status::failed_precondition("unexpected error"));
-        }
-      },
+      Err(Error::AwsSdk(DynamoDBError::InternalServerError(_)))
+      | Err(Error::AwsSdk(
+        DynamoDBError::ProvisionedThroughputExceededException(_),
+      ))
+      | Err(Error::AwsSdk(DynamoDBError::RequestLimitExceeded(_))) => {
+        return Err(Status::unavailable("please retry"))
+      }
+      Err(e) => {
+        error!("Encountered an unexpected error: {}", e);
+        return Err(Status::failed_precondition("unexpected error"));
+      }
     };
   let credential_request =
     CredentialRequest::deserialize(pake_credential_request).map_err(|e| {
@@ -663,10 +656,13 @@
     .await
   {
     Ok(_) => Ok(()),
-    Err(RusotoError::Service(PutItemError::ResourceNotFound(_)))
-    | Err(RusotoError::Credentials(_)) => {
-      Err(Status::failed_precondition("internal error"))
+    Err(Error::AwsSdk(DynamoDBError::InternalServerError(_)))
+    | Err(Error::AwsSdk(
+      DynamoDBError::ProvisionedThroughputExceededException(_),
+    ))
+    | Err(Error::AwsSdk(DynamoDBError::RequestLimitExceeded(_))) => {
+      Err(Status::unavailable("please retry"))
     }
-    Err(_) => Err(Status::unavailable("please retry")),
+    Err(_) => Err(Status::failed_precondition("internal error")),
   }
 }