[ICD] Add ClientType support to the ICDManager and ICD Management cluster (#33811)

* update icdm xml

* generated files

* Add clientType to the ICDMonitoring table

* Add client type buisness logic to ICDM cluster

* Add client type logic to the ICDManager

* finish clean up

* make ClientType arg mandatory

* regen

---------

Co-authored-by: yunhanw <yunhanw@google.com>
diff --git a/examples/chip-tool/commands/clusters/ClusterCommand.h b/examples/chip-tool/commands/clusters/ClusterCommand.h
index ac141fb..bf5c61f 100644
--- a/examples/chip-tool/commands/clusters/ClusterCommand.h
+++ b/examples/chip-tool/commands/clusters/ClusterCommand.h
@@ -21,6 +21,7 @@
 #include "DataModelLogger.h"
 #include "ModelCommand.h"
 #include <app/tests/suites/commands/interaction_model/InteractionModel.h>
+#include <lib/core/ClusterEnums.h>
 
 class ClusterCommand : public InteractionModelCommands, public ModelCommand, public chip::app::CommandSender::Callback
 {
@@ -70,6 +71,7 @@
         ReturnErrorOnFailure(InteractionModelCommands::SendCommand(device, endpointId, clusterId, commandId, value));
         mScopedNodeId     = chip::ScopedNodeId(value.checkInNodeID, device->GetSecureSession().Value()->GetFabricIndex());
         mMonitoredSubject = value.monitoredSubject;
+        mClientType       = value.clientType;
         memcpy(mICDSymmetricKey, value.key.data(), value.key.size());
         return CHIP_NO_ERROR;
     }
@@ -148,6 +150,7 @@
                 clientInfo.peer_node         = mScopedNodeId;
                 clientInfo.monitored_subject = mMonitoredSubject;
                 clientInfo.start_icd_counter = value.ICDCounter;
+                clientInfo.client_type       = mClientType;
 
                 StoreICDEntryWithKey(clientInfo, chip::ByteSpan(mICDSymmetricKey));
             }
@@ -258,8 +261,10 @@
     chip::ClusterId mClusterId;
     chip::CommandId mCommandId;
     chip::ScopedNodeId mScopedNodeId;
-    uint64_t mMonitoredSubject = static_cast<uint64_t>(0);
+    uint64_t mMonitoredSubject                                     = static_cast<uint64_t>(0);
+    chip::app::Clusters::IcdManagement::ClientTypeEnum mClientType = chip::app::Clusters::IcdManagement::ClientTypeEnum::kPermanent;
     uint8_t mICDSymmetricKey[chip::Crypto::kAES_CCM128_Key_Length];
+
     CHIP_ERROR mError = CHIP_NO_ERROR;
     CustomArgument mPayload;
 };
diff --git a/examples/chip-tool/commands/icd/ICDCommand.cpp b/examples/chip-tool/commands/icd/ICDCommand.cpp
index 505e6ad..3f7bfb3 100644
--- a/examples/chip-tool/commands/icd/ICDCommand.cpp
+++ b/examples/chip-tool/commands/icd/ICDCommand.cpp
@@ -21,6 +21,7 @@
 #include <app/icd/client/DefaultICDClientStorage.h>
 #include <crypto/DefaultSessionKeystore.h>
 #include <crypto/RawKeySessionKeystore.h>
+#include <string>
 
 using namespace ::chip;
 using namespace ::chip::app;
@@ -36,31 +37,32 @@
         return CHIP_ERROR_NO_MEMORY;
     }
     app::DefaultICDClientStorage::ICDClientInfoIteratorWrapper clientInfoIteratorWrapper(iter);
-    fprintf(stderr, "  +-----------------------------------------------------------------------------+\n");
-    fprintf(stderr, "  | %-75s |\n", "Known ICDs:");
-    fprintf(stderr, "  +-----------------------------------------------------------------------------+\n");
-    fprintf(stderr, "  | %20s | %15s | %15s | %16s |\n", "Fabric Index:Node ID", "Start Counter", "Counter Offset",
-            "MonitoredSubject");
+    fprintf(stderr, "  +------------------------------------------------------------------------------------------+\n");
+    fprintf(stderr, "  | %-88s |\n", "Known ICDs:");
+    fprintf(stderr, "  +------------------------------------------------------------------------------------------+\n");
+    fprintf(stderr, "  | %20s | %15s | %15s | %16s | %10s |\n", "Fabric Index:Node ID", "Start Counter", "Counter Offset",
+            "MonitoredSubject", "ClientType");
 
     while (iter->Next(info))
     {
-        fprintf(stderr, "  +-----------------------------------------------------------------------------+\n");
-        fprintf(stderr, "  | %3" PRIu32 ":" ChipLogFormatX64 " | %15" PRIu32 " | %15" PRIu32 " | " ChipLogFormatX64 " |\n",
+        fprintf(stderr, "  +------------------------------------------------------------------------------------------+\n");
+        fprintf(stderr, "  | %3" PRIu32 ":" ChipLogFormatX64 " | %15" PRIu32 " | %15" PRIu32 " | " ChipLogFormatX64 " | %10u |\n",
                 static_cast<uint32_t>(info.peer_node.GetFabricIndex()), ChipLogValueX64(info.peer_node.GetNodeId()),
-                info.start_icd_counter, info.offset, ChipLogValueX64(info.monitored_subject));
+                info.start_icd_counter, info.offset, ChipLogValueX64(info.monitored_subject),
+                static_cast<uint8_t>(info.client_type));
 
         static_assert(std::is_same<decltype(CHIPCommand::sSessionKeystore), Crypto::RawKeySessionKeystore>::value,
                       "The following BytesToHex can copy/encode the key bytes from sharedKey to hexadecimal format, which only "
                       "works for RawKeySessionKeystore");
         Encoding::BytesToHex(info.aes_key_handle.As<Crypto::Symmetric128BitsKeyByteArray>(), Crypto::kAES_CCM128_Key_Length,
                              icdAesKeyHex, sizeof(icdAesKeyHex), chip::Encoding::HexFlags::kNullTerminate);
-        fprintf(stderr, "  | aes key: %60s |\n", icdAesKeyHex);
+        fprintf(stderr, "  | aes key:  %60s                   |\n", icdAesKeyHex);
         Encoding::BytesToHex(info.hmac_key_handle.As<Crypto::Symmetric128BitsKeyByteArray>(), Crypto::kHMAC_CCM128_Key_Length,
                              icdHmacKeyHex, sizeof(icdHmacKeyHex), chip::Encoding::HexFlags::kNullTerminate);
-        fprintf(stderr, "  | hmac key: %60s |\n", icdHmacKeyHex);
+        fprintf(stderr, "  | hmac key: %60s                   |\n", icdHmacKeyHex);
     }
 
-    fprintf(stderr, "  +-----------------------------------------------------------------------------+\n");
+    fprintf(stderr, "  +------------------------------------------------------------------------------------------+\n");
     SetCommandExitStatus(CHIP_NO_ERROR);
     return CHIP_NO_ERROR;
 }
diff --git a/examples/chip-tool/commands/pairing/PairingCommand.cpp b/examples/chip-tool/commands/pairing/PairingCommand.cpp
index 7bddfa3..35ce2ba 100644
--- a/examples/chip-tool/commands/pairing/PairingCommand.cpp
+++ b/examples/chip-tool/commands/pairing/PairingCommand.cpp
@@ -157,6 +157,10 @@
         {
             mICDMonitoredSubject.SetValue(mICDCheckInNodeId.Value());
         }
+        if (!mICDClientType.HasValue())
+        {
+            mICDClientType.SetValue(app::Clusters::IcdManagement::ClientTypeEnum::kPermanent);
+        }
         // These Optionals must have values now.
         // The commissioner will verify these values.
         params.SetICDSymmetricKey(mICDSymmetricKey.Value());
@@ -166,6 +170,7 @@
         }
         params.SetICDCheckInNodeId(mICDCheckInNodeId.Value());
         params.SetICDMonitoredSubject(mICDMonitoredSubject.Value());
+        params.SetICDClientType(mICDClientType.Value());
     }
 
     return params;
@@ -459,7 +464,7 @@
                                sizeof(icdSymmetricKeyHex), chip::Encoding::HexFlags::kNullTerminate);
 
     app::ICDClientInfo clientInfo;
-    clientInfo.peer_node         = nodeId;
+    clientInfo.peer_node         = chip::ScopedNodeId(mICDCheckInNodeId.Value(), nodeId.GetFabricIndex());
     clientInfo.monitored_subject = mICDMonitoredSubject.Value();
     clientInfo.start_icd_counter = icdCounter;
 
diff --git a/examples/chip-tool/commands/pairing/PairingCommand.h b/examples/chip-tool/commands/pairing/PairingCommand.h
index facb0f2..0cf4e1d 100644
--- a/examples/chip-tool/commands/pairing/PairingCommand.h
+++ b/examples/chip-tool/commands/pairing/PairingCommand.h
@@ -74,6 +74,8 @@
                     "The check-in node id for the ICD, default: node id of the commissioner.");
         AddArgument("icd-monitored-subject", 0, UINT64_MAX, &mICDMonitoredSubject,
                     "The monitored subject of the ICD, default: The node id used for icd-check-in-nodeid.");
+        AddArgument("icd-client-type", 0, 1, &mICDClientType,
+                    "The ClientType of the client registering, default: Permanent client - 0");
         AddArgument("icd-symmetric-key", &mICDSymmetricKey, "The 16 bytes ICD symmetric key, default: randomly generated.");
         AddArgument("icd-stay-active-duration", 0, UINT32_MAX, &mICDStayActiveDurationMsec,
                     "If set, a LIT ICD that is commissioned will be requested to stay active for this many milliseconds");
@@ -245,6 +247,7 @@
     chip::Optional<NodeId> mICDCheckInNodeId;
     chip::Optional<chip::ByteSpan> mICDSymmetricKey;
     chip::Optional<uint64_t> mICDMonitoredSubject;
+    chip::Optional<chip::app::Clusters::IcdManagement::ClientTypeEnum> mICDClientType;
     chip::Optional<uint32_t> mICDStayActiveDurationMsec;
     chip::app::DataModel::List<chip::app::Clusters::TimeSynchronization::Structs::TimeZoneStruct::Type> mTimeZoneList;
     TypedComplexArgument<chip::app::DataModel::List<chip::app::Clusters::TimeSynchronization::Structs::TimeZoneStruct::Type>>
