diff --git a/bmc/version-handler/version_handler.cpp b/bmc/version-handler/version_handler.cpp
new file mode 100644
index 0000000..75ba940
--- /dev/null
+++ b/bmc/version-handler/version_handler.cpp
@@ -0,0 +1,182 @@
+#include "version_handler.hpp"
+
+#include <stdexcept>
+namespace ipmi_flash
+{
+std::unique_ptr<blobs::GenericBlobInterface>
+    VersionBlobHandler::create(VersionInfoMap&& versionMap)
+{
+    if (versionMap.empty())
+    {
+        return nullptr;
+    }
+    std::vector<std::string> blobList;
+    for (const auto& [key, val] : versionMap)
+    {
+        if (val.blobId != key || val.actionPack == nullptr ||
+            val.imageHandler == nullptr || val.actionPack->onOpen == nullptr)
+        {
+            return nullptr;
+        }
+        blobList.push_back(key);
+    }
+    return std::make_unique<VersionBlobHandler>(std::move(blobList),
+                                                std::move(versionMap));
+}
+
+bool VersionBlobHandler::canHandleBlob(const std::string& path)
+{
+    return (std::find(blobIds.begin(), blobIds.end(), path) != blobIds.end());
+}
+
+std::vector<std::string> VersionBlobHandler::getBlobIds()
+{
+    return blobIds;
+}
+
+/**
+ * deleteBlob - does nothing, always fails
+ */
+bool VersionBlobHandler::deleteBlob(const std::string& path)
+{
+    return false;
+}
+
+bool VersionBlobHandler::stat(const std::string& path, blobs::BlobMeta* meta)
+{
+    // TODO: stat should return the blob state and in the meta data information
+    // on whether a read is successful should be contained
+    // do things like determine if systemd target is triggered
+    // then check if file can be opened for read
+    return false; /* not yet implemented */
+}
+
+bool VersionBlobHandler::open(uint16_t session, uint16_t flags,
+                              const std::string& path)
+{
+    if (sessionToBlob.insert({session, path}).second == false)
+    {
+        fprintf(stderr, "open %s fail: session number %d assigned to %s\n",
+                path.c_str(), session, sessionToBlob.at(session).c_str());
+        return false;
+    }
+    /* only reads are supported, check if blob is handled and make sure
+     * the blob isn't already opened
+     */
+    if (flags != blobs::read)
+    {
+        fprintf(stderr, "open %s fail: unsupported flags(0x%04X.)\n",
+                path.c_str(), flags);
+        cleanup(session);
+        return false;
+    }
+    if (!canHandleBlob(path))
+    {
+        fprintf(stderr, "open %s fail: unrecognized blob\n", path.c_str());
+        cleanup(session);
+        return false;
+    }
+
+    try
+    {
+        auto& v = versionInfoMap.at(path);
+        if (v.blobState == blobs::StateFlags::open_read)
+        {
+            cleanup(session);
+            fprintf(stderr, "open %s fail: blob already opened for read\n",
+                    path.c_str());
+            return false;
+        }
+        if (v.actionPack->onOpen->trigger() == false)
+        {
+            fprintf(stderr, "open %s fail: onOpen trigger failed\n",
+                    path.c_str());
+            cleanup(session);
+            return false;
+        }
+        v.blobState = blobs::StateFlags::open_read;
+        return true;
+    }
+    catch (const std::out_of_range& e)
+    {
+        fprintf(stderr, "open %s fail, exception:%s\n", path.c_str(), e.what());
+        cleanup(session);
+        return false;
+    }
+}
+
+std::vector<uint8_t> VersionBlobHandler::read(uint16_t session, uint32_t offset,
+                                              uint32_t requestedSize)
+{
+    std::string* blobName;
+    VersionInfoPack* pack;
+    try
+    {
+        blobName = &sessionToBlob.at(session);
+        pack = &versionInfoMap.at(*blobName);
+    }
+    catch (const std::out_of_range& e)
+    {
+        return {};
+    }
+    /* onOpen trigger must be successful, otherwise potential
+     * for stale data to be read
+     */
+    if (pack->actionPack->onOpen->status() != ActionStatus::success)
+    {
+        fprintf(stderr, "read failed: onOpen trigger not successful\n");
+        return {};
+    }
+    if (!pack->imageHandler->open("don't care", std::ios::in))
+    {
+        fprintf(stderr, "read failed: file open unsuccessful blob=%s\n",
+                blobName->c_str());
+        return {};
+    }
+    auto d = pack->imageHandler->read(offset, requestedSize);
+    if (!d)
+    {
+        fprintf(stderr, "read failed: unable to read file for blob %s\n",
+                blobName->c_str());
+        pack->imageHandler->close();
+        return {};
+    }
+    pack->imageHandler->close();
+    return *d;
+}
+
+bool VersionBlobHandler::close(uint16_t session)
+{
+    return cleanup(session);
+}
+
+bool VersionBlobHandler::stat(uint16_t session, blobs::BlobMeta* meta)
+{
+    return false;
+}
+
+bool VersionBlobHandler::expire(uint16_t session)
+{
+    return cleanup(session);
+}
+
+bool VersionBlobHandler::cleanup(uint16_t session)
+{
+    try
+    {
+        const auto& blobName = sessionToBlob.at(session);
+        auto& pack = versionInfoMap.at(blobName);
+        if (pack.actionPack->onOpen->status() == ActionStatus::running)
+        {
+            pack.actionPack->onOpen->abort();
+        }
+        pack.blobState = static_cast<blobs::StateFlags>(0);
+        sessionToBlob.erase(session);
+        return true;
+    }
+    catch (const std::out_of_range& e)
+    {
+        return false;
+    }
+}
+} // namespace ipmi_flash
