diff --git a/crates/tor-circmgr/src/isolation.rs b/crates/tor-circmgr/src/isolation.rs
index 05a0d423e8c0070160ba1c7770fee9027a16cee5..a1ccddd4b668ec495842927d95da11359bea29de 100644
--- a/crates/tor-circmgr/src/isolation.rs
+++ b/crates/tor-circmgr/src/isolation.rs
@@ -212,6 +212,134 @@ impl IsolationHelper for IsolationToken {
     }
 }
 
+/// Helper macro to implement IsolationHelper for tuple of IsolationHelper
+macro_rules! tuple_impls {
+    ($(
+        $Tuple:ident {
+            $(($idx:tt) -> $T:ident)+
+        }
+    )+) => {
+        $(
+            impl<$($T:IsolationHelper),+> IsolationHelper for ($($T,)+) {
+                fn compatible_same_type(&self, other: &Self) -> bool {
+                    $(self.$idx.compatible_same_type(&other.$idx))&&+
+                }
+
+                fn join_same_type(&self, other: &Self) -> Option<Self> {
+                    Some((
+                    $(self.$idx.join_same_type(&other.$idx)?,)+
+                    ))
+                }
+            }
+        )+
+    }
+}
+
+tuple_impls! {
+    Tuple1 {
+        (0) -> A
+    }
+    Tuple2 {
+        (0) -> A
+        (1) -> B
+    }
+    Tuple3 {
+        (0) -> A
+        (1) -> B
+        (2) -> C
+    }
+    Tuple4 {
+        (0) -> A
+        (1) -> B
+        (2) -> C
+        (3) -> D
+    }
+    Tuple5 {
+        (0) -> A
+        (1) -> B
+        (2) -> C
+        (3) -> D
+        (4) -> E
+    }
+    Tuple6 {
+        (0) -> A
+        (1) -> B
+        (2) -> C
+        (3) -> D
+        (4) -> E
+        (5) -> F
+    }
+    Tuple7 {
+        (0) -> A
+        (1) -> B
+        (2) -> C
+        (3) -> D
+        (4) -> E
+        (5) -> F
+        (6) -> G
+    }
+    Tuple8 {
+        (0) -> A
+        (1) -> B
+        (2) -> C
+        (3) -> D
+        (4) -> E
+        (5) -> F
+        (6) -> G
+        (7) -> H
+    }
+    Tuple9 {
+        (0) -> A
+        (1) -> B
+        (2) -> C
+        (3) -> D
+        (4) -> E
+        (5) -> F
+        (6) -> G
+        (7) -> H
+        (8) -> I
+    }
+    Tuple10 {
+        (0) -> A
+        (1) -> B
+        (2) -> C
+        (3) -> D
+        (4) -> E
+        (5) -> F
+        (6) -> G
+        (7) -> H
+        (8) -> I
+        (9) -> J
+    }
+    Tuple11 {
+        (0) -> A
+        (1) -> B
+        (2) -> C
+        (3) -> D
+        (4) -> E
+        (5) -> F
+        (6) -> G
+        (7) -> H
+        (8) -> I
+        (9) -> J
+        (10) -> K
+    }
+    Tuple12 {
+        (0) -> A
+        (1) -> B
+        (2) -> C
+        (3) -> D
+        (4) -> E
+        (5) -> F
+        (6) -> G
+        (7) -> H
+        (8) -> I
+        (9) -> J
+        (10) -> K
+        (11) -> L
+    }
+}
+
 #[cfg(test)]
 pub(crate) mod test {
     use super::*;
@@ -326,4 +454,35 @@ pub(crate) mod test {
         assert!(token_1.join(other_1.as_ref()).is_none());
         assert!(other_1.join(token_1.as_ref()).is_none());
     }
+
+    #[test]
+    fn isolation_tuple() {
+        let token_1 = IsolationToken::new();
+        let token_2 = IsolationToken::new();
+        let other_1 = OtherIsolation(0);
+        let other_2 = OtherIsolation(1);
+
+        let token_12: Box<dyn Isolation> = Box::new((token_1, token_2));
+        let token_21: Box<dyn Isolation> = Box::new((token_2, token_1));
+        let mix_11: Box<dyn Isolation> = Box::new((token_1, other_1));
+        let mix_12: Box<dyn Isolation> = Box::new((token_1, other_2));
+        let revmix_11: Box<dyn Isolation> = Box::new((other_1, token_1));
+
+        let join_token = token_12
+            .join(token_12.as_ref())
+            .expect("join should have returned Some");
+        assert!(join_token.compatible(token_12.as_ref()));
+        let join_mix = mix_12
+            .join(mix_12.as_ref())
+            .expect("join should have returned Some");
+        assert!(join_mix.compatible(mix_12.as_ref()));
+
+        let isol_list = [token_12, token_21, mix_11, mix_12, revmix_11];
+
+        for (i, isol1) in isol_list.iter().enumerate() {
+            for (j, isol2) in isol_list.iter().enumerate() {
+                assert_eq!(isol1.compatible(isol2.as_ref()), i == j);
+            }
+        }
+    }
 }