Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QUESTION: embedded_client authentication #219

Open
pudovd opened this issue Feb 17, 2025 · 6 comments
Open

QUESTION: embedded_client authentication #219

pudovd opened this issue Feb 17, 2025 · 6 comments
Labels
question Further information is requested

Comments

@pudovd
Copy link

pudovd commented Feb 17, 2025

The embedded_client feature works great but has has several concerns.

The first, all settings must be known before running terraform. Looks, we can't specify master_password via terraform input:

│ "client_id": all of `client_id,client_secret,master_password` must be
│ specified

So, all settings must be stored in the .env file, which looks as non-secure.

The second, Vaultwarden sends the "New Device Logged" email notification for every terraform run.

Could you give any recommendations for these concerns?

provider version: 0.13.0

@maxlaverse maxlaverse added the question Further information is requested label Feb 18, 2025
@maxlaverse
Copy link
Owner

Hi @pudovd,
Let me try to follow up on your questions one-by-one.

Looks, we can't specify master_password via terraform input:

│ "client_id": all of client_id,client_secret,master_password must be
│ specified

You can (and actually have to) specify the master_password in two of the authentication modes listed in the documentation:

  1. When using an Personal API Key, in which case you also need to provide an email, client_id and client_secret
  2. When using Email and Password in which case you only need the email and master_password.

Using a Personal API Key is recommended over Email and Password, as it allows you to easily revoke external access to the Vault, without changing your master password.

You haven't shared how you configured the plugin, therefore it's hard to tell exactly why this message is showing up.

The first, all settings must be known before running terraform.

Not necessarily. If you use a Terraform Input Variable, the input can be asked to you interactively.

So, all settings must be stored in the .env file, which looks as non-secure.

I wasn't aware Terraform reads .env files, and it's not clear from reading this Q&A. Personally, I prefer not to store credentials on disk, but it's really up to you. That being said, there is nothing forcing you to put store those environment on disk. You can load credentials in the environment in which Terraform will plan or apply by using the built-in export command of Bash, or any other way.

The second, Vaultwarden sends the "New Device Logged" email notification for every terraform run.

When using the embedded client, the Terraform provider writes a small file .bitwarden/device_identifier which is re-used across runs and usually prevents those emails from being sent. Try making sure this file is always present and with the same content.

@pudovd
Copy link
Author

pudovd commented Feb 18, 2025

Hi @maxlaverse!

I'll describe exactly which provider configuration I used in this case.
It is:

provider "bitwarden" {
  server = "https://bitwarden.local"

  experimental {
    embedded_client = true
  }
}

And a simple shell script which exports required environment variables before run terraform:

export BW_EMAIL="[email protected]"
export BW_PASSWORD="pass"
export BW_CLIENTID="clientid"
export BW_CLIENTSECRET="clientsecret"

So, if I don't export BW_PASSWORD I get an error like this:

╷
│ Error: Missing required argument
│ 
│   with provider["registry.terraform.io/maxlaverse/bitwarden"],
│   on provider-bitwarden.tf line 2, in provider "bitwarden":
│    2: provider "bitwarden" {
│ 
│ "master_password": one of `access_token,master_password,session_key` must
│ be specified
╵
╷
│ Error: Missing required argument
│ 
│   with provider["registry.terraform.io/maxlaverse/bitwarden"],
│   on provider-bitwarden.tf line 2, in provider "bitwarden":
│    2: provider "bitwarden" {
│ 
│ "session_key": one of `access_token,master_password,session_key` must be
│ specified
╵
╷
│ Error: Missing required argument
│ 
│   with provider["registry.terraform.io/maxlaverse/bitwarden"],
│   on provider-bitwarden.tf line 2, in provider "bitwarden":
│    2: provider "bitwarden" {
│ 
│ "client_id": all of `client_id,client_secret,master_password` must be
│ specified
╵
╷
│ Error: Missing required argument
│ 
│   with provider["registry.terraform.io/maxlaverse/bitwarden"],
│   on provider-bitwarden.tf line 2, in provider "bitwarden":
│    2: provider "bitwarden" {
│ 
│ "client_secret": all of `client_id,client_secret,master_password` must be
│ specified
╵

@maxlaverse
Copy link
Owner

Hi @pudovd,
Thanks. When using:

provider "bitwarden" {
  server = "https://bitwarden.local"

  experimental {
    embedded_client = true
  }
}

And running:

export BW_EMAIL="[email protected]"
export BW_PASSWORD="pass"
export BW_CLIENTID="clientid"
export BW_CLIENTSECRET="clientsecret"

before your Terraform command, what error do you have ?

So, if I don't export BW_PASSWORD I get an error like this:

I'm sorry if I misled you, but you will always have to provider your Vault's password. It's just that with client ID/Secret, the retrieval of the Vault is made through an API Key, but decrypting the Vault still requires the master password. Without client ID/Secret, the retrieval of the Vault would use your email and password.

@maxlaverse
Copy link
Owner

Technically, you don't need to pass an email if your using API keys with the embedded client btw. I'm fixing the documentation in #220

@pudovd
Copy link
Author

pudovd commented Feb 20, 2025

Hi @maxlaverse,

before your Terraform command, what error do you have ?

If all environment variables are set, no errors occur.

I'm sorry if I misled you, but you will always have to provider your Vault's password. It's just that with client ID/Secret, the retrieval of the Vault is made through an API Key, but decrypting the Vault still requires the master password. Without client ID/Secret, the retrieval of the Vault would use your email and password.

No problem. Thanks for your clarification and good work!

you don't need to pass an email if your using API keys with the embedded client btw.

Got it.

@pudovd
Copy link
Author

pudovd commented Feb 20, 2025

So, all settings must be stored in the .env file, which looks as non-secure.

For this statement I've found workaround with terragrunt.
I'm using a separate vaultwarden account to configure the provider. The implementation below:

  1. terragrunt.hcl:
terraform {
  source = "/path/to/module"

  extra_arguments "configure_bitwarden_provider" {
    commands = ["apply", "plan", "import', "destroy"]
    env_vars = jsondecode(run_cmd("--terragrunt-quiet", "/path/to/configure_bitwarden_provider.sh"))
  }
}
  1. /path/to/configure_bitwarden_provider.sh
#!/usr/bin/env sh

# Extract required information to configure bitwarden provider.
BW_ITEM_WITH_CREDENTIALS="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # item with bw credentials
BW_URL=$(bw status | jq -r .serverUrl )  # extract bitwarden url from current bw configuration
BW_CREDENTIALS=$(bw get item "$BW_ITEM_WITH_CREDENTIALS" \
  | jq '
    {
     BW_PASSWORD: .login.password,
     BW_CLIENTID: (.fields[] | select(.name == "client_id") | .value),
     BW_CLIENTSECRET: (.fields[] | select(.name == "client_secret") | .value)
    }'
)

# Return json in order to configure terraform environment variables
jq -n \
  --arg bw_url "$BW_URL" \
  --argjson bw_credentials "$BW_CREDENTIALS" \
  '$bw_credentials  * {"BW_URL":$bw_url}

So, we can close the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants