diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h
index 7f07413f95602881..4be25042a0d6b387 100644
--- a/include/libcamera/internal/camera_sensor.h
+++ b/include/libcamera/internal/camera_sensor.h
@@ -49,6 +49,7 @@ public:
 	int init();
 
 	const std::string &model() const { return model_; }
+	const std::string &id() const { return id_; }
 	const MediaEntity *entity() const { return entity_; }
 	const std::vector<unsigned int> &mbusCodes() const { return mbusCodes_; }
 	const std::vector<Size> &sizes() const { return sizes_; }
@@ -74,6 +75,7 @@ private:
 	unsigned int pad_;
 
 	std::string model_;
+	std::string id_;
 
 	ImageFormats formats_;
 	Size resolution_;
diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp
index 6e93cc51155ba678..733ddf6866bd1ec1 100644
--- a/src/libcamera/camera_sensor.cpp
+++ b/src/libcamera/camera_sensor.cpp
@@ -205,6 +205,12 @@ int CameraSensor::init()
 	if (ret < 0)
 		return ret;
 
+	/* Create ID from sysfs device path. */
+	id_ = subdev_->devicePath();
+	const std::string dropStr = "/sys/devices/";
+	if (id_.find(dropStr) == 0)
+		id_.erase(0, dropStr.length());
+
 	/* Retrieve and store the camera sensor properties. */
 	const ControlInfoMap &controls = subdev_->controls();
 	int32_t propertyValue;
@@ -284,6 +290,17 @@ int CameraSensor::init()
  * \return The sensor model name
  */
 
+/**
+ * \fn CameraSensor::id()
+ * \brief Retrieve the sensor ID
+ *
+ * The sensor ID is a free-formed string that uniquely identifies the sensor in
+ * the system. The ID is persisted between different instances of libcamera and
+ * between resets of the system.
+ *
+ * \return The sensor ID
+ */
+
 /**
  * \fn CameraSensor::entity()
  * \brief Retrieve the sensor media entity
