diff --git a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ALeappAnalyzerIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ALeappAnalyzerIngestModule.java
index 3cfe4b954c055165bfa1c63fc391e1cc3ca550eb..ea734781e1861cfababecc12cec771abacd6864f 100644
--- a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ALeappAnalyzerIngestModule.java
+++ b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ALeappAnalyzerIngestModule.java
@@ -100,7 +100,7 @@ public void startUp(IngestJobContext context) throws IngestModuleException {
         }
 
         try {
-            aLeappFileProcessor = new LeappFileProcessor(XMLFILE, ALeappAnalyzerModuleFactory.getModuleName(), context);
+            aLeappFileProcessor = new LeappFileProcessor(XMLFILE, ALeappAnalyzerModuleFactory.getModuleName(), ALEAPP, context);
         } catch (IOException | IngestModuleException | NoCurrentCaseException ex) {
             throw new IngestModuleException(Bundle.ALeappAnalyzerIngestModule_error_ileapp_file_processor_init(), ex);
         }
diff --git a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ILeappAnalyzerIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ILeappAnalyzerIngestModule.java
index b46982dfa65225575367368164a2ce1428b48804..b4e6d3dda57fce26af022fb8ff70500222660ccc 100644
--- a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ILeappAnalyzerIngestModule.java
+++ b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ILeappAnalyzerIngestModule.java
@@ -100,7 +100,7 @@ public void startUp(IngestJobContext context) throws IngestModuleException {
         }
 
         try {
-            iLeappFileProcessor = new LeappFileProcessor(XMLFILE, ILeappAnalyzerModuleFactory.getModuleName(), context);
+            iLeappFileProcessor = new LeappFileProcessor(XMLFILE, ILeappAnalyzerModuleFactory.getModuleName(), ILEAPP, context);
         } catch (IOException | IngestModuleException | NoCurrentCaseException ex) {
             throw new IngestModuleException(Bundle.ILeappAnalyzerIngestModule_error_ileapp_file_processor_init(), ex);
         }
diff --git a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/LeappFileProcessor.java b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/LeappFileProcessor.java
index 1e4e30a94473babfcd04684eba1bc9849da6aaf8..fa2c4a857d0e5d115b9a1a10b8e52dcdef4e360d 100644
--- a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/LeappFileProcessor.java
+++ b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/LeappFileProcessor.java
@@ -145,7 +145,11 @@ boolean isRequired() {
     }
 
     private static final Logger logger = Logger.getLogger(LeappFileProcessor.class.getName());
+    private final String CUSTOM_ARTIFACTS_ATTRIBUTES_FILE = "custom-artifact-attribute-list.csv";
+    private final String ARTIFACT_ATTRIBUTE_REFERENCE_USER = "artifact-attribute-reference-user.xml";
+
     private final String xmlFile; //NON-NLS
+    private final String leapModule;
     private final String moduleName;
     private final IngestJobContext context;
 
