diff --git a/duniter4j-client/pom.xml b/duniter4j-client/pom.xml
index db9fed8e06195fc138e0f3cc7aca76a64d498db1..e470589df59c3e3ebcfd79df6e60b245e906e741 100644
--- a/duniter4j-client/pom.xml
+++ b/duniter4j-client/pom.xml
@@ -86,6 +86,14 @@
             <artifactId>jansi</artifactId>
             <version>${jansiVersion}</version>
         </dependency>
+
+        <!-- spring (need to extends configuration) -->
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-core</artifactId>
+            <version>${spring.version}</version>
+            <scope>provided</scope>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/duniter4j-core-client/pom.xml b/duniter4j-core-client/pom.xml
index 75a4c1645d819383c9cef2607fb19c7f3c5efdad..1f7a0c205dd1555998976e73d7dd5d4701b268ae 100644
--- a/duniter4j-core-client/pom.xml
+++ b/duniter4j-core-client/pom.xml
@@ -91,6 +91,14 @@
       <artifactId>jackson-databind</artifactId>
     </dependency>
 
+    <!-- Spring (need for spring compatibility) -->
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>spring-core</artifactId>
+      <version>${spring.version}</version>
+      <scope>provided</scope>
+    </dependency>
+
     <!-- Unit test -->
     <dependency>
       <groupId>junit</groupId>
diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/config/Configuration.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/config/Configuration.java
index d98646f498a1846ea0202e36fbbc332a9d4b90ed..fde296ab11b891e8c8f982ad188836e3d2778030 100644
--- a/duniter4j-core-client/src/main/java/org/duniter/core/client/config/Configuration.java
+++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/config/Configuration.java
@@ -25,20 +25,19 @@ package org.duniter.core.client.config;
 
 import com.google.common.base.Charsets;
 import lombok.extern.slf4j.Slf4j;
+import org.duniter.core.client.util.spring.ConfigurableEnvironments;
 import org.duniter.core.exception.TechnicalException;
-import org.nuiton.config.ApplicationConfig;
-import org.nuiton.config.ApplicationConfigHelper;
-import org.nuiton.config.ApplicationConfigProvider;
-import org.nuiton.config.ArgumentsParserException;
+import org.nuiton.config.*;
 import org.nuiton.version.Version;
 import org.nuiton.version.VersionBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.springframework.core.env.ConfigurableEnvironment;
 
 import java.io.File;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.util.Arrays;
 import java.util.Locale;
+import java.util.Properties;
 import java.util.Set;
 
 import static org.nuiton.i18n.I18n.t;
@@ -83,28 +82,35 @@ public class Configuration  {
         super();
         this.applicationConfig = applicationConfig;
         this.optionKeyToNotSave = null;
-
         // Override application version
         initVersion(applicationConfig);
     }
 
