vals icon indicating copy to clipboard operation
vals copied to clipboard

Feature: support Bitwarden Secrets Manager

Open cortopy opened this issue 1 year ago • 6 comments

It seems vals support Bitwarden Vault as a backend. However, Bitwarden also has a product called "secrets manager", which has its own SDK and CLI

I Just tried to get a secret using current implementation and I get that the secret is not found. This is probably because unlike the vault, Secrets Manager is accessed with machine access tokens and scoped permissions per "project".

cortopy avatar Jun 19 '24 19:06 cortopy

@cortopy PR is weclome.

yxxhero avatar Jun 20 '24 13:06 yxxhero

I can create the PR, my only question is, the SDK needs musl-gcc and CGO_ENABLED, is it a problem @yxxhero ?

image ref: https://github.com/bitwarden/sdk/blob/main/languages/go/INSTRUCTIONS.md#set-go-environment-info

carnei-ro avatar Sep 06 '24 14:09 carnei-ro

here a super simple example how to fetch a secret in the Bitwarden Secrets Manager - this can be easily adapted to vals.

package main

import (
	"fmt"
	"os"

	sdk "github.com/bitwarden/sdk-go"
	"github.com/gofrs/uuid"
)

func main() {
	apiURL := os.Getenv("API_URL")
	if apiURL == "" {
		apiURL = "https://api.bitwarden.com"
	}
	identityURL := os.Getenv("IDENTITY_URL")
	if identityURL == "" {
		identityURL = "https://identity.bitwarden.com"
	}

	bitwardenClient, _ := sdk.NewBitwardenClient(&apiURL, &identityURL)

	accessToken := os.Getenv("ACCESS_TOKEN") // An Access Token from a "Machine account". Ensure you granted "Can read" to a project.
	organizationIDStr := os.Getenv("ORGANIZATION_ID") // The Organization ID where the project is located. This is an UUID that you can find in the URL like: https://vault.bitwarden.com/#/sm/00000000-0000-0000-0000-000000000000, where 00000000-0000-0000-0000-000000000000 is the Organization ID.
	projectName := os.Getenv("PROJECT_NAME")
	secretName := os.Getenv("SECRET_NAME")

	if projectName == "" || organizationIDStr == "" || secretName == "" || accessToken == "" {
		panic("Environment variables required: ACCESS_TOKEN, ORGANIZATION_ID, PROJECT_NAME, SECRET_NAME")
	}

	err := bitwardenClient.AccessTokenLogin(accessToken, nil)
	if err != nil {
		panic(err)
	}

	organizationID, err := uuid.FromString(organizationIDStr)
	if err != nil {
		panic(err)
	}

	var projectID string

	projectList, err := bitwardenClient.Projects().List(organizationID.String())
	if err != nil {
		panic(err)
	}
	for _, project := range projectList.Data {
		if project.Name == projectName {
			projectID = project.ID
		}
	}

	secretsList, err := bitwardenClient.Secrets().List(organizationID.String())
	if err != nil {
		panic(err)
	}
	var secretValue string
	for _, secret := range secretsList.Data {
		if secret.Key == secretName {
			s, err := bitwardenClient.Secrets().Get(secret.ID)
			if err != nil {
				panic(err)
			}
			if *s.ProjectID == projectID {
				secretValue = s.Value
			}
		}
	}

	fmt.Println(secretValue)

	defer bitwardenClient.Close()
}

carnei-ro avatar Sep 06 '24 14:09 carnei-ro

please make a PR, we will test it and review it accordingly @carnei-ro

zhaque44 avatar Sep 06 '24 14:09 zhaque44

@zhaque44 PR opened

carnei-ro avatar Sep 06 '24 17:09 carnei-ro

I guess we should re-open this issue.

carnei-ro avatar Sep 07 '24 12:09 carnei-ro