diff --git a/services/identity/proto/identity.proto b/services/identity/proto/identity.proto
new file mode 100644
--- /dev/null
+++ b/services/identity/proto/identity.proto
@@ -0,0 +1,118 @@
+syntax = "proto3";
+
+package identity;
+
+service IdentityService {
+  // Called by user to register with the Identity Service (PAKE only)
+  rpc RegisterUser(stream RegistrationRequest) returns (stream
+    RegistrationResponse) {}
+  // Called by user to create an active session and get an access token
+  rpc LoginUser(stream LoginRequest) returns (stream LoginResponse) {}
+  // Called by other services to verify a user's token
+  rpc VerifyUserToken(VerifyUserTokenRequest) returns (VerifyUserTokenResponse)
+    {}
+}
+
+// Helper types
+
+message PakeRegistrationRequestAndUserID {
+  string userID = 1;
+  string deviceID = 2;
+  // Message sent to initiate PAKE registration (step 1)
+  bytes pakeRegistrationRequest = 3;
+}
+
+message PakeCredentialRequestAndUserID {
+  string userID = 1;
+  string deviceID = 2;
+  // Message sent to initiate PAKE login (step 1)
+  bytes pakeCredentialRequest = 3;
+}
+
+message PakeLoginRequest {
+  oneof data {
+    PakeCredentialRequestAndUserID pakeCredentialRequestAndUserID = 1;
+    // Final message in PAKE login (step 3)
+    bytes pakeCredentialFinalization = 2;
+  }
+}
+
+message PakeLoginResponse {
+  oneof data {
+    // Answer sent to the user upon reception of the PAKE login attempt,
+    // containing a sealed envelope with the user's private key (step 2)
+    bytes pakeCredentialResponse = 1;
+    bytes token = 2;
+  }
+}
+
+message PakeRegistrationUploadAndCredentialRequest {
+  // Final message in PAKE registration, containing sealed cryptographic
+  // identifiers (step 3)
+  bytes pakeRegistrationUpload = 1;
+  // Message sent to initiate PAKE login (Same as in
+  // PakeCredentialRequestAndUserID) (step 1)
+  bytes pakeCredentialRequest = 2;
+}
+
+message WalletLoginRequest {
+  string userID = 1;
+  string deviceID = 2;
+  string walletAddress = 3;
+  bytes signedMessage = 4;
+}
+
+message WalletLoginResponse {
+  bytes token = 1;
+}
+
+// RegisterUser
+
+message RegistrationRequest {
+  oneof data {
+    PakeRegistrationRequestAndUserID pakeRegistrationRequestAndUserID = 1;
+    // We combine the last step of PAKE registration with the first step of PAKE
+    // login here to reduce the number of messages sent
+    PakeRegistrationUploadAndCredentialRequest
+      pakeRegistrationUploadAndCredentialRequest = 2;
+    // Final message in PAKE login (Same as in PakeLoginRequest) (step 3)
+    bytes pakeCredentialFinalization = 3;
+  }
+}
+
+message RegistrationResponse {
+  oneof data {
+    // Answer sent to the user upon reception of the PAKE registration attempt
+    // (step 2)
+    bytes pakeRegistrationResponse = 1;
+    PakeLoginResponse pakeLoginResponse = 2;
+  }
+}
+
+// LoginUser
+
+message LoginRequest {
+  oneof data {
+    PakeLoginRequest pakeLoginRequest = 1;
+    WalletLoginRequest walletLoginRequest = 2;
+  }
+}
+
+message LoginResponse {
+  oneof data {
+    PakeLoginResponse pakeLoginResponse = 1;
+    WalletLoginResponse walletLoginResponse = 2;
+  }
+}
+
+// VerifyUserToken
+
+message VerifyUserTokenRequest {
+  string userID = 1;
+  string deviceID = 2;
+  bytes token = 3;
+}
+
+message VerifyUserTokenResponse {
+  bool tokenValid = 1;
+}