Repository: kestra-io/kestra
Issue: Secret not in base64 exit the instance
Labels: bug

### Expected Behavior

_No response_

### Actual Behaviour

When putting a SECRET not in base64 the Kestra instance exit with this error :

```
2023-07-05 07:59:30,436 INFO  standalone   io.kestra.cli.AbstractCommand Starting Kestra with environments [cli]
2023-07-05 07:59:30,618 INFO  standalone   io.kestra.cli.AbstractCommand Server Running: http://d55ea905c356:8080, Management server on port http://d55ea905c356:8081/health
2023-07-05 07:59:31,326 ERROR standalone-runner_2 .c.u.ThreadUncaughtExceptionHandlers Caught an exception in Thread[standalone-runner_2,5,main]. Shutting down.
io.micronaut.context.exceptions.DependencyInjectionException: Error instantiating bean of type  [io.kestra.core.runners.pebble.functions.SecretFunction]

Message: Error invoking method: postConstruct
Path Taken: new Extension() --> Extension.secretFunction --> SecretFunction.secretService
        at io.micronaut.context.AbstractInitializableBeanDefinition.invokeMethodWithReflection(AbstractInitializableBeanDefinition.java:957)
        at io.kestra.core.secret.$SecretService$Definition.initialize(Unknown Source)
        at io.kestra.core.secret.$SecretService$Definition.build(Unknown Source)
        at io.micronaut.context.DefaultBeanContext.resolveByBeanFactory(DefaultBeanContext.java:2354)
        at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:2305)
        at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:2251)
        at io.micronaut.context.DefaultBeanContext.createRegistration(DefaultBeanContext.java:3016)
        at io.micronaut.context.SingletonScope.getOrCreate(SingletonScope.java:80)
        at io.micronaut.context.DefaultBeanContext.findOrCreateSingletonBeanRegistration(DefaultBeanContext.java:2918)
        at io.micronaut.context.DefaultBeanContext.resolveBeanRegistration(DefaultBeanContext.java:2879)
        at io.micronaut.context.DefaultBeanContext.resolveBeanRegistration(DefaultBeanContext.java:2800)
        at io.micronaut.context.DefaultBeanContext.getBean(DefaultBeanContext.java:1617)
        at io.micronaut.context.AbstractBeanResolutionContext.getBean(AbstractBeanResolutionContext.java:66)
        at io.micronaut.context.AbstractInitializableBeanDefinition.resolveBean(AbstractInitializableBeanDefinition.java:2065)
        at io.micronaut.context.AbstractInitializableBeanDefinition.getBeanForField(AbstractInitializableBeanDefinition.java:1603)
        at io.kestra.core.runners.pebble.functions.$SecretFunction$Definition.injectBean(Unknown Source)
        at io.kestra.core.runners.pebble.functions.$SecretFunction$Definition.build(Unknown Source)
        at io.micronaut.context.DefaultBeanContext.resolveByBeanFactory(DefaultBeanContext.java:2354)
        at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:2305)
        at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:2251)
        at io.micronaut.context.DefaultBeanContext.createRegistration(DefaultBeanContext.java:3016)
        at io.micronaut.context.SingletonScope.getOrCreate(SingletonScope.java:80)
        at io.micronaut.context.DefaultBeanContext.findOrCreateSingletonBeanRegistration(DefaultBeanContext.java:2918)
        at io.micronaut.context.DefaultBeanContext.resolveBeanRegistration(DefaultBeanContext.java:2879)
        at io.micronaut.context.DefaultBeanContext.resolveBeanRegistration(DefaultBeanContext.java:2800)
        at io.micronaut.context.DefaultBeanContext.getBean(DefaultBeanContext.java:1617)
        at io.micronaut.context.AbstractBeanResolutionContext.getBean(AbstractBeanResolutionContext.java:66)
        at io.micronaut.context.AbstractInitializableBeanDefinition.resolveBean(AbstractInitializableBeanDefinition.java:2065)
        at io.micronaut.context.AbstractInitializableBeanDefinition.getBeanForField(AbstractInitializableBeanDefinition.java:1603)
        at io.kestra.core.runners.pebble.$Extension$Definition.injectBean(Unknown Source)
        at io.kestra.core.runners.pebble.$Extension$Definition.build(Unknown Source)
        at io.micronaut.context.DefaultBeanContext.resolveByBeanFactory(DefaultBeanContext.java:2354)
        at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:2305)
        at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:2251)
        at io.micronaut.context.DefaultBeanContext.createRegistration(DefaultBeanContext.java:3016)
        at io.micronaut.context.SingletonScope.getOrCreate(SingletonScope.java:80)
        at io.micronaut.context.DefaultBeanContext.findOrCreateSingletonBeanRegistration(DefaultBeanContext.java:2918)
        at io.micronaut.context.DefaultBeanContext.resolveBeanRegistration(DefaultBeanContext.java:2879)
        at io.micronaut.context.DefaultBeanContext.resolveBeanRegistration(DefaultBeanContext.java:2853)
        at io.micronaut.context.DefaultBeanContext.addCandidateToList(DefaultBeanContext.java:3511)
        at io.micronaut.context.DefaultBeanContext.resolveBeanRegistrations(DefaultBeanContext.java:3457)
        at io.micronaut.context.DefaultBeanContext.getBeanRegistrations(DefaultBeanContext.java:3427)
        at io.micronaut.context.DefaultBeanContext.getBeansOfType(DefaultBeanContext.java:1381)
        at io.micronaut.context.DefaultBeanContext.getBeansOfType(DefaultBeanContext.java:1364)
        at io.micronaut.context.DefaultBeanContext.getBeansOfType(DefaultBeanContext.java:888)
        at io.kestra.core.runners.VariableRenderer.<init>(VariableRenderer.java:85)
        at io.kestra.core.runners.$VariableRenderer$Definition.build(Unknown Source)
        at io.micronaut.context.DefaultBeanContext.resolveByBeanFactory(DefaultBeanContext.java:2354)
        at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:2305)
        at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:2251)
        at io.micronaut.context.DefaultBeanContext.createRegistration(DefaultBeanContext.java:3016)
        at io.micronaut.context.SingletonScope.getOrCreate(SingletonScope.java:80)
        at io.micronaut.context.DefaultBeanContext.findOrCreateSingletonBeanRegistration(DefaultBeanContext.java:2918)
        at io.micronaut.context.DefaultBeanContext.resolveBeanRegistration(DefaultBeanContext.java:2879)
        at io.micronaut.context.DefaultBeanContext.resolveBeanRegistration(DefaultBeanContext.java:2800)
        at io.micronaut.context.DefaultBeanContext.findBean(DefaultBeanContext.java:1680)
        at io.micronaut.context.DefaultBeanContext.findBean(DefaultBeanContext.java:1655)
        at io.micronaut.context.DefaultBeanContext.findBean(DefaultBeanContext.java:878)
        at io.micronaut.context.BeanLocator.findBean(BeanLocator.java:291)
        at io.kestra.core.runners.RunContext.initBean(RunContext.java:117)
        at io.kestra.core.runners.RunContext.<init>(RunContext.java:91)
        at io.kestra.core.runners.RunContextFactory.of(RunContextFactory.java:30)
        at io.kestra.core.schedulers.AbstractScheduler.lambda$computeSchedulable$8(AbstractScheduler.java:192)
        at java.base/java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
        at java.base/java.util.stream.ReferencePipeline$2$1.accept(Unknown Source)
        at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
        at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source)
        at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source)
        at java.base/java.util.stream.ReferencePipeline.forEach(Unknown Source)
        at java.base/java.util.stream.ReferencePipeline$7$1.accept(Unknown Source)
        at java.base/java.util.stream.ReferencePipeline$2$1.accept(Unknown Source)
        at java.base/java.util.stream.ReferencePipeline$2$1.accept(Unknown Source)
        at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(Unknown Source)
        at java.base/java.util.stream.ReferencePipeline.toArray(Unknown Source)
        at java.base/java.util.stream.ReferencePipeline.toArray(Unknown Source)
        at java.base/java.util.stream.ReferencePipeline.toList(Unknown Source)
        at io.kestra.core.schedulers.AbstractScheduler.computeSchedulable(AbstractScheduler.java:202)
        at io.kestra.core.runners.FlowListeners.listen(FlowListeners.java:132)
        at io.kestra.core.schedulers.AbstractScheduler.run(AbstractScheduler.java:108)
        at io.kestra.jdbc.runner.JdbcScheduler.run(JdbcScheduler.java:52)
        at io.micrometer.core.instrument.internal.TimedRunnable.run(TimedRunnable.java:49)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.base/java.lang.Thread.run(Unknown Source)
Caused by: io.micronaut.core.reflect.exception.InvocationException: Exception occurred invoking method [private void io.kestra.core.secret.SecretService.postConstruct()]: null
        at io.micronaut.core.reflect.ReflectionUtils.invokeMethod(ReflectionUtils.java:198)
        at io.micronaut.context.AbstractInitializableBeanDefinition.invokeMethodWithReflection(AbstractInitializableBeanDefinition.java:952)
        ... 90 common frames omitted
Caused by: java.lang.reflect.InvocationTargetException: null
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.base/java.lang.reflect.Method.invoke(Unknown Source)
        at io.micronaut.core.reflect.ReflectionUtils.invokeMethod(ReflectionUtils.java:194)
        ... 91 common frames omitted
Caused by: java.lang.IllegalArgumentException: Last unit does not have enough valid bits
        at java.base/java.util.Base64$Decoder.decode0(Unknown Source)
        at java.base/java.util.Base64$Decoder.decode(Unknown Source)
        at java.base/java.util.Base64$Decoder.decode(Unknown Source)
        at io.kestra.core.secret.SecretService.lambda$postConstruct$2(SecretService.java:22)
        at java.base/java.util.stream.Collectors.lambda$uniqKeysMapAccumulator$1(Unknown Source)
        at java.base/java.util.stream.ReduceOps$3ReducingSink.accept(Unknown Source)
        at java.base/java.util.stream.ReferencePipeline$2$1.accept(Unknown Source)
        at java.base/java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet.lambda$entryConsumer$0(Unknown Source)
        at java.base/java.util.Iterator.forEachRemaining(Unknown Source)
        at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Unknown Source)
        at java.base/java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet$UnmodifiableEntrySetSpliterator.forEachRemaining(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
        at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source)
        at java.base/java.util.stream.ReferencePipeline.collect(Unknown Source)
        at io.kestra.core.secret.SecretService.postConstruct(SecretService.java:20)
```
        


