diff --git a/Cargo.lock b/Cargo.lock
index 14dbd84ccc4e73654581334a5dfd23085ec32236..e847b89314c1512c24dc3431deecd78bb034e078 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -829,6 +829,7 @@ version = "0.8.0-dev"
 dependencies = [
  "frame-support",
  "frame-system",
+ "log",
  "pallet-authority-members",
  "pallet-balances",
  "pallet-certification",
@@ -4312,6 +4313,7 @@ dependencies = [
  "frame-benchmarking",
  "frame-support",
  "frame-system",
+ "log",
  "maplit",
  "pallet-session",
  "parity-scale-codec",
diff --git a/pallets/authority-members/Cargo.toml b/pallets/authority-members/Cargo.toml
index 7bf31c0ce9adababc4816511d511f88c2e75e7e8..a3bd2700feefc5b0ec353eadb3ba474c7802f0c5 100644
--- a/pallets/authority-members/Cargo.toml
+++ b/pallets/authority-members/Cargo.toml
@@ -17,6 +17,7 @@ std = [
     'frame-support/std',
     'frame-system/std',
     'frame-benchmarking/std',
+	'log/std',
     'pallet-session/std',
     'serde',
     'sp-core/std',
@@ -28,17 +29,19 @@ std = [
 try-runtime = ['frame-support/try-runtime']
 
 [dependencies]
+# local
 sp-membership = { path = "../../primitives/membership", default-features = false }
 
-# substrate
+# crates.io
+log = { version = "0.4.14", default-features = false }
 scale-info = { version = "1.0", default-features = false, features = ["derive"] }
-
 [dependencies.codec]
 default-features = false
 features = ['derive']
 package = 'parity-scale-codec'
 version = '2.3.1'
 
+# substrate
 [dependencies.frame-benchmarking]
 default-features = false
 git = 'https://github.com/librelois/substrate.git'
diff --git a/pallets/authority-members/src/lib.rs b/pallets/authority-members/src/lib.rs
index 9a115df4603b93e5ca358bb0f5f9517a355a9f07..cb0d6dbbb5461d6ddd7ad5254236e250a98b887c 100644
--- a/pallets/authority-members/src/lib.rs
+++ b/pallets/authority-members/src/lib.rs
@@ -100,7 +100,10 @@ pub mod pallet {
         fn build(&self) {
             for (member_id, (account_id, _is_online)) in &self.initial_authorities {
                 AccountIdOf::<T>::insert(member_id, account_id);
-                Members::<T>::insert(member_id, MemberData::new_genesis(T::MaxKeysLife::get()));
+                Members::<T>::insert(
+                    member_id,
+                    MemberData::new_genesis(T::MaxKeysLife::get(), account_id.to_owned()),
+                );
             }
             let mut members_ids = self
                 .initial_authorities
@@ -148,7 +151,8 @@ pub mod pallet {
 
     #[pallet::storage]
     #[pallet::getter(fn member)]
-    pub type Members<T: Config> = StorageMap<_, Twox64Concat, T::MemberId, MemberData, OptionQuery>;
+    pub type Members<T: Config> =
+        StorageMap<_, Twox64Concat, T::MemberId, MemberData<T::AccountId>, OptionQuery>;
 
     #[pallet::storage]
     #[pallet::getter(fn members_expire_on)]
@@ -301,6 +305,7 @@ pub mod pallet {
                 let mut member_data = member_data_opt.get_or_insert(MemberData {
                     expire_on_session,
                     must_rotate_keys_before,
+                    owner_key: who,
                 });
                 member_data.must_rotate_keys_before = must_rotate_keys_before;
             });
@@ -324,25 +329,6 @@ pub mod pallet {
             Ok(().into())
         }
         #[pallet::weight(0)]
-        pub fn purge_old_session_keys(
-            origin: OriginFor<T>,
-            accounts_ids: Vec<T::AccountId>,
-        ) -> DispatchResultWithPostInfo {
-            let who = ensure_signed(origin)?;
-            let member_id = Self::verify_ownership_and_membership(&who)?;
-
-            for account_id in accounts_ids {
-                if !T::IsMember::is_member(&member_id) {
-                    let _post_info = pallet_session::Call::<T>::purge_keys {}
-                        .dispatch_bypass_filter(
-                            frame_system::Origin::<T>::Signed(account_id).into(),
-                        )?;
-                }
-            }
-
-            Ok(().into())
-        }
-        #[pallet::weight(0)]
         pub fn remove_member(
             origin: OriginFor<T>,
             member_id: T::MemberId,
@@ -353,7 +339,8 @@ pub mod pallet {
                 return Err(Error::<T>::NotMember.into());
             }
 
-            Self::do_remove_member(member_id);
+            let member_data = Members::<T>::get(member_id).ok_or(Error::<T>::NotMember)?;
+            Self::do_remove_member(member_id, member_data.owner_key);
 
             Ok(().into())
         }
@@ -362,7 +349,7 @@ pub mod pallet {
     // INTERNAL FUNCTIONS //
 
     impl<T: Config> Pallet<T> {
-        fn do_remove_member(member_id: T::MemberId) -> Weight {
+        fn do_remove_member(member_id: T::MemberId, owner_key: T::AccountId) -> Weight {
             if Self::is_online(member_id) {
                 // Trigger the member deletion for next session
                 Self::insert_out(member_id);
@@ -373,6 +360,18 @@ pub mod pallet {
             Self::remove_online(member_id);
             Members::<T>::remove(member_id);
 
+            // Purge session keys
+            if let Err(e) = pallet_session::Pallet::<T>::purge_keys(
+                frame_system::Origin::<T>::Signed(owner_key).into(),
+            ) {
+                log::error!(
+                    target: "runtime::authority_members",
+                    "Logic error: fail to purge session keys in do_remove_member(): {:?}",
+                    e
+                );
+            }
+
+            // Emit event
             Self::deposit_event(Event::MemberRemoved(member_id));
             let _ = T::OnRemovedMember::on_removed_member(member_id);
 
@@ -382,14 +381,14 @@ pub mod pallet {
             for member_id in MembersExpireOn::<T>::take(current_session_index) {
                 if let Some(member_data) = Members::<T>::get(member_id) {
                     if member_data.expire_on_session == current_session_index {
-                        Self::do_remove_member(member_id);
+                        Self::do_remove_member(member_id, member_data.owner_key);
                     }
                 }
             }
             for member_id in MustRotateKeysBefore::<T>::take(current_session_index) {
                 if let Some(member_data) = Members::<T>::get(member_id) {
                     if member_data.must_rotate_keys_before == current_session_index {
-                        Self::do_remove_member(member_id);
+                        Self::do_remove_member(member_id, member_data.owner_key);
                     }
                 }
             }
diff --git a/pallets/authority-members/src/tests.rs b/pallets/authority-members/src/tests.rs
index 94cfd0a191e3b8ca21b3ef7649eaa0a6b22d4daf..480ecdb408d4caa4302cafafa9fdb8832f9b7923 100644
--- a/pallets/authority-members/src/tests.rs
+++ b/pallets/authority-members/src/tests.rs
@@ -35,6 +35,7 @@ fn test_genesis_build() {
             Some(MemberData {
                 expire_on_session: 0,
                 must_rotate_keys_before: 5,
+                owner_key: 3,
             })
         );
         assert_eq!(
@@ -42,6 +43,7 @@ fn test_genesis_build() {
             Some(MemberData {
                 expire_on_session: 0,
                 must_rotate_keys_before: 5,
+                owner_key: 6,
             })
         );
         assert_eq!(
@@ -49,6 +51,7 @@ fn test_genesis_build() {
             Some(MemberData {
                 expire_on_session: 0,
                 must_rotate_keys_before: 5,
+                owner_key: 9,
             })
         );
 
@@ -92,6 +95,7 @@ fn test_max_keys_life_rule() {
             Some(MemberData {
                 expire_on_session: 0,
                 must_rotate_keys_before: 7,
+                owner_key: 3,
             })
         );
         assert_eq!(
@@ -99,6 +103,7 @@ fn test_max_keys_life_rule() {
             Some(MemberData {
                 expire_on_session: 0,
                 must_rotate_keys_before: 7,
+                owner_key: 6,
             })
         );
 
@@ -138,6 +143,7 @@ fn test_go_offline() {
             Some(MemberData {
                 expire_on_session: 0,
                 must_rotate_keys_before: 5,
+                owner_key: 9,
             })
         );
 
@@ -148,6 +154,7 @@ fn test_go_offline() {
             Some(MemberData {
                 expire_on_session: 4,
                 must_rotate_keys_before: 5,
+                owner_key: 9,
             })
         );
         assert_eq!(AuthorityMembers::members_expire_on(4), vec![9],);
@@ -186,6 +193,7 @@ fn test_go_online() {
             Some(MemberData {
                 expire_on_session: 2,
                 must_rotate_keys_before: 5,
+                owner_key: 12,
             })
         );
 
@@ -201,6 +209,7 @@ fn test_go_online() {
             Some(MemberData {
                 expire_on_session: 2,
                 must_rotate_keys_before: 5,
+                owner_key: 12,
             })
         );
 
@@ -280,6 +289,7 @@ fn test_go_online_then_go_offline_in_same_session() {
             Some(MemberData {
                 expire_on_session: 2,
                 must_rotate_keys_before: 5,
+                owner_key: 12,
             })
         );
     });
@@ -307,6 +317,7 @@ fn test_go_offline_then_go_online_in_same_session() {
             Some(MemberData {
                 expire_on_session: 0,
                 must_rotate_keys_before: 5,
+                owner_key: 9,
             })
         );
     });
diff --git a/pallets/authority-members/src/types.rs b/pallets/authority-members/src/types.rs
index fb3c0746e4e77ca134b7f11dd1ef8d8f40d8a6b3..b9e4bb87e79d5df842d776d1715d6c67c92a248b 100644
--- a/pallets/authority-members/src/types.rs
+++ b/pallets/authority-members/src/types.rs
@@ -24,16 +24,18 @@ use sp_staking::SessionIndex;
 
 #[cfg_attr(feature = "std", derive(Debug, Deserialize, Serialize))]
 #[derive(Encode, Decode, Clone, PartialEq, Eq, TypeInfo)]
-pub struct MemberData {
+pub struct MemberData<AccountId> {
     pub expire_on_session: SessionIndex,
     pub must_rotate_keys_before: SessionIndex,
+    pub owner_key: AccountId,
 }
 
-impl MemberData {
-    pub fn new_genesis(must_rotate_keys_before: SessionIndex) -> Self {
+impl<AccountId> MemberData<AccountId> {
+    pub fn new_genesis(must_rotate_keys_before: SessionIndex, owner_key: AccountId) -> Self {
         MemberData {
             expire_on_session: 0,
             must_rotate_keys_before,
+            owner_key,
         }
     }
 }
diff --git a/pallets/duniter-wot/src/mock.rs b/pallets/duniter-wot/src/mock.rs
index 08dc319fbf51b7aaa2412c0e8a4ffac4ae773770..da821daa430f73d5e2654e4fd426b49af88956b1 100644
--- a/pallets/duniter-wot/src/mock.rs
+++ b/pallets/duniter-wot/src/mock.rs
@@ -118,11 +118,11 @@ impl pallet_identity::Config for Test {
     type IsMember = Membership;
     type OnIdtyChange = DuniterWot;
     type MaxDisabledPeriod = MaxDisabledPeriod;
+    type RemoveIdentityConsumers = ();
 }
 
 // Membership
 parameter_types! {
-    pub const ExternalizeMembershipStorage: bool = false;
     pub const MembershipPeriod: u64 = 5;
     pub const PendingMembershipPeriod: u64 = 3;
     pub const RenewablePeriod: u64 = 2;
@@ -133,10 +133,8 @@ impl pallet_membership::Config<Instance1> for Test {
     type IsIdtyAllowedToRenewMembership = DuniterWot;
     type IsIdtyAllowedToRequestMembership = DuniterWot;
     type Event = Event;
-    type ExternalizeMembershipStorage = ExternalizeMembershipStorage;
     type IdtyId = IdtyIndex;
     type IdtyIdOf = Identity;
-    type MembershipExternalStorage = sp_membership::traits::NoExternalStorage;
     type MembershipPeriod = MembershipPeriod;
     type MetaData = crate::MembershipMetaData<u64>;
     type OnEvent = DuniterWot;
diff --git a/pallets/identity/src/lib.rs b/pallets/identity/src/lib.rs
index 6dd73b244bd6fbc3d19d9ef3d314f4be6f4d51a0..9602885ba0ed5ebabe340b211e7e23b8aa72804c 100644
--- a/pallets/identity/src/lib.rs
+++ b/pallets/identity/src/lib.rs
@@ -90,6 +90,9 @@ pub mod pallet {
         /// Maximum period with disabled status, after this period, the identity is permanently
         /// deleted
         type MaxDisabledPeriod: Get<Self::BlockNumber>;
+        /// Handle the logic that remove all identity consumers.
+        /// "identity consumers" mean all things that rely on the existence of the identity.
+        type RemoveIdentityConsumers: RemoveIdentityConsumers<Self::IdtyIndex>;
     }
 
     // GENESIS STUFFĂ‚ //
@@ -464,10 +467,11 @@ pub mod pallet {
     impl<T: Config> Pallet<T> {
         pub(super) fn do_remove_identity(idty_index: T::IdtyIndex) -> Weight {
             if let Some(idty_val) = Identities::<T>::take(idty_index) {
+                T::RemoveIdentityConsumers::remove_idty_consumers(idty_index);
                 frame_system::Pallet::<T>::dec_sufficients(&idty_val.owner_key);
+                Self::deposit_event(Event::IdtyRemoved { idty_index });
+                T::OnIdtyChange::on_idty_change(idty_index, IdtyEvent::Removed);
             }
-            Self::deposit_event(Event::IdtyRemoved { idty_index });
-            T::OnIdtyChange::on_idty_change(idty_index, IdtyEvent::Removed);
             0
         }
         fn get_next_idty_index() -> T::IdtyIndex {
diff --git a/pallets/identity/src/mock.rs b/pallets/identity/src/mock.rs
index 1cea91aa92a04363f51619fdffbcdfcaa9ce9ef6..3d5103e1d828fa15f1225d72041a0408deb6b7f8 100644
--- a/pallets/identity/src/mock.rs
+++ b/pallets/identity/src/mock.rs
@@ -110,6 +110,7 @@ impl pallet_identity::Config for Test {
     type IsMember = IsMemberTestImpl;
     type OnIdtyChange = ();
     type MaxDisabledPeriod = MaxDisabledPeriod;
+    type RemoveIdentityConsumers = ();
 }
 
 // Build genesis storage according to the mock runtime.
diff --git a/pallets/identity/src/traits.rs b/pallets/identity/src/traits.rs
index 9163e2f1744657ceddce8feda4ed68a0bf89afda..d7db3cbe984a38b0cc80e59aec304b9ebe52d672 100644
--- a/pallets/identity/src/traits.rs
+++ b/pallets/identity/src/traits.rs
@@ -47,3 +47,12 @@ impl<T: Config> OnIdtyChange<T> for () {
         0
     }
 }
+
+pub trait RemoveIdentityConsumers<IndtyIndex> {
+    fn remove_idty_consumers(idty_index: IndtyIndex) -> Weight;
+}
+impl<IndtyIndex> RemoveIdentityConsumers<IndtyIndex> for () {
+    fn remove_idty_consumers(_: IndtyIndex) -> Weight {
+        0
+    }
+}
diff --git a/pallets/membership/src/lib.rs b/pallets/membership/src/lib.rs
index c543a17d0b2c2c5e2ecb62fafe3d3f8f100008e9..2886888b9f6a51b036e8a34ede726deed34e5997 100644
--- a/pallets/membership/src/lib.rs
+++ b/pallets/membership/src/lib.rs
@@ -44,7 +44,7 @@ pub mod pallet {
     use super::*;
     use frame_support::traits::StorageVersion;
     use frame_system::pallet_prelude::*;
-    use sp_runtime::traits::{Convert, IsMember};
+    use sp_runtime::traits::Convert;
 
     /// The current storage version.
     const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
@@ -63,19 +63,12 @@ pub mod pallet {
         type IsIdtyAllowedToRequestMembership: IsIdtyAllowedToRequestMembership<Self::IdtyId>;
         /// Because this pallet emits events, it depends on the runtime's definition of an event.
         type Event: From<Event<Self, I>> + IsType<<Self as frame_system::Config>::Event>;
-        /// Specify true if you want to externalize the storage of memberships, but in this case
-        /// you must provide an implementation of `MembershipExternalStorage`
-        type ExternalizeMembershipStorage: Get<bool>;
         /// Something that identifies an identity
         type IdtyId: Copy + MaybeSerializeDeserialize + Parameter + Ord;
         /// Something that give the IdtyId on an account id
         type IdtyIdOf: Convert<Self::AccountId, Option<Self::IdtyId>>;
         /// Optional metadata
         type MetaData: Parameter + Validate<Self::AccountId>;
-        /// Provide your implementation of membership storage here, if you want the pallet to
-        /// handle the storage for you, specify `()` and set `ExternalizeMembershipStorage` to
-        /// `false`.
-        type MembershipExternalStorage: MembershipExternalStorage<Self::BlockNumber, Self::IdtyId>;
         #[pallet::constant]
         /// Maximum life span of a non-renewable membership (in number of blocks)
         type MembershipPeriod: Get<Self::BlockNumber>;
@@ -113,11 +106,7 @@ pub mod pallet {
         fn build(&self) {
             for (idty_id, membership_data) in &self.memberships {
                 MembershipsExpireOn::<T, I>::append(membership_data.expire_on, idty_id);
-                if T::ExternalizeMembershipStorage::get() {
-                    T::MembershipExternalStorage::insert(*idty_id, *membership_data);
-                } else {
-                    Membership::<T, I>::insert(idty_id, membership_data);
-                }
+                Membership::<T, I>::insert(idty_id, membership_data);
             }
         }
     }
@@ -369,16 +358,17 @@ pub mod pallet {
             Ok(().into())
         }
         pub(super) fn do_revoke_membership(idty_id: T::IdtyId) -> Weight {
-            Self::remove_membership(&idty_id);
-            if T::RevocationPeriod::get() > Zero::zero() {
-                let block_number = frame_system::pallet::Pallet::<T>::block_number();
-                let pruned_on = block_number + T::RevocationPeriod::get();
+            if Self::remove_membership(&idty_id) {
+                if T::RevocationPeriod::get() > Zero::zero() {
+                    let block_number = frame_system::pallet::Pallet::<T>::block_number();
+                    let pruned_on = block_number + T::RevocationPeriod::get();
 
-                RevokedMembership::<T, I>::insert(idty_id, ());
-                RevokedMembershipsPrunedOn::<T, I>::append(pruned_on, idty_id);
+                    RevokedMembership::<T, I>::insert(idty_id, ());
+                    RevokedMembershipsPrunedOn::<T, I>::append(pruned_on, idty_id);
+                }
+                Self::deposit_event(Event::MembershipRevoked(idty_id));
+                T::OnEvent::on_event(&sp_membership::Event::MembershipRevoked(idty_id));
             }
-            Self::deposit_event(Event::MembershipRevoked(idty_id));
-            T::OnEvent::on_event(&sp_membership::Event::MembershipRevoked(idty_id));
 
             0
         }
@@ -436,32 +426,16 @@ pub mod pallet {
         }
 
         pub(super) fn is_member_inner(idty_id: &T::IdtyId) -> bool {
-            if T::ExternalizeMembershipStorage::get() {
-                T::MembershipExternalStorage::is_member(idty_id)
-            } else {
-                Membership::<T, I>::contains_key(idty_id)
-            }
+            Membership::<T, I>::contains_key(idty_id)
         }
         fn insert_membership(idty_id: T::IdtyId, membership_data: MembershipData<T::BlockNumber>) {
-            if T::ExternalizeMembershipStorage::get() {
-                T::MembershipExternalStorage::insert(idty_id, membership_data);
-            } else {
-                Membership::<T, I>::insert(idty_id, membership_data);
-            }
+            Membership::<T, I>::insert(idty_id, membership_data);
         }
         fn get_membership(idty_id: &T::IdtyId) -> Option<MembershipData<T::BlockNumber>> {
-            if T::ExternalizeMembershipStorage::get() {
-                T::MembershipExternalStorage::get(idty_id)
-            } else {
-                Membership::<T, I>::try_get(idty_id).ok()
-            }
+            Membership::<T, I>::try_get(idty_id).ok()
         }
-        fn remove_membership(idty_id: &T::IdtyId) {
-            if T::ExternalizeMembershipStorage::get() {
-                T::MembershipExternalStorage::remove(idty_id);
-            } else {
-                Membership::<T, I>::remove(idty_id);
-            }
+        fn remove_membership(idty_id: &T::IdtyId) -> bool {
+            Membership::<T, I>::take(idty_id).is_some()
         }
     }
 }
diff --git a/pallets/membership/src/mock.rs b/pallets/membership/src/mock.rs
index 507443161e64b76bcfde577df65fc2a0bc2c1bda..e21a415375d0f72bdade6a03fcdf66556f04761c 100644
--- a/pallets/membership/src/mock.rs
+++ b/pallets/membership/src/mock.rs
@@ -78,7 +78,6 @@ impl system::Config for Test {
 }
 
 parameter_types! {
-    pub const ExternalizeMembershipStorage: bool = false;
     pub const MembershipPeriod: BlockNumber = 5;
     pub const PendingMembershipPeriod: BlockNumber = 3;
     pub const RenewablePeriod: BlockNumber = 2;
@@ -89,10 +88,8 @@ impl pallet_membership::Config for Test {
     type IsIdtyAllowedToRenewMembership = ();
     type IsIdtyAllowedToRequestMembership = ();
     type Event = Event;
-    type ExternalizeMembershipStorage = ExternalizeMembershipStorage;
     type IdtyId = IdtyId;
     type IdtyIdOf = ConvertInto;
-    type MembershipExternalStorage = crate::NoExternalStorage;
     type MembershipPeriod = MembershipPeriod;
     type MetaData = ();
     type OnEvent = ();
diff --git a/primitives/membership/src/traits.rs b/primitives/membership/src/traits.rs
index f437cfa0a2f330500e7c62a46bec185ff0ac67d9..2690cb58e6b164e675f038b268329d133d34744e 100644
--- a/primitives/membership/src/traits.rs
+++ b/primitives/membership/src/traits.rs
@@ -14,8 +14,7 @@
 // You should have received a copy of the GNU Affero General Public License
 // along with Substrate-Libre-Currency. If not, see <https://www.gnu.org/licenses/>.
 
-use crate::*;
-use frame_support::pallet_prelude::{TypeInfo, Weight};
+use frame_support::pallet_prelude::Weight;
 
 pub trait IsIdtyAllowedToRenewMembership<IdtyId> {
     fn is_idty_allowed_to_renew_membership(idty_id: &IdtyId) -> bool;
@@ -55,36 +54,6 @@ pub trait MembersCount {
     fn members_count() -> u32;
 }
 
-pub trait MembershipExternalStorage<BlockNumber: Decode + Encode + TypeInfo, IdtyId>:
-    sp_runtime::traits::IsMember<IdtyId>
-{
-    fn insert(idty_id: IdtyId, membership_data: MembershipData<BlockNumber>);
-    fn get(idty_id: &IdtyId) -> Option<MembershipData<BlockNumber>>;
-    fn remove(idty_id: &IdtyId);
-}
-
-static INVALID_CONF_MSG: &str = "invalid pallet configuration: if `MembershipExternalStorage` = (), you must set `ExternalizeMembershipStorage` to `false`.";
-
-pub struct NoExternalStorage;
-impl<IdtyId> sp_runtime::traits::IsMember<IdtyId> for NoExternalStorage {
-    fn is_member(_: &IdtyId) -> bool {
-        panic!("{}", INVALID_CONF_MSG)
-    }
-}
-impl<BlockNumber: Decode + Encode + TypeInfo, IdtyId> MembershipExternalStorage<BlockNumber, IdtyId>
-    for NoExternalStorage
-{
-    fn insert(_: IdtyId, _: MembershipData<BlockNumber>) {
-        panic!("{}", INVALID_CONF_MSG)
-    }
-    fn get(_: &IdtyId) -> Option<MembershipData<BlockNumber>> {
-        panic!("{}", INVALID_CONF_MSG)
-    }
-    fn remove(_: &IdtyId) {
-        panic!("{}", INVALID_CONF_MSG)
-    }
-}
-
 pub trait Validate<AccountId> {
     fn validate(&self, account_id: &AccountId) -> bool;
 }
diff --git a/runtime/common/Cargo.toml b/runtime/common/Cargo.toml
index 9a4aa13284a8f07883babf98f6323bbafbbc3b8e..d664f6723d08da0ba20a3cff9c7503b56b98d11a 100644
--- a/runtime/common/Cargo.toml
+++ b/runtime/common/Cargo.toml
@@ -21,6 +21,7 @@ std = [
     'codec/std',
     'frame-support/std',
     'frame-system/std',
+	'log/std',
     'pallet-authority-members/std',
     'pallet-balances/std',
     'pallet-certification/std',
@@ -46,6 +47,7 @@ pallet-ud-accounts-storage = { path = '../../pallets/ud-accounts-storage', defau
 sp-membership = { path = '../../primitives/membership', default-features = false }
 
 # Crates.io
+log = { version = "0.4.14", default-features = false }
 smallvec = "1.6.1"
 
 # Substrate
diff --git a/runtime/common/src/handlers.rs b/runtime/common/src/handlers.rs
index cfffc01cdcaf09f47c9ad28b7fc9884787f7ddb5..f601b2dc5bcffae9265aa42a1ead14e7783fc4b6 100644
--- a/runtime/common/src/handlers.rs
+++ b/runtime/common/src/handlers.rs
@@ -20,6 +20,7 @@ use frame_support::dispatch::UnfilteredDispatchable;
 use frame_support::instances::{Instance1, Instance2};
 use frame_support::pallet_prelude::Weight;
 use frame_support::Parameter;
+use sp_runtime::traits::IsMember;
 
 pub struct OnMembershipEventHandler<Inner, Runtime>(core::marker::PhantomData<(Inner, Runtime)>);
 
@@ -132,3 +133,52 @@ where
         0
     }
 }
+
+pub struct RemoveIdentityConsumersImpl<Runtime>(core::marker::PhantomData<Runtime>);
+impl<Runtime> pallet_identity::traits::RemoveIdentityConsumers<IdtyIndex>
+    for RemoveIdentityConsumersImpl<Runtime>
+where
+    Runtime: pallet_identity::Config<IdtyIndex = IdtyIndex>
+        + pallet_authority_members::Config<MemberId = IdtyIndex>
+        + pallet_membership::Config<Instance1, IdtyId = IdtyIndex>
+        + pallet_membership::Config<Instance2, IdtyId = IdtyIndex>,
+{
+    fn remove_idty_consumers(idty_index: IdtyIndex) -> Weight {
+        // Remove smith member
+        if pallet_membership::Pallet::<Runtime, Instance2>::is_member(&idty_index) {
+            if let Err(e) = pallet_authority_members::Pallet::<Runtime>::remove_member(
+                frame_system::RawOrigin::Root.into(),
+                idty_index,
+            ) {
+                log::error!(
+                    target: "runtime::common",
+                    "Logic error: fail to remove authority member in remove_idty_consumers(): {:?}",
+                    e
+                );
+            }
+            if let Err(e) = pallet_membership::Pallet::<Runtime, Instance2>::revoke_membership(
+                frame_system::RawOrigin::Root.into(),
+                Some(idty_index),
+            ) {
+                log::error!(
+                    target: "runtime::common",
+                    "Logic error: fail to revoke smith membership in remove_idty_consumers(): {:?}",
+                    e
+                );
+            }
+        }
+        // Remove "classic" member
+        if let Err(e) = pallet_membership::Pallet::<Runtime, Instance1>::revoke_membership(
+            frame_system::RawOrigin::Root.into(),
+            Some(idty_index),
+        ) {
+            log::error!(
+                target: "runtime::common",
+                "Logic error: fail to revoke membership in remove_idty_consumers(): {:?}",
+                e
+            );
+        }
+
+        0
+    }
+}
diff --git a/runtime/common/src/pallets_config.rs b/runtime/common/src/pallets_config.rs
index bc7ebed3c1a6625edeadeb59fa599712f45c99a6..4a9ae041799d4cd606266001e9ed4f8acaaa006b 100644
--- a/runtime/common/src/pallets_config.rs
+++ b/runtime/common/src/pallets_config.rs
@@ -344,16 +344,15 @@ macro_rules! pallets_config {
 			type IsMember = Membership;
 			type OnIdtyChange = Wot;
 			type MaxDisabledPeriod = MaxDisabledPeriod;
+			type RemoveIdentityConsumers = RemoveIdentityConsumersImpl<Self>;
 		}
 
 		impl pallet_membership::Config<frame_support::instances::Instance1> for Runtime {
 			type IsIdtyAllowedToRenewMembership = Wot;
 			type IsIdtyAllowedToRequestMembership = Wot;
 			type Event = Event;
-			type ExternalizeMembershipStorage = frame_support::traits::ConstBool<false>;
 			type IdtyId = IdtyIndex;
 			type IdtyIdOf = Identity;
-			type MembershipExternalStorage = sp_membership::traits::NoExternalStorage;
 			type MembershipPeriod = MembershipPeriod;
 			type MetaData = pallet_duniter_wot::MembershipMetaData<AccountId>;
 			type OnEvent = OnMembershipEventHandler<Wot, Runtime>;
@@ -390,10 +389,8 @@ macro_rules! pallets_config {
 			type IsIdtyAllowedToRenewMembership = ();
 			type IsIdtyAllowedToRequestMembership = ();
 			type Event = Event;
-			type ExternalizeMembershipStorage = frame_support::traits::ConstBool<false>;
 			type IdtyId = IdtyIndex;
 			type IdtyIdOf = Identity;
-			type MembershipExternalStorage = sp_membership::traits::NoExternalStorage;
 			type MembershipPeriod = SmithMembershipPeriod;
 			type MetaData = SmithsMembershipMetaData<opaque::SessionKeysWrapper>;
 			type OnEvent = OnSmithMembershipEventHandler<SmithsSubWot, Runtime>;