@@ -198,7 +202,7 @@ boolean isRequired() {
 
     private final Blackboard blkBoard;
 
-    public LeappFileProcessor(String xmlFile, String moduleName, IngestJobContext context) throws IOException, IngestModuleException, NoCurrentCaseException {
+    public LeappFileProcessor(String xmlFile, String moduleName, String leapModule, IngestJobContext context) throws IOException, IngestModuleException, NoCurrentCaseException {
         this.tsvFiles = new HashMap<>();
         this.tsvFileArtifacts = new HashMap<>();
         this.tsvFileArtifactComments = new HashMap<>();
@@ -206,9 +210,11 @@ public LeappFileProcessor(String xmlFile, String moduleName, IngestJobContext co
         this.xmlFile = xmlFile;
         this.moduleName = moduleName;
         this.context = context;
+        this.leapModule = leapModule;
 
         blkBoard = Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboard();
 
+        loadCustomArtifactsAttributes(blkBoard, leapModule);
         createCustomArtifacts(blkBoard);
         configExtractor();
         loadConfigFile();
@@ -1303,6 +1309,111 @@ static List<AbstractFile> findLeappFilesToProcess(Content dataSource) {
         return leappFilesToProcess;
     }
 
+    /**
+     * Create custom artifacts that are defined in the xLeapp xml file(s).
+     *
+     */
+    private void loadCustomArtifactsAttributes(Blackboard blkBoard, String leapModule) {
+
+        for (Map.Entry<String, String> customArtifact : CUSTOM_ARTIFACT_MAP.entrySet()) {
+            String artifactName = customArtifact.getKey();
+            String artifactDescription = customArtifact.getValue();
+            createCustomAttributesArtifacts(blkBoard, "artifact", artifactName, artifactDescription, null);
+        }
+
+        File customFilePath = new File(PlatformUtil.getUserConfigDirectory() + File.separator + leapModule + '-' + CUSTOM_ARTIFACTS_ATTRIBUTES_FILE);
+        if (customFilePath.exists()) {
+            try (MappingIterator<List<String>> iterator = new CsvMapper()
+                .enable(CsvParser.Feature.WRAP_AS_ARRAY)
+                .readerFor(List.class)
+                .with(CsvSchema.emptySchema().withColumnSeparator(','))
+                .readValues(customFilePath)) {
+
+                if (iterator.hasNext()) {
+                    // Header line we can skip
+                    List<String> headerItems = iterator.next();
+                    int lineNum = 2;
+                    while (iterator.hasNext()) {
+                        List<String> columnItems = iterator.next();
+                        if (columnItems.size() > 3) {
+                            createCustomAttributesArtifacts(blkBoard, columnItems.get(0), columnItems.get(1), columnItems.get(2), columnItems.get(3));
+                        } else {
+                            createCustomAttributesArtifacts(blkBoard, columnItems.get(0), columnItems.get(1), columnItems.get(2), null);                        
+                        }
+                    }
+                }
+            } catch (IOException ex) {
+                    logger.log(Level.WARNING, String.format("Failed to read/open file %s.", customFilePath), ex);            
+            }
+        }
+    }
+    
+    /**
+     * Create custom attributes that are defined in the xLeapp xml file(s).
+     *
+     */
+    private void createCustomAttributesArtifacts(Blackboard blkBoard, String atType, String atName, String atDescription, String attrType) {
+
+        if (atType.toLowerCase().equals("artifact")) {
+            try {
+                BlackboardArtifact.Type customArtifactType = blkBoard.getOrAddArtifactType(atName.toUpperCase(), atDescription);
+            } catch (Blackboard.BlackboardException ex) {
+                logger.log(Level.WARNING, String.format("Failed to create custom artifact type %s.", atName), ex);
+            }
+            return;   
+        }            
+            
+        switch (attrType.toLowerCase()) {
+            case "json":
+            case "string":
+                try {
+                    BlackboardAttribute.Type customAttrbiuteType = blkBoard.getOrAddAttributeType(atName.toUpperCase(), BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING, atDescription);
+                } catch (Blackboard.BlackboardException ex) {
+                    logger.log(Level.WARNING, String.format("Failed to create custom attribute type %s.", atName), ex);
+                }
+                return;
+            case "integer":
+                try {
+                    BlackboardAttribute.Type customAttrbiuteType = blkBoard.getOrAddAttributeType(atName.toUpperCase(), BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING, atDescription);
+                } catch (Blackboard.BlackboardException ex) {
+                    logger.log(Level.WARNING, String.format("Failed to create custom attribute type %s.", atName), ex);
+                }
+                return;
+            case "long":
+                try {
+                    BlackboardAttribute.Type customAttrbiuteType = blkBoard.getOrAddAttributeType(atName.toUpperCase(), BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING, atDescription);
+                } catch (Blackboard.BlackboardException ex) {
+                    logger.log(Level.WARNING, String.format("Failed to create custom attribute type %s.", atName), ex);
+                }
+                return;
+            case "double":
+                try {
+                    BlackboardAttribute.Type customAttrbiuteType = blkBoard.getOrAddAttributeType(atName.toUpperCase(), BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING, atDescription);
+                } catch (Blackboard.BlackboardException ex) {
+                    logger.log(Level.WARNING, String.format("Failed to create custom attribute type %s.", atName), ex);
+                }
+                return;
+            case "byte":
+                try {
+                    BlackboardAttribute.Type customAttrbiuteType = blkBoard.getOrAddAttributeType(atName.toUpperCase(), BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.BYTE, atDescription);
+                } catch (Blackboard.BlackboardException ex) {
+                    logger.log(Level.WARNING, String.format("Failed to create custom attribute type %s.", atName), ex);
+                }
+                return;
+            case "datetime":
+                try {
+                    BlackboardAttribute.Type customAttrbiuteType = blkBoard.getOrAddAttributeType(atName.toUpperCase(), BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME, atDescription);
+                } catch (Blackboard.BlackboardException ex) {
+                    logger.log(Level.WARNING, String.format("Failed to create custom attribute type %s.", atName), ex);
+                }
+                return;
+            default:
+                logger.log(Level.WARNING, String.format("Attribute Type %s for file %s not defined.", attrType, atName)); //NON-NLS                   
+                return;
+
+        }
+    }
+
     /**
      * Create custom artifacts that are defined in the xLeapp xml file(s).
      *