Bitwarden Password Manager and Secrets Manager

Hello,

I’m using Bitwarden Password Manager as password manager.
I’m looking for a Julia client to retrieve API keys stored in Bitwarden Secret Manager.
(Instead of string into flat .env file or any other solution like that)
Is there any Julia package similar to

Cross posted at

Best regards

3 Likes

Julia’s FFI is pretty good. So creating a binding should hopefully be not too hard.

3 Likes

I looked at Python code and they are using Maturin.
But I also noticed some references to OpenAPI (ex Swagger).
I think using a code generator from API is required.

The CLI is available from bitwarden_cli_jll.jl, which you could wrap with a higher level interface.

2 Likes

Thanks @cjdoris but it looks quite old (I hope it’s still maintained)

Moreover there is 2 CLI

  • bw to deal with Bitwarden Password Manager
  • bws to deal with Bitwarden Secrets Manager

Currently I only see support for bw (not bws)

I prefer not to give access to my entire own vault to a script… abd so bws is more appropriated.

That’s why bws is better for my use case.

I could install with:

julia> using CondaPkg

(@v1.10) pkg> conda add maturin

also with (but likely above is preferred):
(@v1.10) pkg> conda pip_add maturin

It is quite old yes, and probably without “bws to deal with Bitwarden Secrets Manager” as you say. It does support the main platforms, for 64-bit, including macOS, though not for Arm. If Maturin works for you you can use it (it additionally supports FreeBSD) with PythonCall.jl, though I see:

Since you’re after CLI access, you can shell to it(?), i.e. you do NOT need any Julia support, meaning you do not need FFI (if so wrap bitwarden-c likely or Rust even or Python) or a wrapper. You just need to install the CLI code, and maybe a trivial way to do that from Julia.

I just took a quick look, maybe you only need CondaPkg.jl, a dependency of PythonCall, to install the CLI, and you wouldn’t need any Python code at all (even though you would install that full Python package; or install Rust CLI somehow with it)?

You might be able to use this (if not for wrapping, then only 323 lines of code, not too hard to translate, probably ChatGPT can even do it):

Kind of off-topic: Julia seemingly needs support for (and might help for this, for JSON API):

I’m trying first to compare bw cli usage with bitwarden_cli_jll.jl

PS C:\Users\scelles> bw -v
2025.1.3
PS C:\Users\scelles> bw login
? Email address: me@domain.com
? Master password: [hidden]
? Two-step login method: Authenticator App
? Two-step login code: 835314
You are logged in!

To unlock your vault, set your session key to the `BW_SESSION` environment variable. ex:
$ export BW_SESSION="......"
> $env:BW_SESSION="....."

You can also pass the session key to any command with the `--session` option. ex:
$ bw list items --session ...+...+...==
PS C:\Users\scelles> $env:BW_SESSION="....."
PS C:\Users\scelles> bw list items
[{"passwordHistory":null,"revisionDate":"2024-08-19T18:01:04.740Z" ...

and

julia> using bitwarden_cli_jll

julia> bw() do exe
           run(`$exe -v`)
           run(`$exe config server https://vault.bitwarden.eu`)
           run(`$exe login`)
       end
1.17.1
? Email address: s.celles@gmail.com
? Master password: [hidden]
{"response":{"error":"invalid_grant","error_description":"Auth-Email header invalid."},"statusCode":400}ERROR: failed process: Process(`'C:\Users\scelles\.julia\artifacts\a9b5ea49d42cbd291b866e295baa7ad47a7c8e8d\bin\bw.exe' login`, ProcessExited(1)) [1]

Stacktrace:
  [1] pipeline_error
    @ .\process.jl:598 [inlined]
  [2] run(::Cmd; wait::Bool)
    @ Base .\process.jl:513
  [3] run
    @ .\process.jl:510 [inlined]
  [4] (::var"#11#12")(exe::String)
    @ Main .\REPL[11]:3
  [5] (::JLLWrappers.var"#2#3"{var"#11#12", String})()
    @ JLLWrappers C:\Users\scelles\.julia\packages\JLLWrappers\GfYNv\src\runtime.jl:49
  [6] withenv(f::JLLWrappers.var"#2#3"{var"#11#12", String}, keyvals::Pair{String, String})
    @ Base .\env.jl:265
  [7]
    @ JLLWrappers C:\Users\scelles\.julia\packages\JLLWrappers\GfYNv\src\runtime.jl:48
  [8] invokelatest(::Any, ::Any, ::Vararg{Any}; kwargs::@Kwargs{})
    @ Base .\essentials.jl:1055
  [9] invokelatest(::Any, ::Any, ::Vararg{Any})
    @ Base .\essentials.jl:1052
 [10] bw(f::Function; adjust_PATH::Bool, adjust_LIBPATH::Bool)
    @ bitwarden_cli_jll C:\Users\scelles\.julia\packages\JLLWrappers\GfYNv\src\products\executable_generators.jl:28
 [11] bw(f::Function)
    @ bitwarden_cli_jll C:\Users\scelles\.julia\packages\JLLWrappers\GfYNv\src\products\executable_generators.jl:25
 [12] top-level scope
    @ REPL[11]:1
Some type information was truncated. Use `show(err)` to see complete types.

but I can’t login.

Any idea?

I opened an issue at

for updating build_tarballs.jl script

Looks like that CLI is no longer supported. But you can wrap the C bindings, which would be a fun little project, here’s how:

  1. Add a recipe to Yggdrasil to build the Bitwarden C bindings.
  2. This will automatically create a JLL package containing the shared library of C bindings.
  3. Create a package to wrap the C bindings. The C part should be quite simple, it’s just 3 functions with a generic JSON interface. Use JSON3.jl to serialise/deserialise messages to/from the C bindings.
  4. Add higher level functions to this package for specific commands. You could be fancy and auto-generate these from the JSON spec, but I don’t think the API is so big that you couldn’t do it by hand.

I wrapped bws CLI See GitHub - s-celles/BitwardenSecretsManagerUnofficialClient.jl

See announcement at [ANN] B7nSecretsManagerUnoffClient.jl - An unofficial Julia client for Bitwarden Secrets Manager

[bws] add 1.0.0 by s-celles · Pull Request #10610 · JuliaPackaging/Yggdrasil · GitHub was an attempt to create a JLL package for bws … but for license reason that doesn’t seems to be possible.
bws need to be dowloaded from official BW Github repository.

JLL package for bw should be possible

because that’s not the same licence than the SDK

there is probably cleaner to do than my current implementation. I will be pleased to see your contributions.