diff --git a/bin/system-info.c b/bin/system-info.c
index c9403bd635b65ed1188fc444e53adab069040b3c..23de35f6a42e54ed6547c4b003d4110780725e1c 100644
--- a/bin/system-info.c
+++ b/bin/system-info.c
@@ -648,10 +648,15 @@ static void
 jsonify_container (JsonBuilder *builder,
                    SrtSystemInfo *info)
 {
-  SrtContainerType type = srt_system_info_get_container_type (info);
-  gchar *host_directory = srt_system_info_dup_container_host_directory (info);
-  gchar **env = NULL;
-  SrtSystemInfo *host = NULL;
+  SrtContainerInfo *container_info = srt_system_info_check_container (info);
+  SrtContainerType type = SRT_CONTAINER_TYPE_UNKNOWN;
+  const gchar *flatpak_version = NULL;
+  const gchar *host_directory = NULL;
+  g_autoptr(SrtSystemInfo) host = NULL;
+
+  type = srt_container_info_get_container_type (container_info);
+  flatpak_version = srt_container_info_get_flatpak_version (container_info);
+  host_directory = srt_container_info_get_container_host_directory (container_info);
 
   json_builder_set_member_name (builder, "container");
   json_builder_begin_object (builder);
@@ -661,6 +666,12 @@ jsonify_container (JsonBuilder *builder,
 
       if (type != SRT_CONTAINER_TYPE_NONE)
         {
+          if (flatpak_version != NULL)
+            {
+              json_builder_set_member_name (builder, "flatpak_version");
+              json_builder_add_string_value (builder, flatpak_version);
+            }
+
           json_builder_set_member_name (builder, "host");
           json_builder_begin_object (builder);
             {
@@ -678,10 +689,6 @@ jsonify_container (JsonBuilder *builder,
         }
     }
   json_builder_end_object (builder);
-
-  g_free (host_directory);
-  g_clear_object (&host);
-  g_strfreev (env);
 }
 
 static void
diff --git a/bin/system-info.md b/bin/system-info.md
index 233885754584f865e9cadf30b238bfec7121b4b4..4d492a02a14f6d009fca3e0e1e22816acc9c8f11 100644
--- a/bin/system-info.md
+++ b/bin/system-info.md
@@ -320,6 +320,11 @@ keys:
         **unknown** (if we appear to be in a container but the type is
         unknown), or **none** (if we do not appear to be in a container).
 
+    **flatpak_version**
+    :   The version string describing the Flatpak container. This key is
+        optional and is not provided if it could not be determined or if the
+        container **type** is not **flatpak**.
+
     **host**
     :   An object describing the host system. The keys are strings:
 
diff --git a/steam-runtime-tools/container-internal.h b/steam-runtime-tools/container-internal.h
new file mode 100644
index 0000000000000000000000000000000000000000..db9dd42e1cb7664dd2c16b5d8a548ceb2b01adc7
--- /dev/null
+++ b/steam-runtime-tools/container-internal.h
@@ -0,0 +1,71 @@
+/*<private_header>*/
+/*
+ * Copyright © 2021 Collabora Ltd.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#pragma once
+
+#include "steam-runtime-tools/container.h"
+
+#include <json-glib/json-glib.h>
+
+/*
+ * _srt_container_info_new:
+ * @type: Type of container
+ * @flatpak_version: (nullable): Flatpak container version, this value is
+ *  relevant only if @type is %SRT_CONTAINER_TYPE_FLATPAK
+ * @host_directory: (nullable) (type filename): Directory where host files can
+ *  be found
+ *
+ * Inline convenience function to create a new SrtContainerInfo.
+ * This is not part of the public API.
+ *
+ * Returns: (transfer full): A new #SrtContainerInfo
+ */
+static inline SrtContainerInfo *_srt_container_info_new (SrtContainerType type,
+                                                         const gchar *flatpak_version,
+                                                         const gchar *host_directory);
+
+#ifndef __GTK_DOC_IGNORE__
+static inline SrtContainerInfo *
+_srt_container_info_new (SrtContainerType type,
+                         const gchar *flatpak_version,
+                         const gchar *host_directory)
+{
+  return g_object_new (SRT_TYPE_CONTAINER_INFO,
+                       "type", type,
+                       "flatpak-version", flatpak_version,
+                       "host-directory", host_directory,
+                       NULL);
+}
+#endif
+
+/* See flatpak-metadata(5) */
+#define FLATPAK_METADATA_GROUP_INSTANCE "Instance"
+#define FLATPAK_METADATA_KEY_FLATPAK_VERSION "flatpak-version"
+
+SrtContainerInfo *_srt_check_container (int sysroot_fd,
+                                        const gchar *sysroot);
+
+SrtContainerInfo *_srt_container_info_get_from_report (JsonObject *json_obj);
diff --git a/steam-runtime-tools/container.c b/steam-runtime-tools/container.c
new file mode 100644
index 0000000000000000000000000000000000000000..e6506206ad275a8a3c1beae28094e97a5d70b070
--- /dev/null
+++ b/steam-runtime-tools/container.c
@@ -0,0 +1,490 @@
+/*
+ * Copyright © 2021 Collabora Ltd.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "steam-runtime-tools/container.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include "steam-runtime-tools/container-internal.h"
+#include "steam-runtime-tools/enums.h"
+#include "steam-runtime-tools/glib-backports-internal.h"
+#include "steam-runtime-tools/json-glib-backports-internal.h"
+#include "steam-runtime-tools/resolve-in-sysroot-internal.h"
+#include "steam-runtime-tools/utils.h"
+#include "steam-runtime-tools/utils-internal.h"
+
+/**
+ * SECTION:container-info
+ * @title: Container info
+ * @short_description: Information about the eventual container that is currently in use
+ * @include: steam-runtime-tools/steam-runtime-tools.h
+ */
+
+struct _SrtContainerInfo
+{
+  /*< private >*/
+  GObject parent;
+  gchar *flatpak_version;
+  gchar *host_directory;
+  SrtContainerType type;
+};
+
+struct _SrtContainerInfoClass
+{
+  /*< private >*/
+  GObjectClass parent_class;
+};
+
+enum {
+  PROP_0,
+  PROP_FLATPAK_VERSION,
+  PROP_HOST_DIRECTORY,
+  PROP_TYPE,
+  N_PROPERTIES
+};
+
+G_DEFINE_TYPE (SrtContainerInfo, srt_container_info, G_TYPE_OBJECT)
+
+static void
+srt_container_info_init (SrtContainerInfo *self)
+{
+}
+
+static void
+srt_container_info_get_property (GObject *object,
+                                 guint prop_id,
+                                 GValue *value,
+                                 GParamSpec *pspec)
+{
+  SrtContainerInfo *self = SRT_CONTAINER_INFO (object);
+
+  switch (prop_id)
+    {
+      case PROP_FLATPAK_VERSION:
+        g_value_set_string (value, self->flatpak_version);
+        break;
+
+      case PROP_HOST_DIRECTORY:
+        g_value_set_string (value, self->host_directory);
+        break;
+
+      case PROP_TYPE:
+        g_value_set_enum (value, self->type);
+        break;
+
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+srt_container_info_set_property (GObject *object,
+                                 guint prop_id,
+                                 const GValue *value,
+                                 GParamSpec *pspec)
+{
+  SrtContainerInfo *self = SRT_CONTAINER_INFO (object);
+
+  switch (prop_id)
+    {
+      case PROP_FLATPAK_VERSION:
+        /* Construct-only */
+        g_return_if_fail (self->flatpak_version == NULL);
+        self->flatpak_version = g_value_dup_string (value);
+        break;
+
+      case PROP_HOST_DIRECTORY:
+        /* Construct-only */
+        g_return_if_fail (self->host_directory == NULL);
+        self->host_directory = g_value_dup_string (value);
+        break;
+
+      case PROP_TYPE:
+        /* Construct-only */
+        g_return_if_fail (self->type == 0);
+        self->type = g_value_get_enum (value);
+        break;
+
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+srt_container_info_finalize (GObject *object)
+{
+  SrtContainerInfo *self = SRT_CONTAINER_INFO (object);
+
+  g_free (self->flatpak_version);
+  g_free (self->host_directory);
+
+  G_OBJECT_CLASS (srt_container_info_parent_class)->finalize (object);
+}
+
+static GParamSpec *properties[N_PROPERTIES] = { NULL };
+
+static void
+srt_container_info_class_init (SrtContainerInfoClass *cls)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (cls);
+
+  object_class->get_property = srt_container_info_get_property;
+  object_class->set_property = srt_container_info_set_property;
+  object_class->finalize = srt_container_info_finalize;
+
+  properties[PROP_FLATPAK_VERSION] =
+    g_param_spec_string ("flatpak-version", "Flatpak version",
+                         "Which Flatpak version, if any, is in use",
+                         NULL,
+                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+                         G_PARAM_STATIC_STRINGS);
+
+  properties[PROP_HOST_DIRECTORY] =
+    g_param_spec_string ("host-directory", "Host directory",
+                         "Absolute path where important files from the host "
+                         "system can be found",
+                         NULL,
+                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+                         G_PARAM_STATIC_STRINGS);
+
+  properties[PROP_TYPE] =
+    g_param_spec_enum ("type", "Container type",
+                       "Which container type is currently in use",
+                       SRT_TYPE_CONTAINER_TYPE, SRT_CONTAINER_TYPE_UNKNOWN,
+                       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+                       G_PARAM_STATIC_STRINGS);
+
+  g_object_class_install_properties (object_class, N_PROPERTIES, properties);
+}
+
+typedef struct
+{
+  SrtContainerType type;
+  const char *name;
+} ContainerTypeName;
+
+static const ContainerTypeName container_types[] =
+{
+  { SRT_CONTAINER_TYPE_DOCKER, "docker" },
+  { SRT_CONTAINER_TYPE_FLATPAK, "flatpak" },
+  { SRT_CONTAINER_TYPE_PODMAN, "podman" },
+  { SRT_CONTAINER_TYPE_PRESSURE_VESSEL, "pressure-vessel" },
+};
+
+static SrtContainerType
+container_type_from_name (const char *name)
+{
+  gsize i;
+
+  for (i = 0; i < G_N_ELEMENTS (container_types); i++)
+    {
+      const ContainerTypeName *entry = &container_types[i];
+
+      if (strcmp (entry->name, name) == 0)
+        return entry->type;
+    }
+
+  return SRT_CONTAINER_TYPE_UNKNOWN;
+}
+
+/**
+ * _srt_check_container:
+ * @sysroot_fd: Sysroot file descriptor
+ * @sysroot: (not nullable) (type filename): Path to the sysroot
+ *
+ * Gather and return information about the container that is currently in use.
+ *
+ * Returns: (transfer full): A new #SrtContainerInfo object.
+ *  Free with g_object_unref().
+ */
+SrtContainerInfo *
+_srt_check_container (int sysroot_fd,
+                      const gchar *sysroot)
+{
+  g_autofree gchar *contents = NULL;
+  g_autofree gchar *run_host_path = NULL;
+  g_autofree gchar *host_directory = NULL;
+  g_autofree gchar *flatpak_version = NULL;
+  SrtContainerType type = SRT_CONTAINER_TYPE_UNKNOWN;
+  glnx_autofd int run_host_fd = -1;
+
+  g_return_val_if_fail (sysroot != NULL, NULL);
+
+  if (sysroot_fd < 0)
+    {
+      g_debug ("Cannot find container info: previously failed to open "
+               "sysroot %s", sysroot);
+      goto out;
+    }
+
+  g_debug ("Finding container info in sysroot %s...", sysroot);
+
+  run_host_fd = _srt_resolve_in_sysroot (sysroot_fd, "/run/host",
+                                         SRT_RESOLVE_FLAGS_DIRECTORY,
+                                         &run_host_path, NULL);
+
+  if (run_host_path != NULL)
+    host_directory = g_build_filename (sysroot, run_host_path, NULL);
+
+  if (_srt_file_get_contents_in_sysroot (sysroot_fd,
+                                         "/run/host/container-manager",
+                                         &contents, NULL, NULL))
+    {
+      g_strchomp (contents);
+      type = container_type_from_name (contents);
+      g_debug ("Type %d based on /run/host/container-manager", type);
+      goto out;
+    }
+
+  if (_srt_file_get_contents_in_sysroot (sysroot_fd,
+                                         "/run/systemd/container",
+                                         &contents, NULL, NULL))
+    {
+      g_strchomp (contents);
+      type = container_type_from_name (contents);
+      g_debug ("Type %d based on /run/systemd/container", type);
+      goto out;
+    }
+
+  if (_srt_file_test_in_sysroot (sysroot, sysroot_fd, "/.flatpak-info",
+                                 G_FILE_TEST_IS_REGULAR))
+    {
+      type = SRT_CONTAINER_TYPE_FLATPAK;
+      g_debug ("Flatpak based on /.flatpak-info");
+      goto out;
+    }
+
+  if (_srt_file_test_in_sysroot (sysroot, sysroot_fd, "/run/pressure-vessel",
+                                 G_FILE_TEST_IS_DIR))
+    {
+      type = SRT_CONTAINER_TYPE_PRESSURE_VESSEL;
+      g_debug ("pressure-vessel based on /run/pressure-vessel");
+      goto out;
+    }
+
+  if (_srt_file_test_in_sysroot (sysroot, sysroot_fd, "/.dockerenv",
+                                 G_FILE_TEST_EXISTS))
+    {
+      type = SRT_CONTAINER_TYPE_DOCKER;
+      g_debug ("Docker based on /.dockerenv");
+      goto out;
+    }
+
+  if (_srt_file_test_in_sysroot (sysroot, sysroot_fd, "/run/.containerenv",
+                                 G_FILE_TEST_EXISTS))
+    {
+      type = SRT_CONTAINER_TYPE_PODMAN;
+      g_debug ("Podman based on /run/.containerenv");
+      goto out;
+    }
+
+  if (_srt_file_get_contents_in_sysroot (sysroot_fd, "/proc/1/cgroup",
+                                         &contents, NULL, NULL))
+    {
+      if (strstr (contents, "/docker/") != NULL)
+        type = SRT_CONTAINER_TYPE_DOCKER;
+
+      if (type != SRT_CONTAINER_TYPE_UNKNOWN)
+        {
+          g_debug ("Type %d based on /proc/1/cgroup", type);
+          goto out;
+        }
+
+      g_clear_pointer (&contents, g_free);
+    }
+
+  if (run_host_fd >= 0)
+    {
+      g_debug ("Unknown container technology based on /run/host");
+      type = SRT_CONTAINER_TYPE_UNKNOWN;
+      goto out;
+    }
+
+  /* We haven't found any particular evidence of being in a container */
+  g_debug ("Probably not a container");
+  type = SRT_CONTAINER_TYPE_NONE;
+
+out:
+  if (type == SRT_CONTAINER_TYPE_FLATPAK)
+    {
+      g_autoptr(GKeyFile) info = NULL;
+      g_autoptr(GError) local_error = NULL;
+      g_autofree gchar *flatpak_info_content = NULL;
+      gsize len;
+
+      if (_srt_file_get_contents_in_sysroot (sysroot_fd, "/.flatpak-info",
+                                             &flatpak_info_content,
+                                             &len, NULL))
+        {
+          info = g_key_file_new ();
+
+          if (!g_key_file_load_from_data (info, flatpak_info_content, len,
+                                          G_KEY_FILE_NONE, &local_error))
+            g_debug ("Unable to load Flatpak instance info: %s", local_error->message);
+
+          flatpak_version = g_key_file_get_string (info,
+                                                   FLATPAK_METADATA_GROUP_INSTANCE,
+                                                   FLATPAK_METADATA_KEY_FLATPAK_VERSION,
+                                                   NULL);
+        }
+    }
+
+  return _srt_container_info_new (type, flatpak_version, host_directory);
+}
+
+/**
+ * srt_container_info_get_container_type:
+ * @self: A SrtContainerInfo object
+ *
+ * If the program appears to be running in a container, return what sort
+ * of container it is.
+ *
+ * Implementation of srt_system_info_get_container_type().
+ *
+ * Returns: A recognised container type, or %SRT_CONTAINER_TYPE_NONE
+ *  if a container cannot be detected, or %SRT_CONTAINER_TYPE_UNKNOWN
+ *  if unsure.
+ */
+SrtContainerType
+srt_container_info_get_container_type (SrtContainerInfo *self)
+{
+  g_return_val_if_fail (SRT_IS_CONTAINER_INFO (self), SRT_CONTAINER_TYPE_UNKNOWN);
+  return self->type;
+}
+
+/**
+ * srt_container_info_get_container_host_directory:
+ * @self: A SrtContainerInfo object
+ *
+ * If the program appears to be running in a container, return the
+ * directory where host files can be found. For example, if this function
+ * returns `/run/host`, it might be possible to load the host system's
+ * `/usr/lib/os-release` by reading `/run/host/usr/lib/os-release`.
+ *
+ * The returned directory is usually not complete. For example,
+ * in a Flatpak app, `/run/host` will sometimes contain the host system's
+ * `/etc` and `/usr`, but only if suitable permissions flags are set.
+ *
+ * Implementation of srt_system_info_dup_container_host_directory().
+ *
+ * Returns: (type filename) (nullable): A path from which at least some
+ *  host-system files can be loaded, typically `/run/host`, or %NULL if
+ *  unknown or unavailable.
+ */
+const gchar *
+srt_container_info_get_container_host_directory (SrtContainerInfo *self)
+{
+  g_return_val_if_fail (SRT_IS_CONTAINER_INFO (self), NULL);
+  return self->host_directory;
+}
+
+/**
+ * srt_container_info_get_flatpak_version:
+ * @self: A SrtContainerInfo object
+ *
+ * If the program appears to be running in a container type
+ * %SRT_CONTAINER_TYPE_FLATPAK, return the Flatpak version.
+ *
+ * Returns: (type filename) (nullable): A filename, or %NULL if the container
+ *  type is not %SRT_CONTAINER_TYPE_FLATPAK or if it was not able to identify
+ *  the Flatpak version.
+ */
+const gchar *
+srt_container_info_get_flatpak_version (SrtContainerInfo *self)
+{
+  g_return_val_if_fail (SRT_IS_CONTAINER_INFO (self), NULL);
+
+  if (self->type != SRT_CONTAINER_TYPE_FLATPAK)
+    return NULL;
+
+  return self->flatpak_version;
+}
+
+/**
+ * _srt_system_info_get_container_info_from_report:
+ * @json_obj: (not nullable): A JSON Object used to search for "container"
+ *  property
+ * @host_path: (not nullable): Used to return the host path
+ *
+ * If the provided @json_obj doesn't have a "container" member,
+ * %SRT_CONTAINER_TYPE_UNKNOWN will be returned.
+ * If @json_obj has some elements that we can't parse, the returned
+ * #SrtContainerType will be set to %SRT_CONTAINER_TYPE_UNKNOWN.
+ *
+ * Returns: The found container type
+ */
+SrtContainerInfo *
+_srt_container_info_get_from_report (JsonObject *json_obj)
+{
+  JsonObject *json_sub_obj;
+  JsonObject *json_host_obj = NULL;
+  const gchar *type_string = NULL;
+  const gchar *flatpak_version = NULL;
+  const gchar *host_path = NULL;
+  SrtContainerType type = SRT_CONTAINER_TYPE_UNKNOWN;
+
+  g_return_val_if_fail (json_obj != NULL, NULL);
+
+  if (json_object_has_member (json_obj, "container"))
+    {
+      json_sub_obj = json_object_get_object_member (json_obj, "container");
+
+      if (json_sub_obj == NULL)
+        goto out;
+
+      if (json_object_has_member (json_sub_obj, "type"))
+        {
+          type_string = json_object_get_string_member (json_sub_obj, "type");
+          G_STATIC_ASSERT (sizeof (SrtContainerType) == sizeof (gint));
+          if (!srt_enum_from_nick (SRT_TYPE_CONTAINER_TYPE, type_string, (gint *) &type, NULL))
+            {
+              g_debug ("The parsed container type '%s' is not a known element", type_string);
+              type = SRT_CONTAINER_TYPE_UNKNOWN;
+            }
+        }
+
+      flatpak_version = json_object_get_string_member_with_default (json_sub_obj,
+                                                                    "flatpak_version",
+                                                                    NULL);
+
+      if (json_object_has_member (json_sub_obj, "host"))
+        {
+          json_host_obj = json_object_get_object_member (json_sub_obj, "host");
+          host_path = json_object_get_string_member_with_default (json_host_obj, "path",
+                                                                  NULL);
+        }
+    }
+
+out:
+  return _srt_container_info_new (type,
+                                  flatpak_version,
+                                  host_path);
+}
diff --git a/steam-runtime-tools/container.h b/steam-runtime-tools/container.h
new file mode 100644
index 0000000000000000000000000000000000000000..63e1177fdb5735f9fb1e3ce03ea16962f6aeb44d
--- /dev/null
+++ b/steam-runtime-tools/container.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright © 2021 Collabora Ltd.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#pragma once
+
+#if !defined(_SRT_IN_SINGLE_HEADER) && !defined(_SRT_COMPILATION)
+#error "Do not include directly, use <steam-runtime-tools/steam-runtime-tools.h>"
+#endif
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <steam-runtime-tools/macros.h>
+
+typedef struct _SrtContainerInfo SrtContainerInfo;
+typedef struct _SrtContainerInfoClass SrtContainerInfoClass;
+
+#define SRT_TYPE_CONTAINER_INFO srt_container_info_get_type ()
+#define SRT_CONTAINER_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SRT_TYPE_CONTAINER_INFO, SrtContainerInfo))
+#define SRT_CONTAINER_INFO_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST ((cls), SRT_TYPE_CONTAINER_INFO, SrtContainerInfoClass))
+#define SRT_IS_CONTAINER_INFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SRT_TYPE_CONTAINER_INFO))
+#define SRT_IS_CONTAINER_INFO_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE ((cls), SRT_TYPE_CONTAINER_INFO))
+#define SRT_CONTAINER_INFO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SRT_TYPE_CONTAINER_INFO, SrtContainerInfoClass)
+_SRT_PUBLIC
+GType srt_container_info_get_type (void);
+
+/**
+ * SrtContainerType:
+ * @SRT_CONTAINER_TYPE_UNKNOWN: Unknown container type
+ * @SRT_CONTAINER_TYPE_NONE: No container detected
+ * @SRT_CONTAINER_TYPE_FLATPAK: Running in a Flatpak app
+ * @SRT_CONTAINER_TYPE_PRESSURE_VESSEL: Running in a Steam Runtime container
+ *  using pressure-vessel
+ * @SRT_CONTAINER_TYPE_DOCKER: Running in a Docker container
+ * @SRT_CONTAINER_TYPE_PODMAN: Running in a Podman container
+ *
+ * A type of container.
+ */
+typedef enum
+{
+  SRT_CONTAINER_TYPE_NONE = 0,
+  SRT_CONTAINER_TYPE_FLATPAK,
+  SRT_CONTAINER_TYPE_PRESSURE_VESSEL,
+  SRT_CONTAINER_TYPE_DOCKER,
+  SRT_CONTAINER_TYPE_PODMAN,
+  SRT_CONTAINER_TYPE_UNKNOWN = -1
+} SrtContainerType;
+
+#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (SrtContainerInfo, g_object_unref)
+#endif
+
+_SRT_PUBLIC
+SrtContainerType srt_container_info_get_container_type (SrtContainerInfo *self);
+_SRT_PUBLIC
+const gchar *srt_container_info_get_container_host_directory (SrtContainerInfo *self);
+_SRT_PUBLIC
+const gchar *srt_container_info_get_flatpak_version (SrtContainerInfo *self);
diff --git a/steam-runtime-tools/meson.build b/steam-runtime-tools/meson.build
index 1f5ea949bd7d893c3723cd4640f5e5c03263d8ae..bd647f8277544761102bd33151c73d451630c096 100644
--- a/steam-runtime-tools/meson.build
+++ b/steam-runtime-tools/meson.build
@@ -24,6 +24,7 @@
 libsteamrt_sources = [
     'architecture-internal.h',
     'architecture.c',
+    'container.c',
     'cpu-feature-internal.h',
     'cpu-feature.c',
     'desktop-entry-internal.h',
@@ -69,6 +70,7 @@ libsteamrt_sources = [
 
 libsteamrt_public_headers = [
     'architecture.h',
+    'container.h',
     'cpu-feature.h',
     'desktop-entry.h',
     'graphics.h',
diff --git a/steam-runtime-tools/steam-runtime-tools.h b/steam-runtime-tools/steam-runtime-tools.h
index c6009f7c81d70e17bca872da67e81f29f7542307..83ad7ca5315810466343badb71879da9c0f84de3 100644
--- a/steam-runtime-tools/steam-runtime-tools.h
+++ b/steam-runtime-tools/steam-runtime-tools.h
@@ -28,6 +28,7 @@
 #define _SRT_IN_SINGLE_HEADER
 
 #include <steam-runtime-tools/architecture.h>
+#include <steam-runtime-tools/container.h>
 #include <steam-runtime-tools/cpu-feature.h>
 #include <steam-runtime-tools/desktop-entry.h>
 #include <steam-runtime-tools/enums.h>
diff --git a/steam-runtime-tools/system-info.c b/steam-runtime-tools/system-info.c
index 4995bc6810f5cb776b9b701dca218071429c6366..be2c172f69ff8d638355c7df6e520ca2ca3a772e 100644
--- a/steam-runtime-tools/system-info.c
+++ b/steam-runtime-tools/system-info.c
@@ -32,6 +32,7 @@
 
 #include "steam-runtime-tools/architecture.h"
 #include "steam-runtime-tools/architecture-internal.h"
+#include "steam-runtime-tools/container-internal.h"
 #include "steam-runtime-tools/cpu-feature-internal.h"
 #include "steam-runtime-tools/desktop-entry-internal.h"
 #include "steam-runtime-tools/graphics.h"
@@ -117,6 +118,7 @@ struct _SrtSystemInfo
   /* If %TRUE, #SrtSystemInfo cannot be changed anymore */
   gboolean immutable_values;
   GHashTable *cached_hidden_deps;
+  SrtContainerInfo *container_info;
   SrtSteam *steam_data;
   SrtXdgPortal *xdg_portal_data;
   struct
@@ -164,12 +166,6 @@ struct _SrtSystemInfo
     gboolean have_data;
   } pinned_libs;
   struct
-  {
-    SrtContainerType type;
-    gchar *host_directory;
-    gboolean have_data;
-  } container;
-  struct
   {
     GList *values;
     gboolean have_data;
@@ -373,8 +369,6 @@ srt_system_info_init (SrtSystemInfo *self)
 
   _srt_os_release_init (&self->os_release);
 
-  self->container.type = SRT_CONTAINER_TYPE_UNKNOWN;
-
   srt_system_info_set_sysroot (self, "/");
   srt_system_info_set_environ (self, NULL);
 }
@@ -433,9 +427,7 @@ forget_desktop_entries (SrtSystemInfo *self)
 static void
 forget_container_info (SrtSystemInfo *self)
 {
-  g_clear_pointer (&self->container.host_directory, g_free);
-  self->container.type = SRT_CONTAINER_TYPE_UNKNOWN;
-  self->container.have_data = FALSE;
+  g_clear_object (&self->container_info);
 }
 
 /*
@@ -629,8 +621,6 @@ srt_system_info_new (const char *expectations)
 }
 
 static gchar ** _srt_system_info_driver_environment_from_report (JsonObject *json_obj);
-static SrtContainerType _srt_system_info_get_container_info_from_report (JsonObject *json_obj,
-                                                                         gchar **host_path);
 static gchar ** _srt_system_info_get_pinned_libs_from_report (JsonObject *json_obj,
                                                               const gchar *which,
                                                               gchar ***messages);
@@ -857,8 +847,7 @@ srt_system_info_new_from_json (const char *path,
 
   _srt_os_release_populate_from_report (json_obj, &info->os_release);
 
-  info->container.type = _srt_system_info_get_container_info_from_report (json_obj,
-                                                                          &info->container.host_directory);
+  info->container_info = _srt_container_info_get_from_report (json_obj);
 
   info->cached_driver_environment = _srt_system_info_driver_environment_from_report (json_obj);
 
@@ -3859,151 +3848,31 @@ _srt_system_info_driver_environment_from_report (JsonObject *json_obj)
                                            "<invalid>");
 }
 
-typedef struct
-{
-  SrtContainerType type;
-  const char *name;
-} ContainerTypeName;
-
-static const ContainerTypeName container_types[] =
-{
-  { SRT_CONTAINER_TYPE_DOCKER, "docker" },
-  { SRT_CONTAINER_TYPE_FLATPAK, "flatpak" },
-  { SRT_CONTAINER_TYPE_PODMAN, "podman" },
-  { SRT_CONTAINER_TYPE_PRESSURE_VESSEL, "pressure-vessel" },
-};
-
-static SrtContainerType
-container_type_from_name (const char *name)
-{
-  gsize i;
-
-  for (i = 0; i < G_N_ELEMENTS (container_types); i++)
-    {
-      const ContainerTypeName *entry = &container_types[i];
-
-      if (strcmp (entry->name, name) == 0)
-        return entry->type;
-    }
-
-  return SRT_CONTAINER_TYPE_UNKNOWN;
-}
-
 static void
 ensure_container_info (SrtSystemInfo *self)
 {
-  g_autofree gchar *contents = NULL;
-  g_autofree gchar *run_host_path = NULL;
-  glnx_autofd int run_host_fd = -1;
-
-  if (self->container.have_data || self->immutable_values)
-    return;
-
-  g_assert (self->container.host_directory == NULL);
-  g_assert (self->container.type == SRT_CONTAINER_TYPE_UNKNOWN);
-  g_assert (self->sysroot != NULL);
-
-  if (self->sysroot_fd < 0)
-    {
-      g_debug ("Cannot find container info: previously failed to open "
-               "sysroot %s", self->sysroot);
-      goto out;
-    }
-
-  g_debug ("Finding container info in sysroot %s...", self->sysroot);
-
-  run_host_fd = _srt_resolve_in_sysroot (self->sysroot_fd, "/run/host",
-                                         SRT_RESOLVE_FLAGS_DIRECTORY,
-                                         &run_host_path, NULL);
-
-  if (run_host_path != NULL)
-    self->container.host_directory = g_build_filename (self->sysroot,
-                                                       run_host_path,
-                                                       NULL);
-
-  if (_srt_file_get_contents_in_sysroot (self->sysroot_fd,
-                                         "/run/host/container-manager",
-                                         &contents, NULL, NULL))
-    {
-      g_strchomp (contents);
-      self->container.type = container_type_from_name (contents);
-      g_debug ("Type %d based on /run/host/container-manager",
-               self->container.type);
-      goto out;
-    }
-
-  if (_srt_file_get_contents_in_sysroot (self->sysroot_fd,
-                                         "/run/systemd/container",
-                                         &contents, NULL, NULL))
-    {
-      g_strchomp (contents);
-      self->container.type = container_type_from_name (contents);
-      g_debug ("Type %d based on /run/systemd/container",
-               self->container.type);
-      goto out;
-    }
-
-  if (_srt_file_test_in_sysroot (self->sysroot, self->sysroot_fd,
-                                 "/.flatpak-info", G_FILE_TEST_IS_REGULAR))
-    {
-      self->container.type = SRT_CONTAINER_TYPE_FLATPAK;
-      g_debug ("Flatpak based on /.flatpak-info");
-      goto out;
-    }
-
-  if (_srt_file_test_in_sysroot (self->sysroot, self->sysroot_fd,
-                                 "/run/pressure-vessel", G_FILE_TEST_IS_DIR))
-    {
-      self->container.type = SRT_CONTAINER_TYPE_PRESSURE_VESSEL;
-      g_debug ("pressure-vessel based on /run/pressure-vessel");
-      goto out;
-    }
-
-  if (_srt_file_test_in_sysroot (self->sysroot, self->sysroot_fd,
-                                 "/.dockerenv", G_FILE_TEST_EXISTS))
-    {
-      self->container.type = SRT_CONTAINER_TYPE_DOCKER;
-      g_debug ("Docker based on /.dockerenv");
-      goto out;
-    }
-
-  if (_srt_file_test_in_sysroot (self->sysroot, self->sysroot_fd,
-                                 "/run/.containerenv", G_FILE_TEST_EXISTS))
-    {
-      self->container.type = SRT_CONTAINER_TYPE_PODMAN;
-      g_debug ("Podman based on /run/.containerenv");
-      goto out;
-    }
-
-  if (_srt_file_get_contents_in_sysroot (self->sysroot_fd,
-                                         "/proc/1/cgroup",
-                                         &contents, NULL, NULL))
-    {
-      if (strstr (contents, "/docker/") != NULL)
-        self->container.type = SRT_CONTAINER_TYPE_DOCKER;
-
-      if (self->container.type != SRT_CONTAINER_TYPE_UNKNOWN)
-        {
-          g_debug ("Type %d based on /proc/1/cgroup", self->container.type);
-          goto out;
-        }
-
-      g_clear_pointer (&contents, g_free);
-    }
+  g_return_if_fail (SRT_IS_SYSTEM_INFO (self));
 
-  if (run_host_fd >= 0)
-    {
-      g_debug ("Unknown container technology based on /run/host");
-      self->container.type = SRT_CONTAINER_TYPE_UNKNOWN;
-      goto out;
-    }
+  if (self->container_info == NULL && !self->immutable_values)
+    self->container_info = _srt_check_container (self->sysroot_fd, self->sysroot);
+}
 
-  /* We haven't found any particular evidence of being in a container */
-  g_debug ("Probably not a container");
-  self->container.type = SRT_CONTAINER_TYPE_NONE;
+/**
+ * srt_system_info_check_container:
+ * @self: The #SrtSystemInfo object
+ *
+ * Gather and return information about the container that is currently in use.
+ *
+ * Returns: (transfer full): An #SrtContainerInfo object.
+ *  Free with g_object_unref().
+ */
+SrtContainerInfo *
+srt_system_info_check_container (SrtSystemInfo *self)
+{
+  g_return_val_if_fail (SRT_IS_SYSTEM_INFO (self), NULL);
 
-out:
-  self->container.have_data = TRUE;
+  ensure_container_info (self);
+  return g_object_ref (self->container_info);
 }
 
 /**
@@ -4023,7 +3892,7 @@ srt_system_info_get_container_type (SrtSystemInfo *self)
   g_return_val_if_fail (SRT_IS_SYSTEM_INFO (self), SRT_CONTAINER_TYPE_UNKNOWN);
 
   ensure_container_info (self);
-  return self->container.type;
+  return srt_container_info_get_container_type (self->container_info);
 }
 
 /**
@@ -4048,60 +3917,7 @@ srt_system_info_dup_container_host_directory (SrtSystemInfo *self)
   g_return_val_if_fail (SRT_IS_SYSTEM_INFO (self), NULL);
 
   ensure_container_info (self);
-  return g_strdup (self->container.host_directory);
-}
-
-/**
- * _srt_system_info_get_container_info_from_report:
- * @json_obj: (not nullable): A JSON Object used to search for "container"
- *  property
- * @host_path: (not nullable): Used to return the host path
- *
- * If the provided @json_obj doesn't have a "container" member,
- * %SRT_CONTAINER_TYPE_UNKNOWN will be returned.
- * If @json_obj has some elements that we can't parse, the returned
- * #SrtContainerType will be set to %SRT_CONTAINER_TYPE_UNKNOWN.
- *
- * Returns: The found container type
- */
-static SrtContainerType
-_srt_system_info_get_container_info_from_report (JsonObject *json_obj,
-                                                 gchar **host_path)
-{
-  JsonObject *json_sub_obj;
-  JsonObject *json_host_obj = NULL;
-  const gchar *type_string = NULL;
-  SrtContainerType ret = SRT_CONTAINER_TYPE_UNKNOWN;
-
-  g_return_val_if_fail (host_path != NULL && *host_path == NULL, SRT_CONTAINER_TYPE_UNKNOWN);
-
-  if (json_object_has_member (json_obj, "container"))
-    {
-      json_sub_obj = json_object_get_object_member (json_obj, "container");
-
-      if (json_sub_obj == NULL)
-        goto out;
-
-      if (json_object_has_member (json_sub_obj, "type"))
-        {
-          type_string = json_object_get_string_member (json_sub_obj, "type");
-          if (!srt_enum_from_nick (SRT_TYPE_CONTAINER_TYPE, type_string, &ret, NULL))
-            {
-              g_debug ("The parsed container type '%s' is not a known element", type_string);
-              ret = SRT_CONTAINER_TYPE_UNKNOWN;
-            }
-        }
-
-      if (json_object_has_member (json_sub_obj, "host"))
-        {
-          json_host_obj = json_object_get_object_member (json_sub_obj, "host");
-          *host_path = g_strdup (json_object_get_string_member_with_default (json_host_obj, "path",
-                                                                             NULL));
-        }
-    }
-
-out:
-  return ret;
+  return g_strdup (srt_container_info_get_container_host_directory (self->container_info));
 }
 
 static void
@@ -4267,7 +4083,7 @@ ensure_xdg_portals_cached (SrtSystemInfo *self)
       _srt_check_xdg_portals (self->env,
                               self->helpers_path,
                               self->test_flags,
-                              self->container.type,
+                              srt_container_info_get_container_type (self->container_info),
                               srt_system_info_get_primary_multiarch_tuple (self),
                               &self->xdg_portal_data);
     }
diff --git a/steam-runtime-tools/system-info.h b/steam-runtime-tools/system-info.h
index 5b3c91a1320c6b3be826ecd851f1151c0d721531..935c82a2b66f23fac3040169809bc78554e0180e 100644
--- a/steam-runtime-tools/system-info.h
+++ b/steam-runtime-tools/system-info.h
@@ -32,6 +32,7 @@
 #include <glib.h>
 #include <glib-object.h>
 
+#include <steam-runtime-tools/container.h>
 #include <steam-runtime-tools/cpu-feature.h>
 #include <steam-runtime-tools/graphics.h>
 #include <steam-runtime-tools/library.h>
@@ -74,28 +75,6 @@ typedef enum
   SRT_DRIVER_FLAGS_NONE = 0
 } SrtDriverFlags;
 
-/**
- * SrtContainerType:
- * @SRT_CONTAINER_TYPE_UNKNOWN: Unknown container type
- * @SRT_CONTAINER_TYPE_NONE: No container detected
- * @SRT_CONTAINER_TYPE_FLATPAK: Running in a Flatpak app
- * @SRT_CONTAINER_TYPE_PRESSURE_VESSEL: Running in a Steam Runtime container
- *  using pressure-vessel
- * @SRT_CONTAINER_TYPE_DOCKER: Running in a Docker container
- * @SRT_CONTAINER_TYPE_PODMAN: Running in a Podman container
- *
- * A type of container.
- */
-typedef enum
-{
-  SRT_CONTAINER_TYPE_NONE = 0,
-  SRT_CONTAINER_TYPE_FLATPAK,
-  SRT_CONTAINER_TYPE_PRESSURE_VESSEL,
-  SRT_CONTAINER_TYPE_DOCKER,
-  SRT_CONTAINER_TYPE_PODMAN,
-  SRT_CONTAINER_TYPE_UNKNOWN = -1
-} SrtContainerType;
-
 typedef struct _SrtSystemInfo SrtSystemInfo;
 typedef struct _SrtSystemInfoClass SrtSystemInfoClass;
 
@@ -120,6 +99,8 @@ _SRT_PUBLIC
 gboolean srt_system_info_can_run (SrtSystemInfo *self,
                                   const char *multiarch_tuple);
 _SRT_PUBLIC
+SrtContainerInfo *srt_system_info_check_container (SrtSystemInfo *self);
+_SRT_PUBLIC
 SrtContainerType srt_system_info_get_container_type (SrtSystemInfo *self);
 _SRT_PUBLIC
 gchar *srt_system_info_dup_container_host_directory (SrtSystemInfo *self);
diff --git a/steam-runtime-tools/xdg-portal-internal.h b/steam-runtime-tools/xdg-portal-internal.h
index 3eeddcfa5ba98de74696a7171ed9bcd661f7db3d..3999a9100010409f4ac58e96fb559112559ac5a1 100644
--- a/steam-runtime-tools/xdg-portal-internal.h
+++ b/steam-runtime-tools/xdg-portal-internal.h
@@ -27,6 +27,7 @@
 #pragma once
 
 #include "steam-runtime-tools/steam-runtime-tools.h"
+#include "steam-runtime-tools/container-internal.h"
 
 #include <json-glib/json-glib.h>
 
diff --git a/steam-runtime-tools/xdg-portal.c b/steam-runtime-tools/xdg-portal.c
index 36b12fec053a9a22e64839903911c57f99877ff1..8aa09c7720a730e4535079fd5ba33700434a6b61 100644
--- a/steam-runtime-tools/xdg-portal.c
+++ b/steam-runtime-tools/xdg-portal.c
@@ -25,6 +25,7 @@
 
 #include "steam-runtime-tools/xdg-portal.h"
 
+#include "steam-runtime-tools/container-internal.h"
 #include "steam-runtime-tools/enums.h"
 #include "steam-runtime-tools/glib-backports-internal.h"
 #include "steam-runtime-tools/json-glib-backports-internal.h"
diff --git a/tests/container.c b/tests/container.c
new file mode 100644
index 0000000000000000000000000000000000000000..50de5d803e549d8507625011ca14bee2cc11f3b7
--- /dev/null
+++ b/tests/container.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright © 2021 Collabora Ltd.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* Include it before steam-runtime-tools.h so that its backport of
+ * G_DEFINE_AUTOPTR_CLEANUP_FUNC will be visible to it */
+#include "steam-runtime-tools/glib-backports-internal.h"
+
+#include <steam-runtime-tools/steam-runtime-tools.h>
+
+#include <string.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#include "steam-runtime-tools/container-internal.h"
+#include "steam-runtime-tools/utils-internal.h"
+#include "test-utils.h"
+
+static const char *argv0;
+static gchar *global_sysroots;
+
+typedef struct
+{
+  gchar *builddir;
+} Fixture;
+
+typedef struct
+{
+  int unused;
+} Config;
+
+static void
+setup (Fixture *f,
+       gconstpointer context)
+{
+  G_GNUC_UNUSED const Config *config = context;
+  f->builddir = g_strdup (g_getenv ("G_TEST_BUILDDIR"));
+
+  if (f->builddir == NULL)
+    f->builddir = g_path_get_dirname (argv0);
+}
+
+static void
+teardown (Fixture *f,
+          gconstpointer context)
+{
+  G_GNUC_UNUSED const Config *config = context;
+
+  g_free (f->builddir);
+}
+
+/*
+ * Test basic functionality of the SrtContainerInfo object.
+ */
+static void
+test_object (Fixture *f,
+             gconstpointer context)
+{
+  g_autoptr(SrtContainerInfo) container = NULL;
+  SrtContainerType type;
+  g_autofree gchar *flatpak_version = NULL;
+  g_autofree gchar *host_directory = NULL;
+
+  container = _srt_container_info_new (SRT_CONTAINER_TYPE_FLATPAK,
+                                       "1.10.2",
+                                       "/run/host");
+
+  g_assert_cmpint (srt_container_info_get_container_type (container), ==,
+                   SRT_CONTAINER_TYPE_FLATPAK);
+  g_assert_cmpstr (srt_container_info_get_flatpak_version (container), ==, "1.10.2");
+  g_assert_cmpstr (srt_container_info_get_container_host_directory (container), ==,
+                   "/run/host");
+  g_object_get (container,
+                "type", &type,
+                "flatpak-version", &flatpak_version,
+                "host-directory", &host_directory,
+                NULL);
+  g_assert_cmpint (type, ==, SRT_CONTAINER_TYPE_FLATPAK);
+  g_assert_cmpstr (flatpak_version, ==, "1.10.2");
+  g_assert_cmpstr (host_directory, ==, "/run/host");
+}
+
+typedef struct
+{
+  const char *description;
+  const char *sysroot;
+  SrtContainerType type;
+  const char *host_directory;
+  const char *flatpak_version;
+} ContainerTest;
+
+static const ContainerTest container_tests[] =
+{
+  {
+    .description = "Has /.dockerenv",
+    .sysroot = "debian-unstable",
+    .type = SRT_CONTAINER_TYPE_DOCKER,
+  },
+  {
+    .description = "Has an unknown value in /run/systemd/container",
+    .sysroot = "debian10",
+    .type = SRT_CONTAINER_TYPE_UNKNOWN,
+  },
+  {
+    .description = "Has 'docker' in /run/systemd/container",
+    .sysroot = "fedora",
+    .type = SRT_CONTAINER_TYPE_DOCKER,
+  },
+  {
+    .description = "Has /.flatpak-info and /run/host",
+    .sysroot = "flatpak-example",
+    .type = SRT_CONTAINER_TYPE_FLATPAK,
+    .host_directory = "/run/host",
+    .flatpak_version = "1.10.2",
+  },
+  {
+    .description = "Has /run/host",
+    .sysroot = "invalid-os-release",
+    .type = SRT_CONTAINER_TYPE_UNKNOWN,
+    .host_directory = "/run/host",
+  },
+  {
+    .description = "Has no evidence of being a container",
+    .sysroot = "no-os-release",
+    .type = SRT_CONTAINER_TYPE_NONE,
+  },
+  {
+    .description = "Has /run/pressure-vessel",
+    .sysroot = "steamrt",
+    .type = SRT_CONTAINER_TYPE_PRESSURE_VESSEL,
+  },
+  {
+    .description = "Has a Docker-looking /proc/1/cgroup",
+    .sysroot = "steamrt-unofficial",
+    .type = SRT_CONTAINER_TYPE_DOCKER,
+  },
+  {
+    .description = "Has 'podman' in /run/host/container-manager",
+    .sysroot = "podman-example",
+    .type = SRT_CONTAINER_TYPE_PODMAN,
+    .host_directory = "/run/host",
+  },
+};
+
+static void
+test_containers (Fixture *f,
+                 gconstpointer context)
+{
+  gsize i, j;
+
+  for (i = 0; i < G_N_ELEMENTS (container_tests); i++)
+    {
+      const ContainerTest *test = &container_tests[i];
+      g_autoptr(SrtSystemInfo) info;
+      g_autofree gchar *expected_host = NULL;
+      g_autofree gchar *sysroot = NULL;
+
+      g_test_message ("%s: %s", test->sysroot, test->description);
+
+      sysroot = g_build_filename (global_sysroots, test->sysroot, NULL);
+
+      info = srt_system_info_new (NULL);
+      g_assert_nonnull (info);
+      srt_system_info_set_sysroot (info, sysroot);
+
+      if (test->host_directory == NULL)
+        expected_host = NULL;
+      else
+        expected_host = g_build_filename (sysroot, test->host_directory, NULL);
+
+      for (j = 0; j < 2; j++)
+        {
+          g_autoptr(SrtContainerInfo) container = NULL;
+          g_autofree gchar *host_dir_dup = NULL;
+
+          container = srt_system_info_check_container (info);
+          g_assert_nonnull (container);
+
+          g_assert_cmpint (srt_system_info_get_container_type (info), ==,
+                           test->type);
+          g_assert_cmpint (srt_container_info_get_container_type (container), ==,
+                           test->type);
+
+          host_dir_dup = srt_system_info_dup_container_host_directory (info);
+          g_assert_cmpstr (host_dir_dup, ==, expected_host);
+          g_assert_cmpstr (srt_container_info_get_container_host_directory (container),
+                           ==, expected_host);
+
+          g_assert_cmpstr (srt_container_info_get_flatpak_version (container),
+                           ==, test->flatpak_version);
+        }
+    }
+}
+
+int
+main (int argc,
+      char **argv)
+{
+  argv0 = argv[0];
+  global_sysroots = _srt_global_setup_sysroots (argv0);
+
+  g_test_init (&argc, &argv, NULL);
+  g_test_add ("/container/object", Fixture, NULL,
+              setup, test_object, teardown);
+  g_test_add ("/container/containers", Fixture, NULL,
+              setup, test_containers, teardown);
+
+  return g_test_run ();
+}
diff --git a/tests/generate-sysroots.py b/tests/generate-sysroots.py
index f64f7a3507479d5e4a52e60a5a1f77227a179b6e..ece15e13563215e80eceeee53a69e8f2d33c4c8c 100755
--- a/tests/generate-sysroots.py
+++ b/tests/generate-sysroots.py
@@ -117,6 +117,7 @@ no-os-release/custom_path64/dri
 no-os-release/custom_path64/va
 no-os-release/usr/lib/dri
 no-os-release/usr/lib/vdpau
+podman-example/run/host
 steamrt/etc
 steamrt/overrides/bin
 steamrt/overrides/lib/x86_64-linux-gnu
@@ -206,7 +207,6 @@ fedora/usr/lib64/libva.so.2
 fedora/usr/lib64/libvdpau.so.1
 fedora/usr/lib64/vdpau/libvdpau_r300.so
 fedora/usr/lib64/vdpau/libvdpau_radeonsi.so
-flatpak-example/.flatpak-info
 flatpak-example/usr/lib/dri/r300_dri.so
 flatpak-example/usr/lib/dri/r600_drv_video.so
 flatpak-example/usr/lib/x86_64-mock-abi/GL/lib/dri/i965_dri.so
@@ -307,6 +307,23 @@ for name, target in {
     except FileExistsError:
         pass
 
+with open('flatpak-example/.flatpak-info', 'w') as writer:
+    writer.write('''\
+[Application]
+name=com.valvesoftware.Steam
+runtime=runtime/org.freedesktop.Platform/x86_64/20.08
+
+[Instance]
+branch=stable
+arch=x86_64
+flatpak-version=1.10.2
+session-bus-proxy=true
+system-bus-proxy=true
+devel=true''')
+
+with open('podman-example/run/host/container-manager', 'w') as writer:
+    writer.write("podman")
+
 with open('debian10/custom_path/Single-good-layer.json', 'w') as writer:
     writer.write('''\
 {
diff --git a/tests/json-report/partial-report.json b/tests/json-report/partial-report.json
index b3e13c453f3ebe50dd1fd7f60c785ab2eb2f98b7..bec5fcd8caf34299c49914675ebd0b6b99893153 100644
--- a/tests/json-report/partial-report.json
+++ b/tests/json-report/partial-report.json
@@ -1,6 +1,7 @@
 {
   "container" : {
     "type" : "flatpak",
+    "flatpak_version" : "1.10.2",
     "host" : {
       "path" : null
     }
diff --git a/tests/meson.build b/tests/meson.build
index 59b03554682d15c0870db70173c01ab1afa0a149..a372c1ca1353c03a1bef17ce7d375954073757cf 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -29,6 +29,7 @@ test_env.prepend('PATH', join_paths(meson.current_build_dir(), '..', 'bin'))
 
 tests = [
   {'name': 'architecture'},
+  {'name': 'container'},
   {'name': 'desktop-entry'},
   {'name': 'graphics'},
   {
diff --git a/tests/system-info.c b/tests/system-info.c
index ca964d7ff5ad4a5c5b01a63b6ccac07c2a5faf19..268b2937ccf33106786e4bda13783d882cd93934 100644
--- a/tests/system-info.c
+++ b/tests/system-info.c
@@ -2388,75 +2388,6 @@ steamscript_env (Fixture *f,
   g_strfreev (envp);
 }
 
-typedef struct
-{
-  const char *description;
-  const char *sysroot;
-  SrtContainerType type;
-  const char *host_directory;
-} ContainerTest;
-
-static const ContainerTest container_tests[] =
-{
-  { "Has /.dockerenv",
-    "debian-unstable", SRT_CONTAINER_TYPE_DOCKER, NULL },
-  { "Has an unknown value in /run/systemd/container",
-    "debian10", SRT_CONTAINER_TYPE_UNKNOWN, NULL },
-  { "Has 'docker' in /run/systemd/container",
-    "fedora", SRT_CONTAINER_TYPE_DOCKER, NULL },
-  { "Has /.flatpak-info and /run/host",
-    "flatpak-example", SRT_CONTAINER_TYPE_FLATPAK, "/run/host" },
-  { "Has /run/host",
-    "invalid-os-release", SRT_CONTAINER_TYPE_UNKNOWN, "/run/host" },
-  { "Has no evidence of being a container",
-    "no-os-release", SRT_CONTAINER_TYPE_NONE, NULL },
-  { "Has /run/pressure-vessel",
-    "steamrt", SRT_CONTAINER_TYPE_PRESSURE_VESSEL, NULL },
-  { "Has a Docker-looking /proc/1/cgroup",
-    "steamrt-unofficial", SRT_CONTAINER_TYPE_DOCKER, NULL },
-};
-
-static void
-test_containers (Fixture *f,
-                 gconstpointer context)
-{
-  gsize i, j;
-
-  for (i = 0; i < G_N_ELEMENTS (container_tests); i++)
-    {
-      const ContainerTest *test = &container_tests[i];
-      SrtSystemInfo *info;
-      gchar *sysroot, *got, *expected;
-
-      g_test_message ("%s: %s", test->sysroot, test->description);
-
-      sysroot = g_build_filename (f->sysroots, test->sysroot, NULL);
-
-      info = srt_system_info_new (NULL);
-      g_assert_nonnull (info);
-      srt_system_info_set_sysroot (info, sysroot);
-
-      for (j = 0; j < 2; j++)
-        {
-          g_assert_cmpint (srt_system_info_get_container_type (info), ==,
-                           test->type);
-          got = srt_system_info_dup_container_host_directory (info);
-
-          if (test->host_directory == NULL)
-            expected = NULL;
-          else
-            expected = g_build_filename (sysroot, test->host_directory, NULL);
-
-          g_assert_cmpstr (got, ==, expected);
-          g_free (got);
-          g_free (expected);
-        }
-
-      g_object_unref (info);
-      g_free (sysroot);
-    }
-}
-
 /* For the purpose of this test an array that is NULL, and one with just one
  * NULL element, are considered to be equal */
 static void
@@ -2527,6 +2458,7 @@ typedef struct
 {
   SrtContainerType type;
   const gchar *host_path;
+  const gchar *flatpak_version;
 } ContTest;
 
 typedef struct
@@ -3097,6 +3029,7 @@ static const JsonTest json_test[] =
     .container =
     {
       .type = SRT_CONTAINER_TYPE_FLATPAK,
+      .flatpak_version = "1.10.2",
     },
     .driver_environment =
     {
@@ -3506,6 +3439,7 @@ json_parsing (Fixture *f,
       g_autoptr(SrtObjectList) portal_backends = NULL;
       g_autoptr(SrtObjectList) explicit_layers = NULL;
       g_autoptr(SrtObjectList) implicit_layers = NULL;
+      g_autoptr(SrtContainerInfo) container = NULL;
       g_autofree gchar *portal_messages = NULL;
       g_autofree gchar *steamscript_path = NULL;
       g_autofree gchar *steamscript_version = NULL;
@@ -3560,9 +3494,12 @@ json_parsing (Fixture *f,
       g_assert_cmpstr (t->os_release.name, ==, name);
       g_assert_cmpstr (t->os_release.pretty_name, ==, pretty_name);
 
+      container = srt_system_info_check_container (info);
       host_directory = srt_system_info_dup_container_host_directory (info);
       g_assert_cmpint (t->container.type, ==, srt_system_info_get_container_type (info));
       g_assert_cmpstr (t->container.host_path, ==, host_directory);
+      g_assert_cmpstr (t->container.flatpak_version, ==,
+                       srt_container_info_get_flatpak_version (container));
 
       driver_environment_list = srt_system_info_list_driver_environment (info);
       assert_equal_strings_arrays (t->driver_environment,
@@ -4088,9 +4025,6 @@ main (int argc,
   g_test_add ("/system-info/steamscript_env", Fixture, NULL,
               setup, steamscript_env, teardown);
 
-  g_test_add ("/system-info/containers", Fixture, NULL,
-              setup, test_containers, teardown);
-
   g_test_add ("/system-info/json_parsing", Fixture, NULL,
               setup, json_parsing, teardown);