diff --git a/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter b/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter
index d64a06c..9bffee1 100644
--- a/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter
+++ b/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter
@@ -1315,6 +1315,11 @@
 cluster IcdManagement = 70 {
   revision 2;
 
+  enum ClientTypeEnum : enum8 {
+    kPermanent = 0;
+    kEphemeral = 1;
+  }
+
   enum OperatingModeEnum : enum8 {
     kSIT = 0;
     kLIT = 1;
@@ -1349,6 +1354,7 @@
   fabric_scoped struct MonitoringRegistrationStruct {
     fabric_sensitive node_id checkInNodeID = 1;
     fabric_sensitive int64u monitoredSubject = 2;
+    fabric_sensitive ClientTypeEnum clientType = 4;
     fabric_idx fabricIndex = 254;
   }
 
@@ -1373,6 +1379,7 @@
     int64u monitoredSubject = 1;
     octet_string<16> key = 2;
     optional octet_string<16> verificationKey = 3;
+    ClientTypeEnum clientType = 4;
   }
 
   response struct RegisterClientResponse = 1 {
diff --git a/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter b/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter
index d0861d5..70cae9e 100644
--- a/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter
+++ b/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter
@@ -1315,6 +1315,11 @@
 cluster IcdManagement = 70 {
   revision 2;
 
+  enum ClientTypeEnum : enum8 {
+    kPermanent = 0;
+    kEphemeral = 1;
+  }
+
   enum OperatingModeEnum : enum8 {
     kSIT = 0;
     kLIT = 1;
@@ -1349,6 +1354,7 @@
   fabric_scoped struct MonitoringRegistrationStruct {
     fabric_sensitive node_id checkInNodeID = 1;
     fabric_sensitive int64u monitoredSubject = 2;
+    fabric_sensitive ClientTypeEnum clientType = 4;
     fabric_idx fabricIndex = 254;
   }
 
@@ -1373,6 +1379,7 @@
     int64u monitoredSubject = 1;
     octet_string<16> key = 2;
     optional octet_string<16> verificationKey = 3;
+    ClientTypeEnum clientType = 4;
   }
 
   response struct RegisterClientResponse = 1 {
diff --git a/examples/fabric-admin/commands/pairing/PairingCommand.cpp b/examples/fabric-admin/commands/pairing/PairingCommand.cpp
index 8a261b0..521325a 100644
--- a/examples/fabric-admin/commands/pairing/PairingCommand.cpp
+++ b/examples/fabric-admin/commands/pairing/PairingCommand.cpp
@@ -157,6 +157,10 @@
         {
             mICDMonitoredSubject.SetValue(mICDCheckInNodeId.Value());
         }
+        if (!mICDClientType.HasValue())
+        {
+            mICDClientType.SetValue(app::Clusters::IcdManagement::ClientTypeEnum::kPermanent);
+        }
         // These Optionals must have values now.
         // The commissioner will verify these values.
         params.SetICDSymmetricKey(mICDSymmetricKey.Value());
@@ -166,6 +170,7 @@
         }
         params.SetICDCheckInNodeId(mICDCheckInNodeId.Value());
         params.SetICDMonitoredSubject(mICDMonitoredSubject.Value());
+        params.SetICDClientType(mICDClientType.Value());
     }
 
     return params;
@@ -459,7 +464,7 @@
                                sizeof(icdSymmetricKeyHex), chip::Encoding::HexFlags::kNullTerminate);
 
     app::ICDClientInfo clientInfo;
-    clientInfo.peer_node         = nodeId;
+    clientInfo.peer_node         = chip::ScopedNodeId(mICDCheckInNodeId.Value(), nodeId.GetFabricIndex());
     clientInfo.monitored_subject = mICDMonitoredSubject.Value();
     clientInfo.start_icd_counter = icdCounter;
 
diff --git a/examples/fabric-admin/commands/pairing/PairingCommand.h b/examples/fabric-admin/commands/pairing/PairingCommand.h
index fbd3344..647f2c3 100644
--- a/examples/fabric-admin/commands/pairing/PairingCommand.h
+++ b/examples/fabric-admin/commands/pairing/PairingCommand.h
@@ -84,6 +84,8 @@
                     "The check-in node id for the ICD, default: node id of the commissioner.");
         AddArgument("icd-monitored-subject", 0, UINT64_MAX, &mICDMonitoredSubject,
                     "The monitored subject of the ICD, default: The node id used for icd-check-in-nodeid.");
+        AddArgument("icd-client-type", 0, 1, &mICDClientType,
+                    "The ClientType of the client registering, default: Permanent client - 0");
         AddArgument("icd-symmetric-key", &mICDSymmetricKey, "The 16 bytes ICD symmetric key, default: randomly generated.");
         AddArgument("icd-stay-active-duration", 0, UINT32_MAX, &mICDStayActiveDurationMsec,
                     "If set, a LIT ICD that is commissioned will be requested to stay active for this many milliseconds");
@@ -258,6 +260,7 @@
     chip::Optional<char *> mCountryCode;
     chip::Optional<bool> mICDRegistration;
     chip::Optional<NodeId> mICDCheckInNodeId;
+    chip::Optional<chip::app::Clusters::IcdManagement::ClientTypeEnum> mICDClientType;
     chip::Optional<chip::ByteSpan> mICDSymmetricKey;
     chip::Optional<uint64_t> mICDMonitoredSubject;
     chip::Optional<uint32_t> mICDStayActiveDurationMsec;
