diff --git a/lib/types/crypto-types.js b/lib/types/crypto-types.js
--- a/lib/types/crypto-types.js
+++ b/lib/types/crypto-types.js
@@ -8,6 +8,11 @@
   +ed25519: string,
   +curve25519: string,
 };
+const olmIdentityKeysValidator: TInterface<OLMIdentityKeys> =
+  tShape<OLMIdentityKeys>({
+    ed25519: t.String,
+    curve25519: t.String,
+  });
 
 export type OLMPrekey = {
   +curve25519: {
@@ -47,6 +52,11 @@
   +primaryIdentityPublicKeys: OLMIdentityKeys,
   +notificationIdentityPublicKeys: OLMIdentityKeys,
 };
+export const identityKeysBlobValidator: TInterface<IdentityKeysBlob> =
+  tShape<IdentityKeysBlob>({
+    primaryIdentityPublicKeys: olmIdentityKeysValidator,
+    notificationIdentityPublicKeys: olmIdentityKeysValidator,
+  });
 
 export type SignedIdentityKeysBlob = {
   +payload: string,
diff --git a/lib/types/identity-service-types.js b/lib/types/identity-service-types.js
--- a/lib/types/identity-service-types.js
+++ b/lib/types/identity-service-types.js
@@ -1,5 +1,17 @@
 // @flow
 
+import t, { type TInterface } from 'tcomb';
+
+import {
+  identityKeysBlobValidator,
+  type IdentityKeysBlob,
+} from './crypto-types.js';
+import {
+  type OlmSessionInitializationInfo,
+  olmSessionInitializationInfoValidator,
+} from './request-types.js';
+import { tShape } from '../utils/validation-utils.js';
+
 export type UserLoginResponse = {
   +userId: string,
   +accessToken: string,
@@ -19,9 +31,25 @@
   +oneTimeNotifPrekey: ?string,
 };
 
+export type KeyserverKeys = {
+  +identityKeysBlob: IdentityKeysBlob,
+  +contentInitializationInfo: OlmSessionInitializationInfo,
+  +notifInitializationInfo: OlmSessionInitializationInfo,
+  +payloadSignature: string,
+  +socialProof: ?string,
+};
+export const keyserverKeysValidator: TInterface<KeyserverKeys> =
+  tShape<KeyserverKeys>({
+    identityKeysBlob: identityKeysBlobValidator,
+    contentInitializationInfo: olmSessionInitializationInfoValidator,
+    notifInitializationInfo: olmSessionInitializationInfoValidator,
+    payloadSignature: t.String,
+    socialProof: t.maybe(t.String),
+  });
+
 export interface IdentityServiceClient {
   +deleteUser: () => Promise<void>;
-  +getKeyserverKeys: string => Promise<?OutboundKeyInfoResponse>;
+  +getKeyserverKeys: string => Promise<KeyserverKeys>;
   +registerUser?: (
     username: string,
     password: string,
diff --git a/native/identity-service/identity-service-context-provider.react.js b/native/identity-service/identity-service-context-provider.react.js
--- a/native/identity-service/identity-service-context-provider.react.js
+++ b/native/identity-service/identity-service-context-provider.react.js
@@ -4,12 +4,14 @@
 
 import { getOneTimeKeyArray } from 'lib/shared/crypto-utils.js';
 import { IdentityClientContext } from 'lib/shared/identity-client-context.js';
-import type {
-  IdentityServiceClient,
-  OutboundKeyInfoResponse,
-  UserLoginResponse,
+import {
+  type IdentityServiceClient,
+  type UserLoginResponse,
+  type KeyserverKeys,
+  keyserverKeysValidator,
 } from 'lib/types/identity-service-types.js';
 import { ONE_TIME_KEYS_NUMBER } from 'lib/types/identity-service-types.js';
+import { assertWithValidator } from 'lib/utils/validation-utils.js';
 
 import { getCommServicesAuthMetadataEmitter } from '../event-emitters/csa-auth-metadata-emitter.js';
 import { commCoreModule, commRustModule } from '../native-modules.js';
@@ -68,7 +70,7 @@
         const { deviceID, userID, accessToken } = await getAuthMetadata();
         return commRustModule.deleteUser(userID, deviceID, accessToken);
       },
-      getKeyserverKeys: async (keyserverID: string) => {
+      getKeyserverKeys: async (keyserverID: string): Promise<KeyserverKeys> => {
         const { deviceID, userID, accessToken } = await getAuthMetadata();
         const result = await commRustModule.getKeyserverKeys(
           userID,
@@ -76,18 +78,33 @@
           accessToken,
           keyserverID,
         );
-        const resultObject: OutboundKeyInfoResponse = JSON.parse(result);
-        if (
-          !resultObject.payload ||
-          !resultObject.payloadSignature ||
-          !resultObject.contentPrekey ||
-          !resultObject.contentPrekeySignature ||
-          !resultObject.notifPrekey ||
-          !resultObject.notifPrekeySignature
-        ) {
-          throw new Error('Invalid response from Identity service');
+        const resultObject = JSON.parse(result);
+        const payload = resultObject?.payload;
+
+        const keyserverKeys = {
+          identityKeysBlob: payload ? JSON.parse(payload) : null,
+          contentInitializationInfo: {
+            prekey: resultObject?.contentPrekey,
+            prekeySignature: resultObject?.contentPrekeySignature,
+            oneTimeKey: resultObject?.oneTimeContentPrekey,
+          },
+          notifInitializationInfo: {
+            prekey: resultObject?.notifPrekey,
+            prekeySignature: resultObject?.notifPrekeySignature,
+            oneTimeKey: resultObject?.oneTimeNotifPrekey,
+          },
+          payloadSignature: resultObject?.payloadSignature,
+          socialProof: resultObject?.socialProof,
+        };
+
+        if (!keyserverKeys.contentInitializationInfo.oneTimeKey) {
+          throw new Error('Missing content one time key');
         }
-        return resultObject;
+        if (!keyserverKeys.notifInitializationInfo.oneTimeKey) {
+          throw new Error('Missing notif one time key');
+        }
+
+        return assertWithValidator(keyserverKeys, keyserverKeysValidator);
       },
       registerUser: async (username: string, password: string) => {
         await commCoreModule.initializeCryptoAccount();
diff --git a/web/grpc/identity-service-client-wrapper.js b/web/grpc/identity-service-client-wrapper.js
--- a/web/grpc/identity-service-client-wrapper.js
+++ b/web/grpc/identity-service-client-wrapper.js
@@ -1,11 +1,13 @@
 // @flow
 
 import identityServiceConfig from 'lib/facts/identity-service.js';
-import type {
-  IdentityServiceAuthLayer,
-  IdentityServiceClient,
-  OutboundKeyInfoResponse,
+import {
+  type IdentityServiceAuthLayer,
+  type IdentityServiceClient,
+  type KeyserverKeys,
+  keyserverKeysValidator,
 } from 'lib/types/identity-service-types.js';
+import { assertWithValidator } from 'lib/utils/validation-utils.js';
 
 import { VersionInterceptor, AuthInterceptor } from './interceptor.js';
 import * as IdentityAuthClient from '../protobufs/identity-auth-client.cjs';
@@ -79,41 +81,49 @@
     await this.authClient.deleteUser(new Empty());
   };
 
-  getKeyserverKeys: (keyserverID: string) => Promise<?OutboundKeyInfoResponse> =
-    async (keyserverID: string) => {
-      const client = this.authClient;
-      if (!client) {
-        throw new Error('Identity service client is not initialized');
-      }
-
-      const request = new IdentityAuthStructs.OutboundKeysForUserRequest();
-      request.setUserId(keyserverID);
-      const response = await client.getKeyserverKeys(request);
-      const keyserverInfo = response.getKeyserverInfo();
-      if (!response.hasKeyserverInfo() || !keyserverInfo) {
-        return null;
-      }
-
-      const identityInfo = keyserverInfo.getIdentityInfo();
-      const contentPreKey = keyserverInfo.getContentPrekey();
-      const notifPreKey = keyserverInfo.getNotifPrekey();
-
-      if (!identityInfo || !contentPreKey || !notifPreKey) {
-        return null;
-      }
-
-      return {
-        payload: identityInfo.getPayload(),
-        payloadSignature: identityInfo.getPayloadSignature(),
-        socialProof: identityInfo.getSocialProof(),
-        contentPrekey: contentPreKey.getPrekey(),
-        contentPrekeySignature: contentPreKey.getPrekeySignature(),
-        notifPrekey: notifPreKey.getPrekey(),
-        notifPrekeySignature: notifPreKey.getPrekeySignature(),
-        oneTimeContentPrekey: keyserverInfo.getOneTimeContentPrekey(),
-        oneTimeNotifPrekey: keyserverInfo.getOneTimeNotifPrekey(),
-      };
+  getKeyserverKeys: (keyserverID: string) => Promise<KeyserverKeys> = async (
+    keyserverID: string,
+  ) => {
+    const client = this.authClient;
+    if (!client) {
+      throw new Error('Identity service client is not initialized');
+    }
+
+    const request = new IdentityAuthStructs.OutboundKeysForUserRequest();
+    request.setUserId(keyserverID);
+    const response = await client.getKeyserverKeys(request);
+
+    const keyserverInfo = response.getKeyserverInfo();
+    const identityInfo = keyserverInfo?.getIdentityInfo();
+    const contentPreKey = keyserverInfo?.getContentPrekey();
+    const notifPreKey = keyserverInfo?.getNotifPrekey();
+    const payload = identityInfo?.getPayload();
+
+    const keyserverKeys = {
+      identityKeysBlob: payload ? JSON.parse(payload) : null,
+      contentInitializationInfo: {
+        prekey: contentPreKey?.getPrekey(),
+        prekeySignature: contentPreKey?.getPrekeySignature(),
+        oneTimeKey: keyserverInfo?.getOneTimeContentPrekey(),
+      },
+      notifInitializationInfo: {
+        prekey: notifPreKey?.getPrekey(),
+        prekeySignature: notifPreKey?.getPrekeySignature(),
+        oneTimeKey: keyserverInfo?.getOneTimeNotifPrekey(),
+      },
+      payloadSignature: identityInfo?.getPayloadSignature(),
+      socialProof: identityInfo?.getSocialProof(),
     };
+
+    if (!keyserverKeys.contentInitializationInfo.oneTimeKey) {
+      throw new Error('Missing content one time key');
+    }
+    if (!keyserverKeys.notifInitializationInfo.oneTimeKey) {
+      throw new Error('Missing notif one time key');
+    }
+
+    return assertWithValidator(keyserverKeys, keyserverKeysValidator);
+  };
 }
 
 export { IdentityServiceClientWrapper };