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
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.
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.
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:
Add a recipe to Yggdrasil to build the Bitwarden C bindings.
This will automatically create a JLL package containing the shared library of C bindings.
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.
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.