diff --git a/examples/light-switch-app/light-switch-common/light-switch-app.matter b/examples/light-switch-app/light-switch-common/light-switch-app.matter
index c4f73e4..1380e67 100644
--- a/examples/light-switch-app/light-switch-common/light-switch-app.matter
+++ b/examples/light-switch-app/light-switch-common/light-switch-app.matter
@@ -1939,6 +1939,11 @@
 cluster IcdManagement = 70 {
   revision 2;
 
+  enum ClientTypeEnum : enum8 {
+    kPermanent = 0;
+    kEphemeral = 1;
+  }
+
   enum OperatingModeEnum : enum8 {
     kSIT = 0;
     kLIT = 1;
@@ -1973,6 +1978,7 @@
   fabric_scoped struct MonitoringRegistrationStruct {
     fabric_sensitive node_id checkInNodeID = 1;
     fabric_sensitive int64u monitoredSubject = 2;
+    fabric_sensitive ClientTypeEnum clientType = 4;
     fabric_idx fabricIndex = 254;
   }
 
@@ -1997,6 +2003,7 @@
     int64u monitoredSubject = 1;
     octet_string<16> key = 2;
     optional octet_string<16> verificationKey = 3;
+    ClientTypeEnum clientType = 4;
   }
 
   response struct RegisterClientResponse = 1 {
diff --git a/examples/light-switch-app/qpg/zap/switch.matter b/examples/light-switch-app/qpg/zap/switch.matter
index d105fde..f42b1f0 100644
--- a/examples/light-switch-app/qpg/zap/switch.matter
+++ b/examples/light-switch-app/qpg/zap/switch.matter
@@ -1736,6 +1736,11 @@
 cluster IcdManagement = 70 {
   revision 2;
 
+  enum ClientTypeEnum : enum8 {
+    kPermanent = 0;
+    kEphemeral = 1;
+  }
+
   enum OperatingModeEnum : enum8 {
     kSIT = 0;
     kLIT = 1;
@@ -1770,6 +1775,7 @@
   fabric_scoped struct MonitoringRegistrationStruct {
     fabric_sensitive node_id checkInNodeID = 1;
     fabric_sensitive int64u monitoredSubject = 2;
+    fabric_sensitive ClientTypeEnum clientType = 4;
     fabric_idx fabricIndex = 254;
   }
 
@@ -1794,6 +1800,7 @@
     int64u monitoredSubject = 1;
     octet_string<16> key = 2;
     optional octet_string<16> verificationKey = 3;
+    ClientTypeEnum clientType = 4;
   }
 
   response struct RegisterClientResponse = 1 {
diff --git a/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.matter b/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.matter
index 9d26024..79f2623 100644
--- a/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.matter
+++ b/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.matter
@@ -1413,6 +1413,11 @@
 cluster IcdManagement = 70 {
   revision 2;
 
+  enum ClientTypeEnum : enum8 {
+    kPermanent = 0;
+    kEphemeral = 1;
+  }
+
   enum OperatingModeEnum : enum8 {
     kSIT = 0;
     kLIT = 1;
@@ -1447,6 +1452,7 @@
   fabric_scoped struct MonitoringRegistrationStruct {
     fabric_sensitive node_id checkInNodeID = 1;
     fabric_sensitive int64u monitoredSubject = 2;
+    fabric_sensitive ClientTypeEnum clientType = 4;
     fabric_idx fabricIndex = 254;
   }
 
@@ -1471,6 +1477,7 @@
     int64u monitoredSubject = 1;
     octet_string<16> key = 2;
     optional octet_string<16> verificationKey = 3;
+    ClientTypeEnum clientType = 4;
   }
 
   response struct RegisterClientResponse = 1 {
diff --git a/examples/lock-app/lock-common/lock-app.matter b/examples/lock-app/lock-common/lock-app.matter
index 5c21291..a484b09 100644
--- a/examples/lock-app/lock-common/lock-app.matter
+++ b/examples/lock-app/lock-common/lock-app.matter
@@ -1756,6 +1756,11 @@
 cluster IcdManagement = 70 {
   revision 2;
 
+  enum ClientTypeEnum : enum8 {
+    kPermanent = 0;
+    kEphemeral = 1;
+  }
+
   enum OperatingModeEnum : enum8 {
     kSIT = 0;
     kLIT = 1;
@@ -1790,6 +1795,7 @@
   fabric_scoped struct MonitoringRegistrationStruct {
     fabric_sensitive node_id checkInNodeID = 1;
     fabric_sensitive int64u monitoredSubject = 2;
+    fabric_sensitive ClientTypeEnum clientType = 4;
     fabric_idx fabricIndex = 254;
   }
 
@@ -1814,6 +1820,7 @@
     int64u monitoredSubject = 1;
     octet_string<16> key = 2;
     optional octet_string<16> verificationKey = 3;
+    ClientTypeEnum clientType = 4;
   }
 
   response struct RegisterClientResponse = 1 {
diff --git a/examples/lock-app/qpg/zap/lock.matter b/examples/lock-app/qpg/zap/lock.matter
index 589eb09..a862831 100644
--- a/examples/lock-app/qpg/zap/lock.matter
+++ b/examples/lock-app/qpg/zap/lock.matter
@@ -1412,6 +1412,11 @@
 cluster IcdManagement = 70 {
   revision 2;
 
+  enum ClientTypeEnum : enum8 {
+    kPermanent = 0;
+    kEphemeral = 1;
+  }
+
   enum OperatingModeEnum : enum8 {
     kSIT = 0;
     kLIT = 1;
@@ -1446,6 +1451,7 @@
   fabric_scoped struct MonitoringRegistrationStruct {
     fabric_sensitive node_id checkInNodeID = 1;
     fabric_sensitive int64u monitoredSubject = 2;
+    fabric_sensitive ClientTypeEnum clientType = 4;
     fabric_idx fabricIndex = 254;
   }
 
@@ -1470,6 +1476,7 @@
     int64u monitoredSubject = 1;
     octet_string<16> key = 2;
     optional octet_string<16> verificationKey = 3;
+    ClientTypeEnum clientType = 4;
   }
 
   response struct RegisterClientResponse = 1 {
diff --git a/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.matter b/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.matter
index ea86a44..9ed425b 100644
--- a/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.matter
+++ b/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.matter
@@ -1732,6 +1732,11 @@
 cluster IcdManagement = 70 {
   revision 2;
 
+  enum ClientTypeEnum : enum8 {
+    kPermanent = 0;
+    kEphemeral = 1;
+  }
+
   enum OperatingModeEnum : enum8 {
     kSIT = 0;
     kLIT = 1;
@@ -1766,6 +1771,7 @@
   fabric_scoped struct MonitoringRegistrationStruct {
     fabric_sensitive node_id checkInNodeID = 1;
     fabric_sensitive int64u monitoredSubject = 2;
+    fabric_sensitive ClientTypeEnum clientType = 4;
     fabric_idx fabricIndex = 254;
   }
 
@@ -1790,6 +1796,7 @@
     int64u monitoredSubject = 1;
     octet_string<16> key = 2;
     optional octet_string<16> verificationKey = 3;
+    ClientTypeEnum clientType = 4;
   }
 
   response struct RegisterClientResponse = 1 {
diff --git a/examples/window-app/common/window-app.matter b/examples/window-app/common/window-app.matter
index 1a5a56c..f39cb71 100644
--- a/examples/window-app/common/window-app.matter
+++ b/examples/window-app/common/window-app.matter
@@ -1830,6 +1830,11 @@
 cluster IcdManagement = 70 {
   revision 2;
 
+  enum ClientTypeEnum : enum8 {
+    kPermanent = 0;
+    kEphemeral = 1;
+  }
+
   enum OperatingModeEnum : enum8 {
     kSIT = 0;
     kLIT = 1;
@@ -1864,6 +1869,7 @@
   fabric_scoped struct MonitoringRegistrationStruct {
     fabric_sensitive node_id checkInNodeID = 1;
     fabric_sensitive int64u monitoredSubject = 2;
+    fabric_sensitive ClientTypeEnum clientType = 4;
     fabric_idx fabricIndex = 254;
   }
 
@@ -1888,6 +1894,7 @@
     int64u monitoredSubject = 1;
     octet_string<16> key = 2;
     optional octet_string<16> verificationKey = 3;
+    ClientTypeEnum clientType = 4;
   }
 
   response struct RegisterClientResponse = 1 {
diff --git a/src/app/clusters/icd-management-server/icd-management-server.cpp b/src/app/clusters/icd-management-server/icd-management-server.cpp
index f6ab59d..e4ead15 100644
--- a/src/app/clusters/icd-management-server/icd-management-server.cpp
+++ b/src/app/clusters/icd-management-server/icd-management-server.cpp
@@ -202,6 +202,7 @@
 
                 Structs::MonitoringRegistrationStruct::Type s{ .checkInNodeID    = e.checkInNodeID,
                                                                .monitoredSubject = e.monitoredSubject,
+                                                               .clientType       = e.clientType,
                                                                .fabricIndex      = e.fabricIndex };
                 ReturnErrorOnFailure(subEncoder.Encode(s));
             }
@@ -252,10 +253,14 @@
     FabricIndex fabricIndex            = commandObj->GetAccessingFabricIndex();
     NodeId nodeId                      = commandData.checkInNodeID;
     uint64_t monitoredSubject          = commandData.monitoredSubject;
+    ClientTypeEnum clientType          = commandData.clientType;
     ByteSpan key                       = commandData.key;
     Optional<ByteSpan> verificationKey = commandData.verificationKey;
     bool isClientAdmin                 = false;
 
+    // Check if ClientType is valid
+    VerifyOrReturnError(clientType != ClientTypeEnum::kUnknownEnumValue, InteractionModel::Status::ConstraintError);
+
     // Check if client is admin
     VerifyOrReturnError(CHIP_NO_ERROR == CheckAdmin(commandObj, commandPath, isClientAdmin), InteractionModel::Status::Failure);
 
@@ -291,6 +296,8 @@
     // Save
     entry.checkInNodeID    = nodeId;
     entry.monitoredSubject = monitoredSubject;
+    entry.clientType       = clientType;
+
     if (entry.keyHandleValid)
     {
         entry.DeleteKey();
diff --git a/src/app/clusters/icd-management-server/icd-management-server.h b/src/app/clusters/icd-management-server/icd-management-server.h
index 5c6b838..38fc1b7 100644
--- a/src/app/clusters/icd-management-server/icd-management-server.h
+++ b/src/app/clusters/icd-management-server/icd-management-server.h
@@ -34,8 +34,6 @@
 #include <lib/core/CHIPPersistentStorageDelegate.h>
 #endif // CHIP_CONFIG_ENABLE_ICD_CIP
 
-using chip::Protocols::InteractionModel::Status;
-
 namespace chip {
 namespace Crypto {
 using SymmetricKeystore = SessionKeystore;
diff --git a/src/app/icd/client/DefaultICDClientStorage.cpp b/src/app/icd/client/DefaultICDClientStorage.cpp
index 73e7b5f..7582e8f 100644
--- a/src/app/icd/client/DefaultICDClientStorage.cpp
+++ b/src/app/icd/client/DefaultICDClientStorage.cpp
@@ -274,6 +274,10 @@
         memcpy(clientInfo.hmac_key_handle.AsMutable<Crypto::Symmetric128BitsKeyByteArray>(), hmacBuf.data(),
                sizeof(Crypto::Symmetric128BitsKeyByteArray));
 
+        // ClientType
+        ReturnErrorOnFailure(reader.Next(TLV::ContextTag(ClientInfoTag::kClientType)));
+        ReturnErrorOnFailure(reader.Get(clientInfo.client_type));
+
         ReturnErrorOnFailure(reader.ExitContainer(ICDClientInfoType));
         clientInfoVector.push_back(clientInfo);
     }
@@ -327,6 +331,7 @@
         ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kAesKeyHandle), aesBuf));
         ByteSpan hmacBuf(clientInfo.hmac_key_handle.As<Crypto::Symmetric128BitsKeyByteArray>());
         ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kHmacKeyHandle), hmacBuf));
+        ReturnErrorOnFailure(writer.Put(TLV::ContextTag(ClientInfoTag::kClientType), clientInfo.client_type));
         ReturnErrorOnFailure(writer.EndContainer(ICDClientInfoContainerType));
     }
     return writer.EndContainer(arrayType);
diff --git a/src/app/icd/client/DefaultICDClientStorage.h b/src/app/icd/client/DefaultICDClientStorage.h
index c2a95fd..c3c4560 100644
--- a/src/app/icd/client/DefaultICDClientStorage.h
+++ b/src/app/icd/client/DefaultICDClientStorage.h
@@ -130,6 +130,7 @@
         kMonitoredSubject = 5,
         kAesKeyHandle     = 6,
         kHmacKeyHandle    = 7,
+        kClientType       = 8,
     };
 
     enum class CounterTag : uint8_t
@@ -156,10 +157,10 @@
     static constexpr size_t MaxICDClientInfoSize()
     {
         // All the fields added together
-        return TLV::EstimateStructOverhead(sizeof(NodeId), sizeof(FabricIndex), sizeof(uint32_t) /*start_icd_counter*/,
-                                           sizeof(uint32_t) /*offset*/, sizeof(uint64_t) /*monitored_subject*/,
-                                           sizeof(Crypto::Symmetric128BitsKeyByteArray) /*aes_key_handle*/,
-                                           sizeof(Crypto::Symmetric128BitsKeyByteArray) /*hmac_key_handle*/);
+        return TLV::EstimateStructOverhead(
+            sizeof(NodeId), sizeof(FabricIndex), sizeof(uint32_t) /*start_icd_counter*/, sizeof(uint32_t) /*offset*/,
+            sizeof(uint64_t) /*monitored_subject*/, sizeof(Crypto::Symmetric128BitsKeyByteArray) /*aes_key_handle*/,
+            sizeof(Crypto::Symmetric128BitsKeyByteArray) /*hmac_key_handle*/, sizeof(uint8_t) /*client_type*/);
     }
 
     static constexpr size_t MaxICDCounterSize()
diff --git a/src/app/icd/client/ICDClientInfo.h b/src/app/icd/client/ICDClientInfo.h
index 5a20b19..45aabf2 100644
--- a/src/app/icd/client/ICDClientInfo.h
+++ b/src/app/icd/client/ICDClientInfo.h
@@ -19,6 +19,7 @@
 
 #include <crypto/CHIPCryptoPAL.h>
 #include <lib/core/CHIPConfig.h>
+#include <lib/core/ClusterEnums.h>
 #include <lib/core/DataModelTypes.h>
 #include <lib/core/ScopedNodeId.h>
 #include <lib/support/CodeUtils.h>
@@ -30,11 +31,12 @@
 struct ICDClientInfo
 {
     ScopedNodeId peer_node;
-    uint32_t start_icd_counter               = 0;
-    uint32_t offset                          = 0;
-    uint64_t monitored_subject               = static_cast<uint64_t>(0);
-    Crypto::Aes128KeyHandle aes_key_handle   = Crypto::Aes128KeyHandle();
-    Crypto::Hmac128KeyHandle hmac_key_handle = Crypto::Hmac128KeyHandle();
+    uint32_t start_icd_counter                          = 0;
+    uint32_t offset                                     = 0;
+    Clusters::IcdManagement::ClientTypeEnum client_type = Clusters::IcdManagement::ClientTypeEnum::kPermanent;
+    uint64_t monitored_subject                          = static_cast<uint64_t>(0);
+    Crypto::Aes128KeyHandle aes_key_handle              = Crypto::Aes128KeyHandle();
+    Crypto::Hmac128KeyHandle hmac_key_handle            = Crypto::Hmac128KeyHandle();
 
     ICDClientInfo() {}
     ICDClientInfo(const ICDClientInfo & other) { *this = other; }
@@ -44,6 +46,7 @@
         peer_node         = other.peer_node;
         start_icd_counter = other.start_icd_counter;
         offset            = other.offset;
+        client_type       = other.client_type;
         monitored_subject = other.monitored_subject;
         ByteSpan aes_buf(other.aes_key_handle.As<Crypto::Symmetric128BitsKeyByteArray>());
         memcpy(aes_key_handle.AsMutable<Crypto::Symmetric128BitsKeyByteArray>(), aes_buf.data(),
diff --git a/src/app/icd/server/BUILD.gn b/src/app/icd/server/BUILD.gn
index c100cc7..89c39c2 100644
--- a/src/app/icd/server/BUILD.gn
+++ b/src/app/icd/server/BUILD.gn
@@ -83,6 +83,7 @@
     "${chip_root}/src/app:subscription-info-provider",
     "${chip_root}/src/app:test-event-trigger",
     "${chip_root}/src/credentials:credentials",
+    "${chip_root}/src/lib/address_resolve:address_resolve",
     "${chip_root}/src/messaging",
   ]
 
diff --git a/src/app/icd/server/ICDCheckInSender.h b/src/app/icd/server/ICDCheckInSender.h
index b681bec..ea56266 100644
--- a/src/app/icd/server/ICDCheckInSender.h
+++ b/src/app/icd/server/ICDCheckInSender.h
@@ -32,7 +32,7 @@
 {
 public:
     ICDCheckInSender(Messaging::ExchangeManager * exchangeManager);
-    ~ICDCheckInSender(){};
+    ~ICDCheckInSender() = default;
 
     CHIP_ERROR RequestResolve(ICDMonitoringEntry & entry, FabricTable * fabricTable, uint32_t counter);
 
diff --git a/src/app/icd/server/ICDManager.cpp b/src/app/icd/server/ICDManager.cpp
index 2b4ccb2..ee55b0b 100644
--- a/src/app/icd/server/ICDManager.cpp
+++ b/src/app/icd/server/ICDManager.cpp
@@ -21,6 +21,7 @@
 #include <app/icd/server/ICDConfigurationData.h>
 #include <app/icd/server/ICDManager.h>
 #include <app/icd/server/ICDServerConfig.h>
+#include <lib/core/ClusterEnums.h>
 #include <lib/support/CodeUtils.h>
 #include <lib/support/logging/CHIPLogging.h>
 #include <platform/ConnectivityManager.h>
@@ -187,6 +188,13 @@
                 continue;
             }
 
+            if (entry.clientType == ClientTypeEnum::kEphemeral)
+            {
+                // If the registered client is ephemeral, do not send a Check-In message
+                // continue to next entry
+                continue;
+            }
+
             if (!ShouldCheckInMsgsBeSentAtActiveModeFunction(entry.fabricIndex, entry.monitoredSubject))
             {
                 continue;
@@ -248,6 +256,12 @@
                 continue;
             }
 
+            if (entry.clientType == ClientTypeEnum::kEphemeral)
+            {
+                // If the registered client is ephemeral, no Check-In message would be sent to this client
+                continue;
+            }
+
             // At least one registration would require a Check-In message
             VerifyOrReturnValue(!shouldCheckInMsgsBeSentFunction(entry.fabricIndex, entry.monitoredSubject), true);
         }
diff --git a/src/app/icd/server/ICDManager.h b/src/app/icd/server/ICDManager.h
index bf9474b..4b996e6 100644
--- a/src/app/icd/server/ICDManager.h
+++ b/src/app/icd/server/ICDManager.h
@@ -18,7 +18,6 @@
 
 #include <app/icd/server/ICDServerConfig.h>
 
-#include <app-common/zap-generated/cluster-enums.h>
 #include <app/AppConfig.h>
 #include <app/SubscriptionsInfoProvider.h>
 #include <app/TestEventTriggerDelegate.h>
diff --git a/src/app/icd/server/ICDMonitoringTable.cpp b/src/app/icd/server/ICDMonitoringTable.cpp
index 57e6fa2..8148a7f 100644
--- a/src/app/icd/server/ICDMonitoringTable.cpp
+++ b/src/app/icd/server/ICDMonitoringTable.cpp
@@ -27,6 +27,7 @@
     kMonitoredSubject = 2,
     kAesKeyHandle     = 3,
     kHmacKeyHandle    = 4,
+    kClientType       = 5,
 };
 
 CHIP_ERROR ICDMonitoringEntry::UpdateKey(StorageKeyName & skey)
@@ -49,6 +50,8 @@
     ByteSpan hmacKeybuf(hmacKeyHandle.As<Crypto::Symmetric128BitsKeyByteArray>());
     ReturnErrorOnFailure(writer.Put(TLV::ContextTag(Fields::kHmacKeyHandle), hmacKeybuf));
 
+    ReturnErrorOnFailure(writer.Put(TLV::ContextTag(Fields::kClientType), clientType));
+
     ReturnErrorOnFailure(writer.EndContainer(outer));
     return CHIP_NO_ERROR;
 }
@@ -106,6 +109,9 @@
                        sizeof(Crypto::Symmetric128BitsKeyByteArray));
             }
             break;
+            case to_underlying(Fields::kClientType):
+                ReturnErrorOnFailure(reader.Get(clientType));
+                break;
             default:
                 break;
             }
@@ -122,6 +128,7 @@
     this->checkInNodeID    = kUndefinedNodeId;
     this->monitoredSubject = kUndefinedNodeId;
     this->keyHandleValid   = false;
+    this->clientType       = app::Clusters::IcdManagement::ClientTypeEnum::kPermanent;
 }
 
 CHIP_ERROR ICDMonitoringEntry::SetKey(ByteSpan keyData)
@@ -210,6 +217,7 @@
     fabricIndex       = icdMonitoringEntry.fabricIndex;
     checkInNodeID     = icdMonitoringEntry.checkInNodeID;
     monitoredSubject  = icdMonitoringEntry.monitoredSubject;
+    clientType        = icdMonitoringEntry.clientType;
     index             = icdMonitoringEntry.index;
     keyHandleValid    = icdMonitoringEntry.keyHandleValid;
     symmetricKeystore = icdMonitoringEntry.symmetricKeystore;
@@ -257,6 +265,7 @@
     ICDMonitoringEntry e(this->mFabric, index);
     e.checkInNodeID    = entry.checkInNodeID;
     e.monitoredSubject = entry.monitoredSubject;
+    e.clientType       = entry.clientType;
     e.index            = index;
 
     memcpy(e.aesKeyHandle.AsMutable<Crypto::Symmetric128BitsKeyByteArray>(),
diff --git a/src/app/icd/server/ICDMonitoringTable.h b/src/app/icd/server/ICDMonitoringTable.h
index e996d0c..942c56f 100644
--- a/src/app/icd/server/ICDMonitoringTable.h
+++ b/src/app/icd/server/ICDMonitoringTable.h
@@ -20,6 +20,7 @@
 #include <crypto/SessionKeystore.h>
 #include <lib/core/CHIPConfig.h>
 #include <lib/core/CHIPPersistentStorageDelegate.h>
+#include <lib/core/ClusterEnums.h>
 #include <lib/core/DataModelTypes.h>
 #include <lib/support/CodeUtils.h>
 #include <lib/support/PersistentData.h>
@@ -101,14 +102,15 @@
      */
     bool IsKeyEquivalent(ByteSpan keyData);
 
-    chip::FabricIndex fabricIndex                 = kUndefinedFabricIndex;
-    chip::NodeId checkInNodeID                    = kUndefinedNodeId;
-    uint64_t monitoredSubject                     = static_cast<uint64_t>(0);
-    Crypto::Aes128KeyHandle aesKeyHandle          = Crypto::Aes128KeyHandle();
-    Crypto::Hmac128KeyHandle hmacKeyHandle        = Crypto::Hmac128KeyHandle();
-    bool keyHandleValid                           = false;
-    uint16_t index                                = 0;
-    Crypto::SymmetricKeystore * symmetricKeystore = nullptr;
+    chip::FabricIndex fabricIndex                           = kUndefinedFabricIndex;
+    chip::NodeId checkInNodeID                              = kUndefinedNodeId;
+    uint64_t monitoredSubject                               = static_cast<uint64_t>(0);
+    app::Clusters::IcdManagement::ClientTypeEnum clientType = app::Clusters::IcdManagement::ClientTypeEnum::kPermanent;
+    Crypto::Aes128KeyHandle aesKeyHandle                    = Crypto::Aes128KeyHandle();
+    Crypto::Hmac128KeyHandle hmacKeyHandle                  = Crypto::Hmac128KeyHandle();
+    bool keyHandleValid                                     = false;
+    uint16_t index                                          = 0;
+    Crypto::SymmetricKeystore * symmetricKeystore           = nullptr;
 };
 
 /**
diff --git a/src/app/icd/server/tests/TestICDManager.cpp b/src/app/icd/server/tests/TestICDManager.cpp
index 45e7816..0b3c1a4 100644
--- a/src/app/icd/server/tests/TestICDManager.cpp
+++ b/src/app/icd/server/tests/TestICDManager.cpp
@@ -25,6 +25,7 @@
 #include <app/icd/server/tests/ICDConfigurationDataTestAccess.h>
 #include <crypto/DefaultSessionKeystore.h>
 #include <gtest/gtest.h>
+#include <lib/address_resolve/AddressResolve.h>
 #include <lib/core/DataModelTypes.h>
 #include <lib/core/NodeId.h>
 #include <lib/support/TestPersistentStorageDelegate.h>
@@ -35,6 +36,7 @@
 using namespace chip;
 using namespace chip::Test;
 using namespace chip::app;
+using namespace chip::AddressResolve;
 using namespace chip::System;
 using namespace chip::System::Clock;
 using namespace chip::System::Clock::Literals;
diff --git a/src/app/icd/server/tests/TestICDMonitoringTable.cpp b/src/app/icd/server/tests/TestICDMonitoringTable.cpp
index ef1e5b3..423bc15 100644
--- a/src/app/icd/server/tests/TestICDMonitoringTable.cpp
+++ b/src/app/icd/server/tests/TestICDMonitoringTable.cpp
@@ -20,10 +20,12 @@
 #include <crypto/DefaultSessionKeystore.h>
 #include <gtest/gtest.h>
 #include <lib/core/CHIPError.h>
+#include <lib/core/ClusterEnums.h>
 #include <lib/support/DefaultStorageKeyAllocator.h>
 #include <lib/support/TestPersistentStorageDelegate.h>
 
 using namespace chip;
+using namespace chip::app::Clusters::IcdManagement;
 
 using TestSessionKeystoreImpl = Crypto::DefaultSessionKeystore;
 
@@ -73,6 +75,7 @@
 
     entry.checkInNodeID    = 34;
     entry.monitoredSubject = 32;
+    entry.clientType       = ClientTypeEnum::kEphemeral;
 
     // Entry should be valid now
     EXPECT_TRUE(entry.IsValid());
@@ -88,6 +91,7 @@
     EXPECT_EQ(entry.fabricIndex, entry2.fabricIndex);
     EXPECT_EQ(entry.checkInNodeID, entry2.checkInNodeID);
     EXPECT_EQ(entry.monitoredSubject, entry2.monitoredSubject);
+    EXPECT_EQ(entry.clientType, entry2.clientType);
 
     EXPECT_TRUE(entry2.IsKeyEquivalent(ByteSpan(kKeyBuffer1a)));
 }
@@ -130,6 +134,7 @@
     ICDMonitoringEntry entry1(&keystore);
     entry1.checkInNodeID    = kClientNodeId11;
     entry1.monitoredSubject = kClientNodeId12;
+    entry1.clientType       = ClientTypeEnum::kPermanent;
     EXPECT_EQ(CHIP_NO_ERROR, entry1.SetKey(ByteSpan(kKeyBuffer1a)));
     EXPECT_EQ(CHIP_NO_ERROR, saving.Set(0, entry1));
 
@@ -137,6 +142,7 @@
     ICDMonitoringEntry entry2(&keystore);
     entry2.checkInNodeID    = kClientNodeId12;
     entry2.monitoredSubject = kClientNodeId11;
+    entry2.clientType       = ClientTypeEnum::kEphemeral;
     EXPECT_EQ(CHIP_NO_ERROR, entry2.SetKey(ByteSpan(kKeyBuffer2a)));
     EXPECT_EQ(CHIP_NO_ERROR, saving.Set(1, entry2));
 
@@ -152,6 +158,7 @@
     EXPECT_EQ(kTestFabricIndex1, entry.fabricIndex);
     EXPECT_EQ(kClientNodeId11, entry.checkInNodeID);
     EXPECT_EQ(kClientNodeId12, entry.monitoredSubject);
+    EXPECT_EQ(ClientTypeEnum::kPermanent, entry.clientType);
     EXPECT_TRUE(entry.IsKeyEquivalent(ByteSpan(kKeyBuffer1a)));
     EXPECT_EQ(memcmp(entry1.hmacKeyHandle.As<Crypto::Symmetric128BitsKeyByteArray>(),
                      entry.hmacKeyHandle.As<Crypto::Symmetric128BitsKeyByteArray>(), sizeof(Crypto::Symmetric128BitsKeyByteArray)),
@@ -162,6 +169,7 @@
     EXPECT_EQ(kTestFabricIndex1, entry.fabricIndex);
     EXPECT_EQ(kClientNodeId12, entry.checkInNodeID);
     EXPECT_EQ(kClientNodeId11, entry.monitoredSubject);
+    EXPECT_EQ(ClientTypeEnum::kEphemeral, entry.clientType);
     EXPECT_TRUE(entry.IsKeyEquivalent(ByteSpan(kKeyBuffer2a)));
     EXPECT_EQ(memcmp(entry2.hmacKeyHandle.As<Crypto::Symmetric128BitsKeyByteArray>(),
                      entry.hmacKeyHandle.As<Crypto::Symmetric128BitsKeyByteArray>(), sizeof(Crypto::Symmetric128BitsKeyByteArray)),
@@ -185,6 +193,7 @@
     EXPECT_EQ(kTestFabricIndex1, entry.fabricIndex);
     EXPECT_EQ(kClientNodeId12, entry.checkInNodeID);
     EXPECT_EQ(kClientNodeId11, entry.monitoredSubject);
+    EXPECT_EQ(ClientTypeEnum::kEphemeral, entry.clientType);
     EXPECT_TRUE(entry.IsKeyEquivalent(ByteSpan(kKeyBuffer2a)));
     EXPECT_EQ(memcmp(entry2.hmacKeyHandle.As<Crypto::Symmetric128BitsKeyByteArray>(),
                      entry.hmacKeyHandle.As<Crypto::Symmetric128BitsKeyByteArray>(), sizeof(Crypto::Symmetric128BitsKeyByteArray)),
@@ -195,6 +204,7 @@
     EXPECT_EQ(kTestFabricIndex1, entry.fabricIndex);
     EXPECT_EQ(kClientNodeId13, entry.checkInNodeID);
     EXPECT_EQ(kClientNodeId11, entry.monitoredSubject);
+    EXPECT_EQ(ClientTypeEnum::kPermanent, entry.clientType);
     EXPECT_TRUE(entry.IsKeyEquivalent(ByteSpan(kKeyBuffer1b)));
     EXPECT_EQ(memcmp(entry4.hmacKeyHandle.As<Crypto::Symmetric128BitsKeyByteArray>(),
                      entry.hmacKeyHandle.As<Crypto::Symmetric128BitsKeyByteArray>(), sizeof(Crypto::Symmetric128BitsKeyByteArray)),
diff --git a/src/app/tests/suites/TestIcdManagementCluster.yaml b/src/app/tests/suites/TestIcdManagementCluster.yaml
index a319683..68e3583 100644
--- a/src/app/tests/suites/TestIcdManagementCluster.yaml
+++ b/src/app/tests/suites/TestIcdManagementCluster.yaml
@@ -195,6 +195,8 @@
                 value: 1001
               - name: "Key"
                 value: "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e"
+              - name: "ClientType"
+                value: ClientTypeEnum.Permanent
       response:
           error: CONSTRAINT_ERROR
 
@@ -208,10 +210,12 @@
                 value: 1001
               - name: "Key"
                 value: "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\xff"
+              - name: "ClientType"
+                value: ClientTypeEnum.Permanent
       response:
           error: CONSTRAINT_ERROR
 
-    - label: "Register 1.1"
+    - label: "Register 1.1 - Invalid ClientType"
       command: "RegisterClient"
       arguments:
           values:
@@ -221,6 +225,23 @@
                 value: 1001
               - name: "Key"
                 value: "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+              - name: "ClientType"
+                value: ClientTypeEnum.UnknownEnumValue
+      response:
+          error: CONSTRAINT_ERROR
+
+    - label: "Register 1.2"
+      command: "RegisterClient"
+      arguments:
+          values:
+              - name: "CheckInNodeID"
+                value: 101
+              - name: "MonitoredSubject"
+                value: 1001
+              - name: "Key"
+                value: "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+              - name: "ClientType"
+                value: ClientTypeEnum.Permanent
       response:
           values:
               - name: "ICDCounter"
@@ -240,6 +261,8 @@
               - name: "Key"
                 value:
                     "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+              - name: "ClientType"
+                value: ClientTypeEnum.Ephemeral
       response:
           values:
               - name: "ICDCounter"
@@ -258,6 +281,8 @@
                 value: 3001
               - name: "Key"
                 value: "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+              - name: "ClientType"
+                value: ClientTypeEnum.Permanent
       response:
           error: RESOURCE_EXHAUSTED
 
@@ -267,8 +292,16 @@
       response:
           value:
               [
-                  { CheckInNodeID: 101, MonitoredSubject: 1001 },
-                  { CheckInNodeID: 201, MonitoredSubject: 2001 },
+                  {
+                      CheckInNodeID: 101,
+                      MonitoredSubject: 1001,
+                      ClientType: ClientTypeEnum.Permanent,
+                  },
+                  {
+                      CheckInNodeID: 201,
+                      MonitoredSubject: 2001,
+                      ClientType: ClientTypeEnum.Ephemeral,
+                  },
               ]
 
     - label: "Register 1.1 (update)"
@@ -281,6 +314,8 @@
                 value: 1002
               - name: "Key"
                 value: "\x01\x11\x21\x31\x41\x51\x61\x71\x81\x91\xa1\xb1\xc1\xd1\xe1\xf1"
+              - name: "ClientType"
+                value: ClientTypeEnum.Ephemeral
       response:
           values:
               - name: "ICDCounter"
@@ -295,8 +330,16 @@
       response:
           value:
               [
-                  { CheckInNodeID: 101, MonitoredSubject: 1002 },
-                  { CheckInNodeID: 201, MonitoredSubject: 2001 },
+                  {
+                      CheckInNodeID: 101,
+                      MonitoredSubject: 1002,
+                      ClientType: ClientTypeEnum.Ephemeral,
+                  },
+                  {
+                      CheckInNodeID: 201,
+                      MonitoredSubject: 2001,
+                      ClientType: ClientTypeEnum.Ephemeral,
+                  },
               ]
 
     - label: "Register 2.2 (wrong verification key)"
@@ -312,6 +355,8 @@
               - name: "VerificationKey"
                 value:
                     "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2f\x2f"
+              - name: "ClientType"
+                value: ClientTypeEnum.Permanent
       response:
           values:
               - name: "ICDCounter"
@@ -326,8 +371,16 @@
       response:
           value:
               [
-                  { CheckInNodeID: 101, MonitoredSubject: 1002 },
-                  { CheckInNodeID: 201, MonitoredSubject: 2002 },
+                  {
+                      CheckInNodeID: 101,
+                      MonitoredSubject: 1002,
+                      ClientType: ClientTypeEnum.Ephemeral,
+                  },
+                  {
+                      CheckInNodeID: 201,
+                      MonitoredSubject: 2002,
+                      ClientType: ClientTypeEnum.Permanent,
+                  },
               ]
 
     - label: "Unregister 1.1 (wrong key)"
diff --git a/src/app/tests/suites/certification/Test_TC_ICDM_3_4.yaml b/src/app/tests/suites/certification/Test_TC_ICDM_3_4.yaml
index 7bbcb72..a4eb232 100644
--- a/src/app/tests/suites/certification/Test_TC_ICDM_3_4.yaml
+++ b/src/app/tests/suites/certification/Test_TC_ICDM_3_4.yaml
@@ -128,6 +128,9 @@
                 value: MonitorSubID1
               - name: "Key"
                 value: Key1
+                # Adding input for the test to pass for now - Full test script needs to be updated
+              - name: "ClientType"
+                value: ClientTypeEnum.Permanent
       response:
           values:
               - name: "ICDCounter"
diff --git a/src/app/zap-templates/zcl/data-model/chip/icd-management-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/icd-management-cluster.xml
index 0269b8f..c1e2805 100644
--- a/src/app/zap-templates/zcl/data-model/chip/icd-management-cluster.xml
+++ b/src/app/zap-templates/zcl/data-model/chip/icd-management-cluster.xml
@@ -39,17 +39,24 @@
         <field name="AppDefinedButton" mask="0x10000"/>
     </bitmap>
 
+    <enum name="ClientTypeEnum" type="enum8">
+        <cluster code="0x0046"/>
+        <item value="0" name="Permanent"/>
+        <item value="1" name="Ephemeral"/>
+    </enum>
+
     <struct name = "MonitoringRegistrationStruct" isFabricScoped="true">
         <cluster code="0x0046"/>
         <item fieldId="1" name="CheckInNodeID" type="node_id" isFabricSensitive="true"/>
         <item fieldId="2" name="MonitoredSubject" type="int64u" isFabricSensitive="true"/>
         <!-- RESERVED = 0x03 -->
+        <item fieldId="4" name="ClientType" type="ClientTypeEnum" isFabricSensitive="true" default="0"/>
     </struct>
 
     <enum name="OperatingModeEnum" type="enum8">
-    <cluster code="0x0046" />
-    <item value="0" name="SIT" />
-    <item value="1" name="LIT" />
+        <cluster code="0x0046" />
+        <item value="0" name="SIT" />
+        <item value="1" name="LIT" />
     </enum>
 
     <cluster>
@@ -113,6 +120,7 @@
             <arg name="MonitoredSubject" type="int64u" optional="false"/>
             <arg name="Key" type="octet_string" length="16" optional="false"/>
             <arg name="VerificationKey" type="octet_string" length="16" optional="true"/>
+            <arg name="ClientType" type="ClientTypeEnum" optional="false"/>
             <access op="invoke" privilege="manage"/>
         </command>
 
diff --git a/src/controller/AutoCommissioner.cpp b/src/controller/AutoCommissioner.cpp
index d6bc9f5..8232292 100644
--- a/src/controller/AutoCommissioner.cpp
+++ b/src/controller/AutoCommissioner.cpp
@@ -91,6 +91,11 @@
         ChipLogError(Controller, "Missing ICD monitored subject!");
         return CHIP_ERROR_INVALID_ARGUMENT;
     }
+    if (!params.GetICDClientType().HasValue())
+    {
+        ChipLogError(Controller, "Missing ICD Client Type!");
+        return CHIP_ERROR_INVALID_ARGUMENT;
+    }
     return CHIP_NO_ERROR;
 }
 
@@ -270,6 +275,7 @@
         mParams.SetICDSymmetricKey(ByteSpan(mICDSymmetricKey));
         mParams.SetICDCheckInNodeId(params.GetICDCheckInNodeId().Value());
         mParams.SetICDMonitoredSubject(params.GetICDMonitoredSubject().Value());
+        mParams.SetICDClientType(params.GetICDClientType().Value());
     }
 
     return CHIP_NO_ERROR;
diff --git a/src/controller/CommissioningDelegate.h b/src/controller/CommissioningDelegate.h
index 99f00f1..7a96939 100644
--- a/src/controller/CommissioningDelegate.h
+++ b/src/controller/CommissioningDelegate.h
@@ -558,6 +558,13 @@
         return *this;
     }
 
+    Optional<app::Clusters::IcdManagement::ClientTypeEnum> GetICDClientType() const { return mICDClientType; }
+    CommissioningParameters & SetICDClientType(app::Clusters::IcdManagement::ClientTypeEnum icdClientType)
+    {
+        mICDClientType = MakeOptional(icdClientType);
+        return *this;
+    }
+
     Optional<uint32_t> GetICDStayActiveDurationMsec() const { return mICDStayActiveDurationMsec; }
     CommissioningParameters & SetICDStayActiveDurationMsec(uint32_t stayActiveDurationMsec)
     {
@@ -632,6 +639,7 @@
     Optional<NodeId> mICDCheckInNodeId;
     Optional<uint64_t> mICDMonitoredSubject;
     Optional<ByteSpan> mICDSymmetricKey;
+    Optional<app::Clusters::IcdManagement::ClientTypeEnum> mICDClientType;
     Optional<uint32_t> mICDStayActiveDurationMsec;
     ICDRegistrationStrategy mICDRegistrationStrategy = ICDRegistrationStrategy::kIgnore;
     bool mCheckForMatchingFabric                     = false;
diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter
index cb858ff..a8567d5 100644
--- a/src/controller/data_model/controller-clusters.matter
+++ b/src/controller/data_model/controller-clusters.matter
@@ -2672,6 +2672,11 @@
 cluster IcdManagement = 70 {
   revision 2;
 
+  enum ClientTypeEnum : enum8 {
+    kPermanent = 0;
+    kEphemeral = 1;
+  }
+
   enum OperatingModeEnum : enum8 {
     kSIT = 0;
     kLIT = 1;
@@ -2706,6 +2711,7 @@
   fabric_scoped struct MonitoringRegistrationStruct {
     fabric_sensitive node_id checkInNodeID = 1;
     fabric_sensitive int64u monitoredSubject = 2;
+    fabric_sensitive ClientTypeEnum clientType = 4;
     fabric_idx fabricIndex = 254;
   }
 
@@ -2730,6 +2736,7 @@
     int64u monitoredSubject = 1;
     octet_string<16> key = 2;
     optional octet_string<16> verificationKey = 3;
+    ClientTypeEnum clientType = 4;
   }
 
   response struct RegisterClientResponse = 1 {
diff --git a/src/controller/java/AndroidDeviceControllerWrapper.cpp b/src/controller/java/AndroidDeviceControllerWrapper.cpp
index 87f5373..af5d220 100644
--- a/src/controller/java/AndroidDeviceControllerWrapper.cpp
+++ b/src/controller/java/AndroidDeviceControllerWrapper.cpp
@@ -526,6 +526,12 @@
     VerifyOrReturnError(err == CHIP_NO_ERROR, err);
     jbyteArray jSymmetricKey = static_cast<jbyteArray>(env->CallObjectMethod(icdRegistrationInfo, getSymmetricKeyMethod));
 
+    jmethodID getClientTypeMethod;
+    err = chip::JniReferences::GetInstance().FindMethod(env, icdRegistrationInfo, "getClientType", "()Ljava/lang/Integer;",
+                                                        &getClientTypeMethod);
+    VerifyOrReturnError(err == CHIP_NO_ERROR, err);
+    jobject jClientType = env->CallObjectMethod(icdRegistrationInfo, getClientTypeMethod);
+
     chip::NodeId checkInNodeId = chip::kUndefinedNodeId;
     if (jCheckInNodeId != nullptr)
     {
@@ -556,6 +562,14 @@
     }
     params.SetICDSymmetricKey(chip::ByteSpan(mICDSymmetricKey));
 
+    chip::app::Clusters::IcdManagement::ClientTypeEnum clientType = chip::app::Clusters::IcdManagement::ClientTypeEnum::kPermanent;
+    if (jClientType != nullptr)
+    {
+        clientType = static_cast<chip::app::Clusters::IcdManagement::ClientTypeEnum>(
+            chip::JniReferences::GetInstance().IntegerToPrimitive(jClientType));
+    }
+    params.SetICDClientType(clientType);
+
     return err;
 }
 
diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java
index 8049151..4b762e1 100644
--- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java
+++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java
@@ -18618,11 +18618,11 @@
       return 0L;
     }
 
-    public void registerClient(RegisterClientResponseCallback callback, Long checkInNodeID, Long monitoredSubject, byte[] key, Optional<byte[]> verificationKey) {
-      registerClient(callback, checkInNodeID, monitoredSubject, key, verificationKey, 0);
+    public void registerClient(RegisterClientResponseCallback callback, Long checkInNodeID, Long monitoredSubject, byte[] key, Optional<byte[]> verificationKey, Integer clientType) {
+      registerClient(callback, checkInNodeID, monitoredSubject, key, verificationKey, clientType, 0);
     }
 
-    public void registerClient(RegisterClientResponseCallback callback, Long checkInNodeID, Long monitoredSubject, byte[] key, Optional<byte[]> verificationKey, int timedInvokeTimeoutMs) {
+    public void registerClient(RegisterClientResponseCallback callback, Long checkInNodeID, Long monitoredSubject, byte[] key, Optional<byte[]> verificationKey, Integer clientType, int timedInvokeTimeoutMs) {
       final long commandId = 0L;
 
       ArrayList<StructElement> elements = new ArrayList<>();
@@ -18642,6 +18642,10 @@
       BaseTLVType verificationKeytlvValue = verificationKey.<BaseTLVType>map((nonOptionalverificationKey) -> new ByteArrayType(nonOptionalverificationKey)).orElse(new EmptyType());
       elements.add(new StructElement(verificationKeyFieldID, verificationKeytlvValue));
 
+      final long clientTypeFieldID = 4L;
+      BaseTLVType clientTypetlvValue = new UIntType(clientType);
+      elements.add(new StructElement(clientTypeFieldID, clientTypetlvValue));
+
       StructType commandArgs = new StructType(elements);
       invoke(new InvokeCallbackImpl(callback) {
           @Override
diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java b/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java
index c22d359..f78eaf9 100644
--- a/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java
+++ b/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java
@@ -3483,18 +3483,22 @@
 public static class IcdManagementClusterMonitoringRegistrationStruct {
   public Long checkInNodeID;
   public Long monitoredSubject;
+  public Integer clientType;
   public Integer fabricIndex;
   private static final long CHECK_IN_NODE_I_D_ID = 1L;
   private static final long MONITORED_SUBJECT_ID = 2L;
+  private static final long CLIENT_TYPE_ID = 4L;
   private static final long FABRIC_INDEX_ID = 254L;
 
   public IcdManagementClusterMonitoringRegistrationStruct(
     Long checkInNodeID,
     Long monitoredSubject,
+    Integer clientType,
     Integer fabricIndex
   ) {
     this.checkInNodeID = checkInNodeID;
     this.monitoredSubject = monitoredSubject;
+    this.clientType = clientType;
     this.fabricIndex = fabricIndex;
   }
 
@@ -3502,6 +3506,7 @@
     ArrayList<StructElement> values = new ArrayList<>();
     values.add(new StructElement(CHECK_IN_NODE_I_D_ID, new UIntType(checkInNodeID)));
     values.add(new StructElement(MONITORED_SUBJECT_ID, new UIntType(monitoredSubject)));
+    values.add(new StructElement(CLIENT_TYPE_ID, new UIntType(clientType)));
     values.add(new StructElement(FABRIC_INDEX_ID, new UIntType(fabricIndex)));
 
     return new StructType(values);
@@ -3513,6 +3518,7 @@
     }
     Long checkInNodeID = null;
     Long monitoredSubject = null;
+    Integer clientType = null;
     Integer fabricIndex = null;
     for (StructElement element: ((StructType)tlvValue).value()) {
       if (element.contextTagNum() == CHECK_IN_NODE_I_D_ID) {
@@ -3525,6 +3531,11 @@
           UIntType castingValue = element.value(UIntType.class);
           monitoredSubject = castingValue.value(Long.class);
         }
+      } else if (element.contextTagNum() == CLIENT_TYPE_ID) {
+        if (element.value(BaseTLVType.class).type() == TLVType.UInt) {
+          UIntType castingValue = element.value(UIntType.class);
+          clientType = castingValue.value(Integer.class);
+        }
       } else if (element.contextTagNum() == FABRIC_INDEX_ID) {
         if (element.value(BaseTLVType.class).type() == TLVType.UInt) {
           UIntType castingValue = element.value(UIntType.class);
@@ -3535,6 +3546,7 @@
     return new IcdManagementClusterMonitoringRegistrationStruct(
       checkInNodeID,
       monitoredSubject,
+      clientType,
       fabricIndex
     );
   }
@@ -3549,6 +3561,9 @@
     output.append("\tmonitoredSubject: ");
     output.append(monitoredSubject);
     output.append("\n");
+    output.append("\tclientType: ");
+    output.append(clientType);
+    output.append("\n");
     output.append("\tfabricIndex: ");
     output.append(fabricIndex);
     output.append("\n");
diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java
index 06f9941..cc2cb93 100644
--- a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java
+++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java
@@ -5859,7 +5859,7 @@
                 }
                 throw new NoSuchFieldError();
             }
-        }public enum RegisterClientCommandField {CheckInNodeID(0),MonitoredSubject(1),Key(2),VerificationKey(3),;
+        }public enum RegisterClientCommandField {CheckInNodeID(0),MonitoredSubject(1),Key(2),VerificationKey(3),ClientType(4),;
                     private final int id;
                     RegisterClientCommandField(int id) {
                         this.id = id;
diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java
index f4830c3..2573b42 100644
--- a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java
+++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java
@@ -23986,6 +23986,9 @@
 
     CommandParameterInfo icdManagementregisterClientverificationKeyCommandParameterInfo = new CommandParameterInfo("verificationKey", Optional.class, byte[].class);
     icdManagementregisterClientCommandParams.put("verificationKey",icdManagementregisterClientverificationKeyCommandParameterInfo);
+
+    CommandParameterInfo icdManagementregisterClientclientTypeCommandParameterInfo = new CommandParameterInfo("clientType", Integer.class, Integer.class);
+    icdManagementregisterClientCommandParams.put("clientType",icdManagementregisterClientclientTypeCommandParameterInfo);
     InteractionInfo icdManagementregisterClientInteractionInfo = new InteractionInfo(
       (cluster, callback, commandArguments) -> {
         ((ChipClusters.IcdManagementCluster) cluster)
@@ -24002,6 +24005,9 @@
            , (Optional<byte[]>)
              commandArguments.get("verificationKey")
 
+           , (Integer)
+             commandArguments.get("clientType")
+
             );
         },
         () -> new DelegatedIcdManagementClusterRegisterClientResponseCallback(),
diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/IcdManagementClusterMonitoringRegistrationStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/IcdManagementClusterMonitoringRegistrationStruct.kt
index 8c8a7dc..fd60e6d 100644
--- a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/IcdManagementClusterMonitoringRegistrationStruct.kt
+++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/IcdManagementClusterMonitoringRegistrationStruct.kt
@@ -25,12 +25,14 @@
 class IcdManagementClusterMonitoringRegistrationStruct(
   val checkInNodeID: ULong,
   val monitoredSubject: ULong,
+  val clientType: UInt,
   val fabricIndex: UInt,
 ) {
   override fun toString(): String = buildString {
     append("IcdManagementClusterMonitoringRegistrationStruct {\n")
     append("\tcheckInNodeID : $checkInNodeID\n")
     append("\tmonitoredSubject : $monitoredSubject\n")
+    append("\tclientType : $clientType\n")
     append("\tfabricIndex : $fabricIndex\n")
     append("}\n")
   }
@@ -40,6 +42,7 @@
       startStructure(tlvTag)
       put(ContextSpecificTag(TAG_CHECK_IN_NODE_I_D), checkInNodeID)
       put(ContextSpecificTag(TAG_MONITORED_SUBJECT), monitoredSubject)
+      put(ContextSpecificTag(TAG_CLIENT_TYPE), clientType)
       put(ContextSpecificTag(TAG_FABRIC_INDEX), fabricIndex)
       endStructure()
     }
@@ -48,6 +51,7 @@
   companion object {
     private const val TAG_CHECK_IN_NODE_I_D = 1
     private const val TAG_MONITORED_SUBJECT = 2
+    private const val TAG_CLIENT_TYPE = 4
     private const val TAG_FABRIC_INDEX = 254
 
     fun fromTlv(
@@ -57,6 +61,7 @@
       tlvReader.enterStructure(tlvTag)
       val checkInNodeID = tlvReader.getULong(ContextSpecificTag(TAG_CHECK_IN_NODE_I_D))
       val monitoredSubject = tlvReader.getULong(ContextSpecificTag(TAG_MONITORED_SUBJECT))
+      val clientType = tlvReader.getUInt(ContextSpecificTag(TAG_CLIENT_TYPE))
       val fabricIndex = tlvReader.getUInt(ContextSpecificTag(TAG_FABRIC_INDEX))
 
       tlvReader.exitContainer()
@@ -64,6 +69,7 @@
       return IcdManagementClusterMonitoringRegistrationStruct(
         checkInNodeID,
         monitoredSubject,
+        clientType,
         fabricIndex,
       )
     }
diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/IcdManagementCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/IcdManagementCluster.kt
index fd77e38..ddc206e 100644
--- a/src/controller/java/generated/java/matter/controller/cluster/clusters/IcdManagementCluster.kt
+++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/IcdManagementCluster.kt
@@ -107,6 +107,7 @@
     monitoredSubject: ULong,
     key: ByteArray,
     verificationKey: ByteArray?,
+    clientType: UByte,
     timedInvokeTimeout: Duration? = null,
   ): RegisterClientResponse {
     val commandId: UInt = 0u
@@ -127,6 +128,9 @@
     verificationKey?.let {
       tlvWriter.put(ContextSpecificTag(TAG_VERIFICATION_KEY_REQ), verificationKey)
     }
+
+    val TAG_CLIENT_TYPE_REQ: Int = 4
+    tlvWriter.put(ContextSpecificTag(TAG_CLIENT_TYPE_REQ), clientType)
     tlvWriter.endStructure()
 
     val request: InvokeRequest =
diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/IcdManagementClusterMonitoringRegistrationStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/IcdManagementClusterMonitoringRegistrationStruct.kt
index f9866aa..fbf95fd 100644
--- a/src/controller/java/generated/java/matter/controller/cluster/structs/IcdManagementClusterMonitoringRegistrationStruct.kt
+++ b/src/controller/java/generated/java/matter/controller/cluster/structs/IcdManagementClusterMonitoringRegistrationStruct.kt
@@ -25,12 +25,14 @@
 class IcdManagementClusterMonitoringRegistrationStruct(
   val checkInNodeID: ULong,
   val monitoredSubject: ULong,
+  val clientType: UByte,
   val fabricIndex: UByte,
 ) {
   override fun toString(): String = buildString {
     append("IcdManagementClusterMonitoringRegistrationStruct {\n")
     append("\tcheckInNodeID : $checkInNodeID\n")
     append("\tmonitoredSubject : $monitoredSubject\n")
+    append("\tclientType : $clientType\n")
     append("\tfabricIndex : $fabricIndex\n")
     append("}\n")
   }
@@ -40,6 +42,7 @@
       startStructure(tlvTag)
       put(ContextSpecificTag(TAG_CHECK_IN_NODE_I_D), checkInNodeID)
       put(ContextSpecificTag(TAG_MONITORED_SUBJECT), monitoredSubject)
+      put(ContextSpecificTag(TAG_CLIENT_TYPE), clientType)
       put(ContextSpecificTag(TAG_FABRIC_INDEX), fabricIndex)
       endStructure()
     }
@@ -48,6 +51,7 @@
   companion object {
     private const val TAG_CHECK_IN_NODE_I_D = 1
     private const val TAG_MONITORED_SUBJECT = 2
+    private const val TAG_CLIENT_TYPE = 4
     private const val TAG_FABRIC_INDEX = 254
 
     fun fromTlv(
@@ -57,6 +61,7 @@
       tlvReader.enterStructure(tlvTag)
       val checkInNodeID = tlvReader.getULong(ContextSpecificTag(TAG_CHECK_IN_NODE_I_D))
       val monitoredSubject = tlvReader.getULong(ContextSpecificTag(TAG_MONITORED_SUBJECT))
+      val clientType = tlvReader.getUByte(ContextSpecificTag(TAG_CLIENT_TYPE))
       val fabricIndex = tlvReader.getUByte(ContextSpecificTag(TAG_FABRIC_INDEX))
 
       tlvReader.exitContainer()
@@ -64,6 +69,7 @@
       return IcdManagementClusterMonitoringRegistrationStruct(
         checkInNodeID,
         monitoredSubject,
+        clientType,
         fabricIndex,
       )
     }
diff --git a/src/controller/java/src/chip/devicecontroller/ICDRegistrationInfo.java b/src/controller/java/src/chip/devicecontroller/ICDRegistrationInfo.java
index be978fa..417d147 100644
--- a/src/controller/java/src/chip/devicecontroller/ICDRegistrationInfo.java
+++ b/src/controller/java/src/chip/devicecontroller/ICDRegistrationInfo.java
@@ -24,11 +24,13 @@
   @Nullable private final Long checkInNodeId;
   @Nullable private final Long monitoredSubject;
   @Nullable private final byte[] symmetricKey;
+  @Nullable private final Integer clientType;
 
   private ICDRegistrationInfo(Builder builder) {
     this.checkInNodeId = builder.checkInNodeId;
     this.monitoredSubject = builder.monitoredSubject;
     this.symmetricKey = builder.symmetricKey;
+    this.clientType = builder.clientType;
   }
 
   /** Returns the check in node ID. */
@@ -46,6 +48,10 @@
     return symmetricKey;
   }
 