-    public Configuration(String file, String... args) {
+    public Configuration(ConfigurableEnvironment env,
+                                String... args) {
+        this(env, "application.fake.properties", args);
+    }
+
+    public Configuration(String file,
+                         String... args) {
+        this(null, file, args);
+    }
+
+    protected Configuration(ConfigurableEnvironment env,
+                         String file,
+                         String... args) {
         super();
-        this.applicationConfig = new ApplicationConfig();
+        // load all default options
+        Set<ApplicationConfigProvider> providers = getProviders();
+        Properties defaults = getDefaults(providers, env);
+
+        // Create Nuiton config instance
+        this.applicationConfig = new ApplicationConfig(ApplicationConfigInit.forAllScopesWithout(
+            ApplicationConfigScope.HOME
+        ).setDefaults(defaults));
         this.applicationConfig.setEncoding(Charsets.UTF_8.name());
         this.applicationConfig.setConfigFileName(file);
 
-        // get allOfToList config providers
-        Set<ApplicationConfigProvider> providers =
-                ApplicationConfigHelper.getProviders(null,
-                        null,
-                        null,
-                        true);
-
-        // load allOfToList default options
-        ApplicationConfigHelper.loadAllDefaultOption(applicationConfig,
-                providers);
-
         // Load actions
         for (ApplicationConfigProvider provider : providers) {
             applicationConfig.loadActions(provider.getActions());
@@ -132,30 +138,35 @@ public class Configuration  {
             throw new TechnicalException(t("duniter4j.config.parse.error"), e);
         }
 
-        // TODO Review this, this is very dirty to do this...
-        File appBasedir = applicationConfig.getOptionAsFile(
-                ConfigurationOption.BASEDIR.getKey());
+        // Prepare base dir
+        fixBaseDir(applicationConfig);
+    }
 
-        if (appBasedir == null) {
-            appBasedir = new File("");
-        }
-        if (!appBasedir.isAbsolute()) {
-            appBasedir = new File(appBasedir.getAbsolutePath());
-        }
-        if (appBasedir.getName().equals("..")) {
-            appBasedir = appBasedir.getParentFile().getParentFile();
-        }
-        if (appBasedir.getName().equals(".")) {
-            appBasedir = appBasedir.getParentFile();
-        }
-        if (log.isInfoEnabled()) {
-            log.info("Application basedir: " + appBasedir);
+    protected static Set<ApplicationConfigProvider> getProviders() {
+        // get allOfToList config providers
+        return ApplicationConfigHelper.getProviders(null,
+                        null,
+                        null,
+                        true);
+    }
+
+    protected Properties getDefaults(Set<ApplicationConfigProvider> providers, ConfigurableEnvironment env) {
+
+        // Populate defaults from providers
+        final Properties defaults = new Properties();
+        providers.forEach(provider -> Arrays.stream(provider.getOptions())
+            .filter(configOptionDef -> configOptionDef.getDefaultValue() != null)
+            .forEach(configOptionDef -> defaults.setProperty(configOptionDef.getKey(), configOptionDef.getDefaultValue())));
+
+        // Set options from env if provided
+        if (env != null) {
+            return ConfigurableEnvironments.readProperties(env, defaults);
         }
-        applicationConfig.setOption(
-                ConfigurationOption.BASEDIR.getKey(),
-                appBasedir.getAbsolutePath());
+
+        return defaults;
     }
 
+
     /**
      * Override the version default option, from the MANIFEST implementation version (if any)
      * @param applicationConfig
@@ -184,7 +195,32 @@ public class Configuration  {
         applicationConfig.addAlias("-c", "--option", ConfigurationOption.NODE_CURRENCY.getKey());
         applicationConfig.addAlias("--salt", "--option", ConfigurationOption.USER_SALT.getKey());
         applicationConfig.addAlias("--passwd", "--option", ConfigurationOption.USER_PASSWD.getKey());
-     }
+    }
+
+    protected void fixBaseDir(ApplicationConfig applicationConfig) {
+        // TODO Review this, this is very dirty to do this...
+        File appBasedir = applicationConfig.getOptionAsFile(
+                ConfigurationOption.BASEDIR.getKey());
+
+        if (appBasedir == null) {
+            appBasedir = new File("");
+        }
+        if (!appBasedir.isAbsolute()) {
+            appBasedir = new File(appBasedir.getAbsolutePath());
+        }
+        if (appBasedir.getName().equals("..")) {
+            appBasedir = appBasedir.getParentFile().getParentFile();
+        }
+        if (appBasedir.getName().equals(".")) {
+            appBasedir = appBasedir.getParentFile();
+        }
+        if (log.isInfoEnabled()) {
+            log.info("Application basedir: " + appBasedir);
+        }
+        applicationConfig.setOption(
+                ConfigurationOption.BASEDIR.getKey(),
+                appBasedir.getAbsolutePath());
+    }
 
     public File getConfigFile() {
         if (configFile == null) {
diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/config/ConfigurationOption.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/config/ConfigurationOption.java
index ea5d6ef0c1796491c27a6047175b9848bbc41aa3..35b44db712cad0ccffb10eb2e14582a98ec8a944 100644
--- a/duniter4j-core-client/src/main/java/org/duniter/core/client/config/ConfigurationOption.java
+++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/config/ConfigurationOption.java
@@ -44,11 +44,22 @@ public enum ConfigurationOption implements ConfigOptionDef {
     // ------------------------------------------------------------------------//
     // -- READ-ONLY OPTIONS ---------------------------------------------------//
     // ------------------------------------------------------------------------//
+    APP_NAME(
+            "duniter4j.name",
+            n("duniter4j.config.option.app.name.description"),
+            "duniter4j",
+            File.class),
+
+    VERSION(
+            "duniter4j.version",
+            n("duniter4j.config.option.version.description"),
+            "1.0.0",
+            Version.class),
 
     BASEDIR(
             "duniter4j.basedir",
             n("duniter4j.config.option.basedir.description"),
-            "${user.home}/.config/duniter4j",
+            "${user.home}/.config/${duniter4j.name}",
             File.class),
 
     DATA_DIRECTORY(
@@ -75,12 +86,6 @@ public enum ConfigurationOption implements ConfigOptionDef {
             "${duniter4j.data.directory}/cache",
             File.class),
 
-    VERSION(
-            "duniter4j.version",
-            n("duniter4j.config.option.version.description"),
-            "1.0",
-            Version.class),
-
     SITE_URL(
             "duniter4j.site.url",
             n("duniter4j.config.option.site.url.description"),
diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/ModelUtils.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/ModelUtils.java
index e4106f051c3f194de1da8ec16bf0b0a89f006b73..f73c8c029574bfdfa6babc4a283216b5b3934392 100644
--- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/ModelUtils.java
+++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/ModelUtils.java
@@ -126,6 +126,7 @@ public class ModelUtils {
         if (pubkey == null || pubkey.length() < 6) {
             return pubkey;
         }
+        // TODO: use new pubkey minify
         return pubkey.substring(0, 8);
     }
 
diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/elasticsearch/UserProfile.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/elasticsearch/UserProfile.java
index dca4bc89951f1e314584c0695a64d3a6998863b2..76d46e79c08525549a849aa1d72433e04ae70847 100644
--- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/elasticsearch/UserProfile.java
+++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/elasticsearch/UserProfile.java
@@ -22,61 +22,20 @@ package org.duniter.core.client.model.elasticsearch;
  * #L%
  */
 
+import lombok.Data;
+import lombok.experimental.FieldNameConstants;
+
 /**
  * Created by blavenie on 01/03/16.
  */
+@Data
+@FieldNameConstants
 public class UserProfile extends Record {
 
-    public static final String PROPERTY_TITLE = "title";
-    public static final String PROPERTY_DESCRIPTION="description";
-    public static final String PROPERTY_ADDRESS="address";
-    public static final String PROPERTY_CITY="city";
-    public static final String PROPERTY_EMAIL="email";
-    public static final String PROPERTY_LOCALE="locale";
-
     private String title;
     private String description;
     private String address;
+    private String city;
     private String email;
     private String locale;
-
-    public String getTitle() {
-        return title;
-    }
-
-    public void setTitle(String title) {
-        this.title = title;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-
-    public void setDescription(String description) {
-        this.description = description;
-    }
-
-    public String getEmail() {
-        return email;
-    }
-
-    public void setEmail(String email) {
-        this.email = email;
-    }
-
-    public String getLocale() {
-        return locale;
-    }
-
-    public void setLocale(String locale) {
-        this.locale = locale;
-    }
-
-    public String getAddress() {
-        return address;
-    }
-
-    public void setAddress(String address) {
-        this.address = address;
-    }
 }
diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/util/spring/ConfigurableEnvironments.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/util/spring/ConfigurableEnvironments.java
new file mode 100644
index 0000000000000000000000000000000000000000..8422c09e4471d847910eb7f0b4533b814213b6c7
--- /dev/null
+++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/util/spring/ConfigurableEnvironments.java
@@ -0,0 +1,60 @@
+package org.duniter.core.client.util.spring;
+
+import com.google.common.collect.Lists;
+import lombok.NonNull;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.core.env.ConfigurableEnvironment;
+import org.springframework.core.env.MapPropertySource;
+
+import java.util.List;
+import java.util.Properties;
+import java.util.stream.Collectors;
+
+@Slf4j
+public class ConfigurableEnvironments {
+
+    protected ConfigurableEnvironments() {
+        // Helper class
+    }
+
+    public static Properties readProperties(@NonNull ConfigurableEnvironment env, Properties defaultOptions) {
+        boolean debug = log.isDebugEnabled();
+        List<MapPropertySource> sources = env.getPropertySources().stream()
+            .filter(source -> source instanceof MapPropertySource)
+            .map(source -> (MapPropertySource)source).collect(Collectors.toList());
+        final Properties target = new Properties(defaultOptions);
+
+        if (debug) log.debug("-- Reading environment properties... ---\n");
+        for (MapPropertySource source: Lists.reverse(sources)) {
+
+            if (debug) log.debug("Processing source {} ...", source.getName());
+
+            // Cascade properties (keep original order)
+            for (String key: source.getPropertyNames()) {
+                Object value = source.getProperty(key);
+                if (value != null) {
+                    if (debug) {
+                        if (target.containsKey(key)) log.debug(" {}={} /!\\ Overriding previous value", key, value);
+                        else log.debug(" {}={}", key, value);
+                    }
+                    target.setProperty(key, value.toString());
+                }
+            }
+        }
+
+        // DEBUG
+        if (debug) {
+            log.debug("-- Environment properties - final summary ---\n");
+            target.keySet()
+                .stream()
+                .map(Object::toString)
+                .sorted()
+                .forEach(key -> {
+                    Object value = target.getProperty(key);
+                    log.debug(" {}={}", key, value);
+                });
+        }
+
+        return target;
+    }
+}
diff --git a/duniter4j-core-client/src/main/resources/i18n/duniter4j-core-client_en_GB.properties b/duniter4j-core-client/src/main/resources/i18n/duniter4j-core-client_en_GB.properties
index 6d8cde9d3611d881401ed1628a7c7b393b99313c..84c6ceffe76cd7d9ffbc716fd494779df126fc40 100644
--- a/duniter4j-core-client/src/main/resources/i18n/duniter4j-core-client_en_GB.properties
+++ b/duniter4j-core-client/src/main/resources/i18n/duniter4j-core-client_en_GB.properties
@@ -7,6 +7,7 @@ duniter4j.client.core.timeout=
 duniter4j.client.notFound=Resource non found [%s]
 duniter4j.client.status=Http request error\: %s
 duniter4j.config=
+duniter4j.config.option.app.name.description=
 duniter4j.config.option.basedir.description=
 duniter4j.config.option.cache.directory.description=
 duniter4j.config.option.data.directory.description=
diff --git a/duniter4j-core-client/src/main/resources/i18n/duniter4j-core-client_fr_FR.properties b/duniter4j-core-client/src/main/resources/i18n/duniter4j-core-client_fr_FR.properties
index 291be52ea0f81e0a0ad8acc937fffc59b0c74dcb..470918a3bb70c1417bafd256fc59467bf588eef0 100644
--- a/duniter4j-core-client/src/main/resources/i18n/duniter4j-core-client_fr_FR.properties
+++ b/duniter4j-core-client/src/main/resources/i18n/duniter4j-core-client_fr_FR.properties
@@ -7,6 +7,7 @@ duniter4j.client.core.timeout=Délai d'attente de la requête dépassé
 duniter4j.client.notFound=Ressource non trouvée [%s]
 duniter4j.client.status=Echec de requete HTTP [%s] \: %s
 duniter4j.config=Options de configuration Duniter4j \:\: client
+duniter4j.config.option.app.name.description=
 duniter4j.config.option.basedir.description=Répertoire de travail de l'application
 duniter4j.config.option.cache.directory.description=Répertoire pour le cache applicatif
 duniter4j.config.option.data.directory.description=Répertoire de stockage des données
diff --git a/pom.xml b/pom.xml
index 417cac1c3216bdfd056af7c3106f3d1e8b99dd48..c56c69f287084f773e38a649a1cb7e2f86365697 100644
--- a/pom.xml
+++ b/pom.xml
@@ -36,12 +36,12 @@
     <lombok.version>1.18.20</lombok.version>
     <httpclient.version>4.5.10</httpclient.version>
 
-    <nuitonConfigVersion>3.0</nuitonConfigVersion>
+    <nuitonConfigVersion>3.4</nuitonConfigVersion>
     <nuitonVersionVersion>1.0-rc-2</nuitonVersionVersion>
     <nuitonI18nVersion>3.6.3</nuitonI18nVersion>
 
     <!-- UI versions -->
-    <spring.version>4.2.1.RELEASE</spring.version>
+    <spring.version>5.3.5</spring.version>
     <aspectj.version>1.8.7</aspectj.version>
 
     <!-- Unit test -->