static int __pakfire_extract(struct pakfire* pakfire, struct archive* a,
                struct archive_entry* entry, void* p) {
        struct pakfire_file* file = NULL;
+       struct vfs_cap_data cap_data = {};
        char buffer[PATH_MAX];
        int r;
 
                // Remove any extended attributes which we never write to disk
                archive_entry_xattr_clear(entry);
 
+               // Set capabilities
+               if (pakfire_file_has_caps(file)) {
+                       r = pakfire_file_write_fcaps(file, &cap_data);
+                       if (r)
+                               goto ERROR;
+
+                       // Store capabilities in archive entry
+                       archive_entry_xattr_add_entry(entry, "security.capability",
+                               &cap_data, sizeof(cap_data));
+               }
+
                // Write payload
                r = archive_read_extract2(data->archive, entry, data->writer);
                switch (r) {
 
        return r;
 }
 
+int pakfire_file_write_fcaps(struct pakfire_file* file, struct vfs_cap_data* cap_data) {
+       cap_flag_value_t cap_permitted;
+       cap_flag_value_t cap_inheritable;
+       cap_flag_value_t cap_effective;
+       int r;
+
+       // This should not be called when we have no caps
+       if (!file->caps) {
+               errno = EINVAL;
+               return 1;
+       }
+
+       uint32_t magic = VFS_CAP_REVISION_2;
+
+       for (unsigned int cap = 0; cap_valid(cap); cap++) {
+               // Find the index where to find this cap
+               int index = CAP_TO_INDEX(cap);
+               int mask  = CAP_TO_MASK(cap);
+
+               // Fetch CAP_PERMITTED
+               r = cap_get_flag(file->caps, cap, CAP_PERMITTED, &cap_permitted);
+               if (r) {
+                       ERROR(file->pakfire, "Could not fetch capability %d: %m\n", cap);
+                       goto ERROR;
+               }
+
+               // Fetch CAP_INHERITABLE
+               r = cap_get_flag(file->caps, cap, CAP_INHERITABLE, &cap_inheritable);
+               if (r) {
+                       ERROR(file->pakfire, "Could not fetch capability %d: %m\n", cap);
+                       goto ERROR;
+               }
+
+               // Fetch CAP_EFFECTIVE
+               r = cap_get_flag(file->caps, cap, CAP_EFFECTIVE, &cap_effective);
+               if (r) {
+                       ERROR(file->pakfire, "Could not fetch capability %d: %m\n", cap);
+                       goto ERROR;
+               }
+
+               // Store CAP_PERMITTED
+               if (cap_permitted)
+                       cap_data->data[index].permitted |= htole32(mask);
+
+               // Store CAP_INHERITED
+               if (cap_inheritable)
+                       cap_data->data[index].inheritable |= htole32(mask);
+
+               // Set EFFECTIVE flag if CAP_EFFECTIVE is set
+               if (cap_effective)
+                       magic |= VFS_CAP_FLAGS_EFFECTIVE;
+       }
+
+       // Store the magic value
+       cap_data->magic_etc = htole32(magic);
+
+ERROR:
+       return r;
+}
+
 static int pakfire_file_from_archive_entry(struct pakfire_file* file, struct archive_entry* entry) {
        char* buffer = NULL;
        const char* path = NULL;
 }
 
 struct archive_entry* pakfire_file_archive_entry(struct pakfire_file* file, int digest_types) {
+       struct vfs_cap_data cap_data = {};
        const char* path = NULL;
        int r;
 
                archive_entry_xattr_add_entry(entry, "PAKFIRE.digests.sha2_256",
                        file->digests.sha2_256, sizeof(file->digests.sha2_256));
 
+       // Capabilities
+       if (file->caps) {
+               r = pakfire_file_write_fcaps(file, &cap_data);
+               if (r) {
+                       ERROR(file->pakfire, "Could not export capabilities: %m\n");
+                       goto ERROR;
+               }
+
+               // Store capabilities in archive entry
+               archive_entry_xattr_add_entry(entry,
+                       "security.capability", &cap_data, sizeof(cap_data));
+       }
+
        return entry;
 
 ERROR:
        return 0;
 }
 
+PAKFIRE_EXPORT int pakfire_file_has_caps(struct pakfire_file* file) {
+       if (file->caps)
+               return 1;
+
+       return 0;
+}
+
+PAKFIRE_EXPORT char* pakfire_file_get_caps(struct pakfire_file* file) {
+       char* copy = NULL;
+       char* text = NULL;
+       ssize_t length = 0;
+
+       if (file->caps) {
+               text = cap_to_text(file->caps, &length);
+               if (!text) {
+                       ERROR(file->pakfire, "Could not export capabilities: %m\n");
+                       goto ERROR;
+               }
+
+               // libcap is being weird and uses its own allocator so we have to copy the string
+               copy = strndup(text, length);
+               if (!copy)
+                       goto ERROR;
+       }
+
+ERROR:
+       if (text)
+               cap_free(text);
+
+       return copy;
+}
+
 static int pakfire_file_levels(struct pakfire_file* file) {
        if (!*file->path)
                return 0;
 
 int pakfire_file_set_digest(struct pakfire_file* file,
        const enum pakfire_digest_types type, const unsigned char* digest, const size_t length);
 
+// Capabilities
+int pakfire_file_has_caps(struct pakfire_file* file);
+char* pakfire_file_get_caps(struct pakfire_file* file);
+
 // MIME Type
 const char* pakfire_file_get_mimetype(struct pakfire_file* file);
 int pakfire_file_set_mimetype(struct pakfire_file* file, const char* mimetype);
 
 #include <archive_entry.h>
 
+#include <sys/capability.h>
+
 enum pakfire_file_classes {
        PAKFIRE_FILE_UNKNOWN         = 0,
 
        PAKFIRE_FILE_RUNTIME_LINKER  = (1 << 14),
 };
 
+int pakfire_file_write_fcaps(struct pakfire_file* file, struct vfs_cap_data* cap_data);
+
 int pakfire_file_create_from_path(struct pakfire_file** file,
        struct pakfire* pakfire, const char* path);
 int pakfire_file_create_from_archive_entry(struct pakfire_file** file, struct pakfire* pakfire,