+  public Integer getClientType() {
+    return clientType;
+  }
+
   public static Builder newBuilder() {
     return new Builder();
   }
@@ -55,6 +61,7 @@
     @Nullable private Long checkInNodeId = null;
     @Nullable private Long monitoredSubject = null;
     @Nullable private byte[] symmetricKey = null;
+    @Nullable private Integer clientType = null;
 
     private Builder() {}
 
@@ -81,6 +88,11 @@
       return this;
     }
 
+    public Builder setClientType(Integer clientType) {
+      this.clientType = clientType;
+      return this;
+    }
+
     public ICDRegistrationInfo build() {
       return new ICDRegistrationInfo(this);
     }
diff --git a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp
index 7cdabec..4cebe9e 100644
--- a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp
+++ b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp
@@ -12306,6 +12306,13 @@
                 chip::JniReferences::GetInstance().CreateBoxedObject<jlong>(
                     newElement_0_monitoredSubjectClassName.c_str(), newElement_0_monitoredSubjectCtorSignature.c_str(),
                     jninewElement_0_monitoredSubject, newElement_0_monitoredSubject);
+                jobject newElement_0_clientType;
+                std::string newElement_0_clientTypeClassName     = "java/lang/Integer";
+                std::string newElement_0_clientTypeCtorSignature = "(I)V";
+                jint jninewElement_0_clientType                  = static_cast<jint>(entry_0.clientType);
+                chip::JniReferences::GetInstance().CreateBoxedObject<jint>(newElement_0_clientTypeClassName.c_str(),
+                                                                           newElement_0_clientTypeCtorSignature.c_str(),
+                                                                           jninewElement_0_clientType, newElement_0_clientType);
                 jobject newElement_0_fabricIndex;
                 std::string newElement_0_fabricIndexClassName     = "java/lang/Integer";
                 std::string newElement_0_fabricIndexCtorSignature = "(I)V";