### Steps To Reproduce

_No response_

### Environment Information

- Kestra Version:
- Operating System (OS / Docker / Kubernetes):
- Java Version (If not docker):


### Example flow

_No response_

Issue comments:

Pull request review comments:
We usually use `@Slf4j` at the class level.
At least add it as a constant it's a best practice even if only used there.

Patch that resolved the issue:
diff --git a/build.gradle b/build.gradle
index 6387373985..cfe5455df3 100644
--- a/build.gradle
+++ b/build.gradle
@@ -170,6 +170,7 @@ subprojects {
         systemProperty 'user.country', 'US'
 
         environment 'SECRETS_MY_SECRET', "{\"secretKey\":\"secretValue\"}".bytes.encodeBase64().toString()
+        environment 'SECRETS_NON_B64_SECRET', "some secret value"
     }
 
     testlogger {
diff --git a/core/src/main/java/io/kestra/core/secret/SecretService.java b/core/src/main/java/io/kestra/core/secret/SecretService.java
index 13ba7f97aa..05b9e859e8 100644
--- a/core/src/main/java/io/kestra/core/secret/SecretService.java
+++ b/core/src/main/java/io/kestra/core/secret/SecretService.java
@@ -2,6 +2,9 @@
 
 import io.kestra.core.exceptions.IllegalVariableEvaluationException;
 import jakarta.inject.Singleton;
+import lombok.extern.slf4j.Slf4j;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import javax.annotation.PostConstruct;
 import java.io.IOException;
@@ -11,16 +14,26 @@
 import java.util.stream.Collectors;
 
 @Singleton
+@Slf4j
 public class SecretService {
     private static final String SECRET_PREFIX = "SECRETS_";
     private Map<String, String> decodedSecrets;
 
     @PostConstruct
     private void postConstruct() {
-        decodedSecrets = System.getenv().entrySet().stream().filter(entry -> entry.getKey().startsWith(SECRET_PREFIX)).collect(Collectors.toMap(
-            entry -> entry.getKey().substring(SECRET_PREFIX.length()).toUpperCase(),
-            entry -> new String(Base64.getDecoder().decode(entry.getValue()))
-        ));
+        decodedSecrets = System.getenv().entrySet().stream()
+            .filter(entry -> entry.getKey().startsWith(SECRET_PREFIX))
+            .<Map.Entry<String, String>>mapMulti((entry, consumer) -> {
+                try {
+                    consumer.accept(Map.entry(entry.getKey(), new String(Base64.getDecoder().decode(entry.getValue()))));
+                } catch (Exception e) {
+                    log.error("Could not decode secret '{}', make sure it is Base64-encoded", entry.getKey(), e);
+                }
+            })
+            .collect(Collectors.toMap(
+                entry -> entry.getKey().substring(SECRET_PREFIX.length()).toUpperCase(),
+                Map.Entry::getValue
+            ));
     }
 
     public String findSecret(String namespace, String key) throws IOException, IllegalVariableEvaluationException {


Test patch: