diff --git a/services/identity/src/database/farcaster.rs b/services/identity/src/database/farcaster.rs
--- a/services/identity/src/database/farcaster.rs
+++ b/services/identity/src/database/farcaster.rs
@@ -55,6 +55,28 @@
 
     Ok(users)
   }
+
+  pub async fn add_farcaster_id(
+    &self,
+    user_id: String,
+    farcaster_id: String,
+  ) -> Result<(), Error> {
+    let update_expression =
+      format!("SET {} = :val", USERS_TABLE_FARCASTER_ID_ATTRIBUTE_NAME);
+
+    self
+      .client
+      .update_item()
+      .table_name(USERS_TABLE)
+      .key(USERS_TABLE_PARTITION_KEY, AttributeValue::S(user_id))
+      .update_expression(update_expression)
+      .expression_attribute_values(":val", AttributeValue::S(farcaster_id))
+      .send()
+      .await
+      .map_err(|e| Error::AwsSdk(e.into()))?;
+
+    Ok(())
+  }
 }
 
 impl TryFrom<AttributeMap> for FarcasterUserData {
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
@@ -398,9 +398,19 @@
 
   async fn link_farcaster_account(
     &self,
-    _request: tonic::Request<LinkFarcasterAccountRequest>,
+    request: tonic::Request<LinkFarcasterAccountRequest>,
   ) -> Result<Response<Empty>, tonic::Status> {
-    unimplemented!();
+    let (user_id, _) = get_user_and_device_id(&request)?;
+    let message = request.into_inner();
+
+    self
+      .db_client
+      .add_farcaster_id(user_id, message.farcaster_id)
+      .await
+      .map_err(handle_db_error)?;
+
+    let response = Empty {};
+    Ok(Response::new(response))
   }
 }