@@ -12325,9 +12332,10 @@
                 }
 
                 jmethodID monitoringRegistrationStructStructCtor_1;
-                err = chip::JniReferences::GetInstance().FindMethod(env, monitoringRegistrationStructStructClass_1, "<init>",
-                                                                    "(Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Integer;)V",
-                                                                    &monitoringRegistrationStructStructCtor_1);
+                err = chip::JniReferences::GetInstance().FindMethod(
+                    env, monitoringRegistrationStructStructClass_1, "<init>",
+                    "(Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Integer;Ljava/lang/Integer;)V",
+                    &monitoringRegistrationStructStructCtor_1);
                 if (err != CHIP_NO_ERROR || monitoringRegistrationStructStructCtor_1 == nullptr)
                 {
                     ChipLogError(Zcl, "Could not find ChipStructs$IcdManagementClusterMonitoringRegistrationStruct constructor");
@@ -12335,7 +12343,8 @@
                 }
 
                 newElement_0 = env->NewObject(monitoringRegistrationStructStructClass_1, monitoringRegistrationStructStructCtor_1,
-                                              newElement_0_checkInNodeID, newElement_0_monitoredSubject, newElement_0_fabricIndex);
+                                              newElement_0_checkInNodeID, newElement_0_monitoredSubject, newElement_0_clientType,
+                                              newElement_0_fabricIndex);
                 chip::JniReferences::GetInstance().AddToList(value, newElement_0);
             }
             return value;
