Wish Secrets wallet

Magma

Expert
Licensed User
Longtime User
Many times need - fast copy a sub - that have a password on it, or some information of third users...

Wouldn't be nice to have myusernameforserver1, mypasswordforserver1 ... MyName, MyLastName - and all these be into a hashed wallet (may be sqlite) - that will be accessible from B4X IDE Menu....

So API Keys, passwords, anything that don't want be shared will be there and also reusable anytime !
 

aeric

Expert
Licensed User
Longtime User
Opss... to read, we can use the build in GetEnvironmentVariable.

but to write, we need jShell via SetEnvironmentVariables.

jShell provides the following Code Snippet:
Code Snippet: jShell:
Dim shl As Shell
shl.Initialize("shell", "your_program.exe", Array As String("arg1", "arg2"))
' Set the environment variables for this specific shell process
shl.SetEnvironmentVariables(CreateMap("MY_VARIABLE": "MyValue", "ANOTHER_VAR": "123"))
shl.Run(10000) ' Run the process with a timeout
 

Magma

Expert
Licensed User
Longtime User
i think we need some JNA (for win32) use (just javaobject)
 
Last edited:

aeric

Expert
Licensed User
Longtime User
I asked DeepSeek: how to use it for jServer during debug and release to store API Keys or Secret?

Storing API keys and secrets for a `jServer` application in B4X involves balancing convenience during debugging with security for release builds. Since `jServer` runs as a B4J app, you generally cannot use `SetEnvironmentVariables` from `jShell` to inject variables into the running server process itself (as that method is for child processes). Instead, here are the practical patterns to handle this split between debug and release modes:

1. Using the B4J `#CustomBuildAction` with a Properties File (Recommended)​

This is the most structured approach, allowing you to keep a local configuration file for debugging while injecting secure variables on the build server or production host.
  • Create a Configuration File: Create a file named `config.properties` (or `secrets.txt`) in your project's `Files` folder. For local debugging, store your keys here. Critical: Add this file to your `.gitignore` (or equivalent) to avoid committing secrets to version control.
  • Read in Code: Use `JavaObject` to load the file. You can use `File.ReadString` or the Java `Properties` class to load the key-value pairs.
  • Switch for Release:
    • In your project, go to `Project > Build Configuration`.
    • In the `#CustomBuildAction` attribute, you can execute a script before the release build.
    • This script can replace the contents of `config.properties` with the actual production secrets (often passed as environment variables in the build pipeline) or create a new file with the correct values.
    • Alternatively, you can rely on environment variables on the production server: if the file is missing in release, your code can fall back to reading `System.getenv("API_KEY")` using `JavaObject`.

2. Using JavaObject to Read System Environment Variables (Production)​

If you prefer to keep secrets out of the file system entirely and rely on the server's OS environment variables, you can read them at runtime. This is useful for cloud platforms (Heroku, AWS) where you set config vars via the dashboard.*
  • Code to Read: Use `JavaObject` to call `System.getenv()`.
    B4X:
    Dim sys As JavaObject
    sys.InitializeStatic("java.lang.System")
    Dim ApiKey As String = sys.RunMethod("getenv", Array("API_KEY"))
  • Fallback Logic: Combine this with the file method for debug. If the app is running in Debug mode (`#If DEBUG`), load from the file. In Release mode, always attempt `getenv` first.

3. Simulating "Process-Specific" Variables via Build Configuration​

While you can't inject environment variables into the existing `jServer` process using `jShell` (as `jShell` is for spawning new processes), you can achieve a similar effect by using B4J's conditional compilation symbols.
  • Define Symbols: Go to `Project > Build Configuration` and add a custom symbol like `RELEASE` for the release build.
  • Conditional Code: In your `Main` or `Server` module:
    B4X:
    #If RELEASE
        Private Secret As String = "Production_Key_Here" ' Ideally still read from env var
    #Else
        Private Secret As String = "Debug_Key"
    #End If
  • Note: If you hardcode the production key here, it is embedded in the compiled `.jar` file. It is recommended to only use this for choosing which method of retrieval (File vs. Env) to use, rather than storing the raw secret string.

4. Passing Variables When Starting the Server (JAR Execution)​

If you are starting the server from a command line or a script, you can pass the variable to the JVM and read it with `JavaObject`.
  • Start Command: `java -Dapi.key=YourSecretKey -jar YourServer.jar`
  • Read in B4X:
    B4X:
        Dim sys As JavaObject
        sys.InitializeStatic("java.lang.System")
        Dim Key As String = sys.RunMethod("getProperty", Array("api.key"))

Recommendation for Security​

  • NEVER hardcode production secrets in your B4X source code if the source code is shared or in a public repository.
  • For Debug, use a local `.properties` file that is easy to change.
  • For Release, exclusively rely on `System.getenv()` or pass them via `-D` JVM arguments. This ensures the actual secret value is never stored in the build artifact (the `.jar` file) but is injected by the hosting environment. You can implement a simple check: if the environment variable is null, log an error and stop the server to prevent it from running without credentials.
 

Magma

Expert
Licensed User
Longtime User
This is going to other level...

So need to pass them with java execution: java -Dapi.key=YourSecretKey -jar YourServer.jar

not the best way - typing all these - by the way having them unhashed / clean text into vps - that's also a problem (not a big - but a problem too)
 

Cableguy

Expert
Licensed User
Longtime User
Do you honestly think hardcoding (an environment variable IS an hardcoded value) sensible info is a good idea and/or practice?
 

Magma

Expert
Licensed User
Longtime User
we are trying to find the best way, as you can see...

which way do you think is the best ?

a scenario:
* You have a small example using an api... saying for example: api_key="XXxxxxxxx"
* You need to zip and share it... ?
without manual replacement you will share the api key...

If it is on environment or into IDE and special variables (first said) - will just share $apikey$ for example without the real api key
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…