# How to Best Store and Access Credentials in Julia?

**URL:** https://discourse.julialang.org/t/how-to-best-store-and-access-credentials-in-julia/54997
**Category:** General Usage
**Tags:** question, first-steps, data, security
**Created:** [February 10, 2021, 2:31pm UTC](https://discourse.julialang.org/t/how-to-best-store-and-access-credentials-in-julia/54997 "2021-02-10T14:31:20Z")
**Posts on this page:** 14
**Page:** 1

<div class="post-metadata">

### Author: ![TheCedarPrince](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thecedarprince/32/17323_2.png) [@TheCedarPrince](https://discourse.julialang.org/u/TheCedarPrince)
#### Post date: [February 10, 2021, 2:31pm UTC](https://discourse.julialang.org/t/how-to-best-store-and-access-credentials-in-julia/54997/1 "2021-02-10T14:31:20Z")

</div>

Hi all,

I was recently stumped by something:

Suppose I have some credentials I need to store to access a SQL DB. How should I best store these credentials for Julia to easily access?

My current pattern is to use a combo of `DataFrames.jl` and `CSV.jl` like so:

1. Create a `credentials.csv` like so:

```julia
user pass
lama 1234

```

1. Using `CSV.jl` and `DataFrames.jl`, read it into a DataFrame:

```julia
using CSV
using DataFrames

f = CSV.File("credentials.csv") |> DataFrame;

```

1. Parse and assign variables:

```julia
USERNAME = f[1, :user]
PASSWORD = f[1, :pass]

```

Is there a better way of doing this? Any better suggestions? Thank you!

~ tcp 🌳

---

<div class="post-metadata">

### Author: ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)
#### Post date: [February 10, 2021, 2:35pm UTC](https://discourse.julialang.org/t/how-to-best-store-and-access-credentials-in-julia/54997/2 "2021-02-10T14:35:45Z")

</div>

Usually environment variables are used for this, perhaps with an `.env` file that you source:

```julia
export DB_USER=fredrik
export DB_PASSWORD= *******

```

and then access as

```julia
db_user = ENV["DB_USER"]
db_password = ENV["DB_PASSWORD"]

```

Edit: Looks like Discourse automatically edits the post and insert `*`s instead of my password. I typed `DB_PASSWORD=hunter2` but it was edited.

---

<div class="post-metadata">

### Author: ![StatisticalMouse](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/statisticalmouse/32/43370_2.png) [@StatisticalMouse](https://discourse.julialang.org/u/StatisticalMouse)
#### Post date: [February 10, 2021, 2:45pm UTC](https://discourse.julialang.org/t/how-to-best-store-and-access-credentials-in-julia/54997/3 "2021-02-10T14:45:58Z")

</div>

I believe the correct answer is: it depends (on the platform).  
For example if you run in GCP: [Secret Manager &nbsp;|&nbsp; Google Cloud](https://cloud.google.com/secret-manager)

---

<div class="post-metadata">

### Author: ![Tero\_Frondelius](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tero_frondelius/32/7629_2.png) [@Tero\_Frondelius](https://discourse.julialang.org/u/Tero_Frondelius)
#### Post date: [February 10, 2021, 2:46pm UTC](https://discourse.julialang.org/t/how-to-best-store-and-access-credentials-in-julia/54997/4 "2021-02-10T14:46:45Z")

</div>

Maybe, one could make a function that would interactively ask the credentials if those env-variables are empty.

Does anyone know easy cyber secure solution?

---

<div class="post-metadata">

### Author: ![TheCedarPrince](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thecedarprince/32/17323_2.png) [@TheCedarPrince](https://discourse.julialang.org/u/TheCedarPrince)
#### Post date: [February 10, 2021, 3:09pm UTC](https://discourse.julialang.org/t/how-to-best-store-and-access-credentials-in-julia/54997/5 "2021-02-10T15:09:33Z")

</div>

I really like this solution! Thanks @fredrikekre - when you say source, how would I do that? Would it be as simple as `include("credentials.env")` or how do you imagine it?

I like the function idea @Tero_Frondelius - I will prototype something and post back later.

---

<div class="post-metadata">

### Author: ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)
#### Post date: [February 10, 2021, 3:12pm UTC](https://discourse.julialang.org/t/how-to-best-store-and-access-credentials-in-julia/54997/6 "2021-02-10T15:12:11Z")

</div>

> [@TheCedarPrince](#):
>
> when you say source, how would I do that?

I was referring to the shell command [`source`](https://www.gnu.org/software/bash/manual/bash.html#index-_002e):

```shell
$ cat .env 
export DB_USER=fredrik

$ source .env 

$ julia -E 'ENV["DB_USER"]'
"fredrik"

```

---

<div class="post-metadata">

### Author: ![TheCedarPrince](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thecedarprince/32/17323_2.png) [@TheCedarPrince](https://discourse.julialang.org/u/TheCedarPrince)
#### Post date: [February 10, 2021, 3:15pm UTC](https://discourse.julialang.org/t/how-to-best-store-and-access-credentials-in-julia/54997/7 "2021-02-10T15:15:12Z")

</div>

Oh gotcha! Do you happen to know of an analogous method I could do this for within Julia?

---

<div class="post-metadata">

### Author: ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)
#### Post date: [February 10, 2021, 3:37pm UTC](https://discourse.julialang.org/t/how-to-best-store-and-access-credentials-in-julia/54997/8 "2021-02-10T15:37:53Z")

</div>

You can just save credentials in a Julia file and add it with `include`

---

<div class="post-metadata">

### Author: ![johnh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnh/32/3615_2.png) [@johnh](https://discourse.julialang.org/u/johnh)
#### Post date: [February 10, 2021, 3:54pm UTC](https://discourse.julialang.org/t/how-to-best-store-and-access-credentials-in-julia/54997/9 "2021-02-10T15:54:20Z")

</div>

Do not save credentials in a file within your source tree. I an no expert.  
If you upload to Github/Gitlab you have a security breach - I believe Github scans repositories for private keys which are uploaded in files.  
A recent big security problem was triggered by keeping credentials in a file.

---

<div class="post-metadata">

### Author: ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)
#### Post date: [February 10, 2021, 5:41pm UTC](https://discourse.julialang.org/t/how-to-best-store-and-access-credentials-in-julia/54997/10 "2021-02-10T17:41:39Z")

</div>

That’s true, so I usually generate two files: secrets.jl and secrets\_template.jl You put secrets.jl in .gitignore and write all necessary constants in secrets\_template.jl without values of course. This way you always know how to deploy your script.

---

<div class="post-metadata">

### Author: ![TheCedarPrince](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thecedarprince/32/17323_2.png) [@TheCedarPrince](https://discourse.julialang.org/u/TheCedarPrince)
#### Post date: [February 10, 2021, 6:14pm UTC](https://discourse.julialang.org/t/how-to-best-store-and-access-credentials-in-julia/54997/11 "2021-02-10T18:14:45Z")

</div>

@Skoffer - how do you happen to generate these two files? I ideally would like to take in user input, write that to a Julia file that could then be ran and export these user defined values whenever they run a package I am creating.

---

<div class="post-metadata">

### Author: ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)
#### Post date: [February 11, 2021, 10:58am UTC](https://discourse.julialang.org/t/how-to-best-store-and-access-credentials-in-julia/54997/12 "2021-02-11T10:58:22Z")

</div>

It looks like you have a slightly different scenario in mind. You can see an example of what I said for example [here](https://github.com/Arkoniak/SOtoZulip.jl#configuration). I.e. it is assumed, that the user should do the following

1. Clone your application
2. Copy `secrets_template.jl` to `secrets.jl`
3. Edit file `secrets.jl` by hand.

Of course, it means, that the user is advanced enough, to understand what is `.gitignore`, how relative paths are working and can without errors edit julia files. If it is a problem, then I would recommend to use environment variables, it is much easier to explain and it is less error prone.

You can try to find middle ground, by using `.env` file, so less advanced users can just setup environment variables on os level, and more advanced users can write all values in `.env` file and get a more flexible approach. To avoid issues with file sourcing, you can add something like this to the beginning of your application

```julia
function load_dotenv(filename = ".env")
    isfile(filename) || return
    for line in eachline(filename)
        var, val = strip.(split(line, "="))
        ENV[var] = val
    end
end

load_dotenv()

```

This way `.env` will override any environment variables and will do nothing if the file does not exist. As a side note, it could be good to revive [DotEnv.jl](https://github.com/vmari/DotEnv.jl) which was written specifically for this purposes.

Of course, you still can simplify users life by creating something like `gen_dotenv.jl` with the content

```julia
function gen_dotenv()
    print("User: ")
    user = readline()
    pass = read(Base.getpass("Password"), String)
    open(".env", "w") do io
        println(io, "USER = ", user)
        print(io, "PASSWORD = ", pass)
    end
end

gen_dotenv()

```

and explain to a user, that he should run this script at the root of the application.

---

<div class="post-metadata">

### Author: ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)
#### Post date: [February 11, 2021, 12:21pm UTC](https://discourse.julialang.org/t/how-to-best-store-and-access-credentials-in-julia/54997/13 "2021-02-11T12:21:35Z")

</div>

> [@Skoffer](#):
>
> As a side note, it could be good to revive [DotEnv.jl](https://github.com/vmari/DotEnv.jl) which was written specifically for this purposes.

I was going to advise using `DotEnv.jl` when I saw this comment. Is it dead? I was under the impression that it simply did not get updated because there wasn’t much to do anyway…

In any case, if `DotEnv.jl` is indeed dead, I do think it would be important to revive it. I know about several people relying on it in production environments.

---

<div class="post-metadata">

### Author: ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)
#### Post date: [February 11, 2021, 12:30pm UTC](https://discourse.julialang.org/t/how-to-best-store-and-access-credentials-in-julia/54997/14 "2021-02-11T12:30:09Z")

</div>

Ah, my bad, it uses old `REQUIRE` instead of `Project.toml`, which is why I decided that it is dead. Maybe cosmetic fresh up is all that is needed.