diff --git a/src/controller/python/ChipDeviceController-ScriptDevicePairingDelegate.cpp b/src/controller/python/ChipDeviceController-ScriptDevicePairingDelegate.cpp
index c979e0d..c04481a 100644
--- a/src/controller/python/ChipDeviceController-ScriptDevicePairingDelegate.cpp
+++ b/src/controller/python/ChipDeviceController-ScriptDevicePairingDelegate.cpp
@@ -191,6 +191,7 @@
     clientInfo.peer_node         = nodeId;
     clientInfo.monitored_subject = sCommissioningParameters.GetICDMonitoredSubject().Value();
     clientInfo.start_icd_counter = icdCounter;
+    clientInfo.client_type       = sCommissioningParameters.GetICDClientType().Value();
 
     CHIP_ERROR err = sICDClientStorage.SetKey(clientInfo, ByteSpan(sICDSymmetricKey));
     if (err == CHIP_NO_ERROR)
diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py
index 773fe34..37ead8e 100644
--- a/src/controller/python/chip/clusters/CHIPClusters.py
+++ b/src/controller/python/chip/clusters/CHIPClusters.py
@@ -4064,6 +4064,7 @@
                     "monitoredSubject": "int",
                     "key": "bytes",
                     "verificationKey": "bytes",
+                    "clientType": "int",
                 },
             },
             0x00000002: {
diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py
index 4391719..4c17fd9 100644
--- a/src/controller/python/chip/clusters/Objects.py
+++ b/src/controller/python/chip/clusters/Objects.py
@@ -14187,6 +14187,15 @@
     clusterRevision: 'uint' = None
 
     class Enums:
+        class ClientTypeEnum(MatterIntEnum):
+            kPermanent = 0x00
+            kEphemeral = 0x01
+            # All received enum values that are not listed above will be mapped
+            # to kUnknownEnumValue. This is a helper enum value that should only
+            # be used by code to process how it handles receiving and unknown
+            # enum value. This specific should never be transmitted.
+            kUnknownEnumValue = 2,
+
         class OperatingModeEnum(MatterIntEnum):
             kSit = 0x00
             kLit = 0x01
@@ -14230,11 +14239,13 @@
                     Fields=[
                         ClusterObjectFieldDescriptor(Label="checkInNodeID", Tag=1, Type=uint),
                         ClusterObjectFieldDescriptor(Label="monitoredSubject", Tag=2, Type=uint),
+                        ClusterObjectFieldDescriptor(Label="clientType", Tag=4, Type=IcdManagement.Enums.ClientTypeEnum),
                         ClusterObjectFieldDescriptor(Label="fabricIndex", Tag=254, Type=uint),
                     ])
 
             checkInNodeID: 'uint' = 0
             monitoredSubject: 'uint' = 0
+            clientType: 'IcdManagement.Enums.ClientTypeEnum' = 0
             fabricIndex: 'uint' = 0
 
     class Commands:
@@ -14253,12 +14264,14 @@
                         ClusterObjectFieldDescriptor(Label="monitoredSubject", Tag=1, Type=uint),
                         ClusterObjectFieldDescriptor(Label="key", Tag=2, Type=bytes),
                         ClusterObjectFieldDescriptor(Label="verificationKey", Tag=3, Type=typing.Optional[bytes]),
+                        ClusterObjectFieldDescriptor(Label="clientType", Tag=4, Type=IcdManagement.Enums.ClientTypeEnum),
                     ])
 
             checkInNodeID: 'uint' = 0
             monitoredSubject: 'uint' = 0
             key: 'bytes' = b""
             verificationKey: 'typing.Optional[bytes]' = None
+            clientType: 'IcdManagement.Enums.ClientTypeEnum' = 0
 
         @dataclass
         class RegisterClientResponse(ClusterCommand):
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm
index 02ce62e..1feae62 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm
@@ -5040,6 +5040,7 @@
                 newElement_0 = [MTRICDManagementClusterMonitoringRegistrationStruct new];
                 newElement_0.checkInNodeID = [NSNumber numberWithUnsignedLongLong:entry_0.checkInNodeID];
                 newElement_0.monitoredSubject = [NSNumber numberWithUnsignedLongLong:entry_0.monitoredSubject];
+                newElement_0.clientType = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.clientType)];
                 newElement_0.fabricIndex = [NSNumber numberWithUnsignedChar:entry_0.fabricIndex];
                 [array_0 addObject:newElement_0];
             }
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h
index a481ad0..1513b8c 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h
@@ -17756,6 +17756,11 @@
     MTRGroupKeyManagementFeatureCacheAndSync MTR_PROVISIONALLY_AVAILABLE = 0x1,
 } MTR_PROVISIONALLY_AVAILABLE;
 
+typedef NS_ENUM(uint8_t, MTRICDManagementClientType) {
+    MTRICDManagementClientTypePermanent MTR_PROVISIONALLY_AVAILABLE = 0x00,
+    MTRICDManagementClientTypeEphemeral MTR_PROVISIONALLY_AVAILABLE = 0x01,
+} MTR_PROVISIONALLY_AVAILABLE;
+
 typedef NS_ENUM(uint8_t, MTRICDManagementOperatingMode) {
     MTRICDManagementOperatingModeSIT MTR_PROVISIONALLY_AVAILABLE = 0x00,
     MTRICDManagementOperatingModeLIT MTR_PROVISIONALLY_AVAILABLE = 0x01,
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h
index 4e74aa8..d95ac77 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h
@@ -3618,6 +3618,8 @@
 @property (nonatomic, copy) NSData * _Nonnull key MTR_PROVISIONALLY_AVAILABLE;
 
 @property (nonatomic, copy) NSData * _Nullable verificationKey MTR_PROVISIONALLY_AVAILABLE;
+
+@property (nonatomic, copy) NSNumber * _Nonnull clientType MTR_PROVISIONALLY_AVAILABLE;
 /**
  * Controls whether the command is a timed command (using Timed Invoke).
  *
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm
index 1dd6753..08b00b6 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm
@@ -9524,6 +9524,8 @@
         _key = [NSData data];
 
         _verificationKey = nil;
+
+        _clientType = @(0);
         _timedInvokeTimeoutMs = nil;
         _serverSideProcessingTimeout = nil;
     }
@@ -9538,6 +9540,7 @@
     other.monitoredSubject = self.monitoredSubject;
     other.key = self.key;
     other.verificationKey = self.verificationKey;
+    other.clientType = self.clientType;
     other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs;
     other.serverSideProcessingTimeout = self.serverSideProcessingTimeout;
 
@@ -9546,7 +9549,7 @@
 
 - (NSString *)description
 {
-    NSString * descriptionString = [NSString stringWithFormat:@"<%@: checkInNodeID:%@; monitoredSubject:%@; key:%@; verificationKey:%@; >", NSStringFromClass([self class]), _checkInNodeID, _monitoredSubject, [_key base64EncodedStringWithOptions:0], [_verificationKey base64EncodedStringWithOptions:0]];
+    NSString * descriptionString = [NSString stringWithFormat:@"<%@: checkInNodeID:%@; monitoredSubject:%@; key:%@; verificationKey:%@; clientType:%@; >", NSStringFromClass([self class]), _checkInNodeID, _monitoredSubject, [_key base64EncodedStringWithOptions:0], [_verificationKey base64EncodedStringWithOptions:0], _clientType];
     return descriptionString;
 }
 
@@ -9573,6 +9576,9 @@
             definedValue_0 = AsByteSpan(self.verificationKey);
         }
     }
+    {
+        encodableStruct.clientType = static_cast<std::remove_reference_t<decltype(encodableStruct.clientType)>>(self.clientType.unsignedCharValue);
+    }
 
     auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0);
     if (buffer.IsNull()) {
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h
index 2d5da93..8ea03ce 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h
@@ -762,6 +762,7 @@
 @interface MTRICDManagementClusterMonitoringRegistrationStruct : NSObject <NSCopying>
 @property (nonatomic, copy) NSNumber * _Nonnull checkInNodeID MTR_PROVISIONALLY_AVAILABLE;
 @property (nonatomic, copy) NSNumber * _Nonnull monitoredSubject MTR_PROVISIONALLY_AVAILABLE;
+@property (nonatomic, copy) NSNumber * _Nonnull clientType MTR_PROVISIONALLY_AVAILABLE;
 @property (nonatomic, copy) NSNumber * _Nonnull fabricIndex MTR_PROVISIONALLY_AVAILABLE;
 @end
 
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm
index 5597899..1ff604e 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm
@@ -2774,6 +2774,8 @@
 
         _monitoredSubject = @(0);
 
+        _clientType = @(0);
+
         _fabricIndex = @(0);
     }
     return self;
@@ -2785,6 +2787,7 @@
 
     other.checkInNodeID = self.checkInNodeID;
     other.monitoredSubject = self.monitoredSubject;
+    other.clientType = self.clientType;
     other.fabricIndex = self.fabricIndex;
 
     return other;
@@ -2792,7 +2795,7 @@
 
 - (NSString *)description
 {
-    NSString * descriptionString = [NSString stringWithFormat:@"<%@: checkInNodeID:%@; monitoredSubject:%@; fabricIndex:%@; >", NSStringFromClass([self class]), _checkInNodeID, _monitoredSubject, _fabricIndex];
+    NSString * descriptionString = [NSString stringWithFormat:@"<%@: checkInNodeID:%@; monitoredSubject:%@; clientType:%@; fabricIndex:%@; >", NSStringFromClass([self class]), _checkInNodeID, _monitoredSubject, _clientType, _fabricIndex];
     return descriptionString;
 }
 
diff --git a/src/lib/support/JniReferences.cpp b/src/lib/support/JniReferences.cpp
index 6b8bb00..021f13c 100644
--- a/src/lib/support/JniReferences.cpp
+++ b/src/lib/support/JniReferences.cpp
@@ -392,6 +392,19 @@
     return env->CallDoubleMethod(boxedDouble, valueMethod);
 }
 
+jshort JniReferences::ShortToPrimitive(jobject boxedShort)
+{
+    JNIEnv * env = GetEnvForCurrentThread();
+    VerifyOrReturnValue(env != nullptr, 0, ChipLogError(Support, "env cannot be nullptr"));
+    jclass boxedTypeCls = nullptr;
+    CHIP_ERROR err      = chip::JniReferences::GetInstance().GetLocalClassRef(env, "java/lang/Short", boxedTypeCls);
+    VerifyOrReturnValue(err == CHIP_NO_ERROR, 0,
+                        ChipLogError(Support, "ShortToPrimitive failed due to %" CHIP_ERROR_FORMAT, err.Format()));
+
+    jmethodID valueMethod = env->GetMethodID(boxedTypeCls, "shortValue", "()S");
+    return env->CallShortMethod(boxedShort, valueMethod);
+}
+
 CHIP_ERROR JniReferences::CallSubscriptionEstablished(jobject javaCallback, long subscriptionId)
 {
     CHIP_ERROR err = CHIP_NO_ERROR;
diff --git a/src/lib/support/JniReferences.h b/src/lib/support/JniReferences.h
index 5cea905..a9a3e29 100644
--- a/src/lib/support/JniReferences.h
+++ b/src/lib/support/JniReferences.h
@@ -177,6 +177,11 @@
      */
     jdouble DoubleToPrimitive(jobject boxedObject);
 
+    /**
+     * Get a primitive jshort from the Java boxed type Short, using shortValue().
+     */
+    jshort ShortToPrimitive(jobject boxedShort);
+
     CHIP_ERROR CreateArrayList(jobject & outList);
 
     CHIP_ERROR AddToList(jobject list, jobject objectToAdd);
diff --git a/src/python_testing/TC_ICDM_3_1.py b/src/python_testing/TC_ICDM_3_1.py
index b504035..f5a37cd 100644
--- a/src/python_testing/TC_ICDM_3_1.py
+++ b/src/python_testing/TC_ICDM_3_1.py
@@ -38,6 +38,7 @@
 cluster = Clusters.Objects.IcdManagement
 commands = cluster.Commands
 monitoredRegistration = cluster.Structs.MonitoringRegistrationStruct
+clientTypeEnum = cluster.Enums.ClientTypeEnum
 
 
 # Step 2 Registration entry
@@ -141,7 +142,7 @@
         self.step(2)
         if self.pics_guard(self.check_pics("ICDM.S.C00.Rsp")):
             try:
-                response = await self._send_single_icdm_command(commands.RegisterClient(checkInNodeID=kStep2CheckInNodeId, monitoredSubject=kStep2MonitoredSubjectStep2, key=kStep2Key))
+                response = await self._send_single_icdm_command(commands.RegisterClient(checkInNodeID=kStep2CheckInNodeId, monitoredSubject=kStep2MonitoredSubjectStep2, key=kStep2Key, clientType=clientTypeEnum.kEphemeral))
             except InteractionModelError as e:
                 asserts.assert_equal(
                     e.status, Status.Success, "Unexpected error returned")
@@ -164,6 +165,8 @@
                 registeredClients[0].checkInNodeID, kStep2CheckInNodeId, "The read attribute does not match the registered value.")
             asserts.assert_equal(
                 registeredClients[0].monitoredSubject, kStep2MonitoredSubjectStep2, "The read attribute does not match the registered value.")
+            asserts.assert_equal(
+                registeredClients[0].clientType, clientTypeEnum.kEphemeral, "The read attribute does not match the registered value.")
 
         self.step(4)
         if self.pics_guard(self.check_pics("ICDM.S.C00.Rsp")):
@@ -174,12 +177,13 @@
                     newClients.append({
                         "checkInNodeID": i + 1,
                         "monitoredSubject": i + 1,
-                        "key": os.urandom(16)
+                        "key": os.urandom(16),
+                        "clientType": clientTypeEnum.kPermanent
                     })
 
             for client in newClients:
                 try:
-                    response = await self._send_single_icdm_command(commands.RegisterClient(checkInNodeID=client["checkInNodeID"], monitoredSubject=client["monitoredSubject"], key=client["key"]))
+                    response = await self._send_single_icdm_command(commands.RegisterClient(checkInNodeID=client["checkInNodeID"], monitoredSubject=client["monitoredSubject"], key=client["key"], clientType=client["clientType"]))
                 except InteractionModelError as e:
                     asserts.assert_equal(
                         e.status, Status.Success, "Unexpected error returned")
@@ -203,11 +207,13 @@
                     client.checkInNodeID, expectedClient["checkInNodeID"], "The read attribute does not match the registered value.")
                 asserts.assert_equal(
                     client.monitoredSubject, expectedClient["monitoredSubject"], "The read attribute does not match the registered value.")
+                asserts.assert_equal(
+                    client.clientType, expectedClient["clientType"], "The read attribute does not match the registered value.")
 
         self.step(6)
         if self.pics_guard(self.check_pics("ICDM.S.C00.Rsp")):
             try:
-                response = await self._send_single_icdm_command(commands.RegisterClient(checkInNodeID=0xFFFF, monitoredSubject=0xFFFF, key=os.urandom(16)))
+                response = await self._send_single_icdm_command(commands.RegisterClient(checkInNodeID=0xFFFF, monitoredSubject=0xFFFF, key=os.urandom(16), clientType=clientTypeEnum.kPermanent))
             except InteractionModelError as e:
                 asserts.assert_equal(
                     e.status, Status.ResourceExhausted, "Unexpected error returned")
diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h
index e53404d..7e52fd0 100644
--- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h
+++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h
@@ -1328,6 +1328,18 @@
     }
 }
 
+static auto __attribute__((unused)) EnsureKnownEnumValue(IcdManagement::ClientTypeEnum val)
+{
+    using EnumType = IcdManagement::ClientTypeEnum;
+    switch (val)
+    {
+    case EnumType::kPermanent:
+    case EnumType::kEphemeral:
+        return val;
+    default:
+        return EnumType::kUnknownEnumValue;
+    }
+}
 static auto __attribute__((unused)) EnsureKnownEnumValue(IcdManagement::OperatingModeEnum val)
 {
     using EnumType = IcdManagement::OperatingModeEnum;
diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h
index 27601f4..a7c4338 100644
--- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h
+++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h
@@ -1601,6 +1601,18 @@
 
 namespace IcdManagement {
 
+// Enum for ClientTypeEnum
+enum class ClientTypeEnum : uint8_t
+{
+    kPermanent = 0x00,
+    kEphemeral = 0x01,
+    // All received enum values that are not listed above will be mapped
+    // to kUnknownEnumValue. This is a helper enum value that should only
+    // be used by code to process how it handles receiving and unknown
+    // enum value. This specific should never be transmitted.
+    kUnknownEnumValue = 2,
+};
+
 // Enum for OperatingModeEnum
 enum class OperatingModeEnum : uint8_t
 {
diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp
index 2899097..54bcec3 100644
--- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp
+++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp
@@ -9622,6 +9622,10 @@
     {
         encoder.Encode(to_underlying(Fields::kMonitoredSubject), monitoredSubject);
     }
+    if (includeSensitive)
+    {
+        encoder.Encode(to_underlying(Fields::kClientType), clientType);
+    }
     if (aAccessingFabricIndex.HasValue())
     {
         encoder.Encode(to_underlying(Fields::kFabricIndex), fabricIndex);
@@ -9652,6 +9656,10 @@
         {
             err = DataModel::Decode(reader, monitoredSubject);
         }
+        else if (__context_tag == to_underlying(Fields::kClientType))
+        {
+            err = DataModel::Decode(reader, clientType);
+        }
         else if (__context_tag == to_underlying(Fields::kFabricIndex))
         {
             err = DataModel::Decode(reader, fabricIndex);
@@ -9676,6 +9684,7 @@
     encoder.Encode(to_underlying(Fields::kMonitoredSubject), monitoredSubject);
     encoder.Encode(to_underlying(Fields::kKey), key);
     encoder.Encode(to_underlying(Fields::kVerificationKey), verificationKey);
+    encoder.Encode(to_underlying(Fields::kClientType), clientType);
     return encoder.Finalize();
 }
 
@@ -9709,6 +9718,10 @@
         {
             err = DataModel::Decode(reader, verificationKey);
         }
+        else if (__context_tag == to_underlying(Fields::kClientType))
+        {
+            err = DataModel::Decode(reader, clientType);
+        }
         else
         {
         }
diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h
index d396989..84f19b1 100644
--- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h
+++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h
@@ -13130,6 +13130,7 @@
 {
     kCheckInNodeID    = 1,
     kMonitoredSubject = 2,
+    kClientType       = 4,
     kFabricIndex      = 254,
 };
 
@@ -13138,6 +13139,7 @@
 public:
     chip::NodeId checkInNodeID    = static_cast<chip::NodeId>(0);
     uint64_t monitoredSubject     = static_cast<uint64_t>(0);
+    ClientTypeEnum clientType     = static_cast<ClientTypeEnum>(0);
     chip::FabricIndex fabricIndex = static_cast<chip::FabricIndex>(0);
 
     CHIP_ERROR Decode(TLV::TLVReader & reader);
@@ -13198,6 +13200,7 @@
     kMonitoredSubject = 1,
     kKey              = 2,
     kVerificationKey  = 3,
+    kClientType       = 4,
 };
 
 struct Type
@@ -13211,6 +13214,7 @@
     uint64_t monitoredSubject  = static_cast<uint64_t>(0);
     chip::ByteSpan key;
     Optional<chip::ByteSpan> verificationKey;
+    ClientTypeEnum clientType = static_cast<ClientTypeEnum>(0);
 
     CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const;
 
@@ -13229,6 +13233,7 @@
     uint64_t monitoredSubject  = static_cast<uint64_t>(0);
     chip::ByteSpan key;
     Optional<chip::ByteSpan> verificationKey;
+    ClientTypeEnum clientType = static_cast<ClientTypeEnum>(0);
     CHIP_ERROR Decode(TLV::TLVReader & reader);
 };
 }; // namespace RegisterClient
diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h
index a9658c4..2cdd59a 100644
--- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h
+++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h
@@ -4242,6 +4242,7 @@
         AddArgument("MonitoredSubject", 0, UINT64_MAX, &mRequest.monitoredSubject);
         AddArgument("Key", &mRequest.key);
         AddArgument("VerificationKey", &mRequest.verificationKey);
+        AddArgument("ClientType", 0, UINT8_MAX, &mRequest.clientType);
         ClusterCommand::AddArguments();
     }
 
diff --git a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp
index 6c7da78..6a73b61 100644
--- a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp
+++ b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp
@@ -2066,6 +2066,8 @@
                                                                   value.isMember("checkInNodeID")));
     ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("MonitoringRegistrationStruct.monitoredSubject",
                                                                   "monitoredSubject", value.isMember("monitoredSubject")));
+    ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("MonitoringRegistrationStruct.clientType", "clientType",
+                                                                  value.isMember("clientType")));
 
     char labelWithMember[kMaxLabelLength];
     snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "checkInNodeID");
@@ -2076,6 +2078,10 @@
     ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.monitoredSubject, value["monitoredSubject"]));
     valueCopy.removeMember("monitoredSubject");
 
+    snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "clientType");
+    ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.clientType, value["clientType"]));
+    valueCopy.removeMember("clientType");
+
     if (value.isMember("fabricIndex"))
     {
         snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "fabricIndex");
@@ -2090,6 +2096,7 @@
 {
     ComplexArgumentParser::Finalize(request.checkInNodeID);
     ComplexArgumentParser::Finalize(request.monitoredSubject);
+    ComplexArgumentParser::Finalize(request.clientType);
     ComplexArgumentParser::Finalize(request.fabricIndex);
 }
 
diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp
index 1f8be3d..a9d3f94 100644
--- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp
+++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp
@@ -1879,6 +1879,14 @@
         }
     }
     {
+        CHIP_ERROR err = LogValue("ClientType", indent + 1, value.clientType);
+        if (err != CHIP_NO_ERROR)
+        {
+            DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'ClientType'");
+            return err;
+        }
+    }
+    {
         CHIP_ERROR err = LogValue("FabricIndex", indent + 1, value.fabricIndex);
         if (err != CHIP_NO_ERROR)
         {
diff --git a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h
index 2bea6e6..dfac8e4 100644
--- a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h
+++ b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h
@@ -47525,6 +47525,9 @@
 #if MTR_ENABLE_PROVISIONAL
         AddArgument("VerificationKey", &mRequest.verificationKey);
 #endif // MTR_ENABLE_PROVISIONAL
+#if MTR_ENABLE_PROVISIONAL
+        AddArgument("ClientType", 0, UINT8_MAX, &mRequest.clientType);
+#endif // MTR_ENABLE_PROVISIONAL
         ClusterCommand::AddArguments();
     }
 
@@ -47555,6 +47558,9 @@
             params.verificationKey = nil;
         }
 #endif // MTR_ENABLE_PROVISIONAL
+#if MTR_ENABLE_PROVISIONAL
+        params.clientType = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.clientType)];
+#endif // MTR_ENABLE_PROVISIONAL
         uint16_t repeatCount = mRepeatCount.ValueOr(1);
         uint16_t __block responsesNeeded = repeatCount;
         while (repeatCount--) {