couchbasecapella

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 8, 2023 License: MPL-2.0 Imports: 29 Imported by: 0

README

vault-plugin-database-couchbasecapella

CircleCI

A Vault plugin for Couchbase Capella

This project uses the database plugin interface introduced in Vault version 0.7.1.

The plugin supports the generation of static and dynamic user roles and root credential rotation.

Build

To build this package for any platform you will need to clone this repository and cd into the repo directory and go build -o couchbasecapella-database-plugin ./cmd/couchbasecapella-database-plugin/. To run some of the tests, create a provisioned Capella cluster instance and run it locally similar to the below example.

Set env variables and run the below: export ORG_ID=<>; export PROJECT_ID=<>; export CLUSTER_ID=<>; export ADMIN_USER_ACCESS_KEY=<>; export ADMIN_USER_SECRET_KEY=<>

make test

(or using the flags)

go test -v \
-apiUrl='https://cloudapi.dev.nonprod-project-avengers.com/v4' \
-orgId='6af08c0a-8cab-4c1c-b257-b521575c16d0' \
-projectId='d352361d-8de1-445b-9969-873b6decb63a' \
-clusterId='92236592-9f74-475e-afeb-0609b743c41b' \
-adminUserAccessKey='NbMSRuuUlVNuvFCLNDVc9Hk9xvoqMbKP' \
-adminUserSecretKey='eNJMuUwHP95vxSftiBsjO2WPS1znWcIQlng64PKIkUjCf5#yBVWDS8tFtFnGt7es'

Installation

The Vault plugin system is documented on the Vault documentation site.

You will need to define a plugin directory using the plugin_directory configuration directive, then place the vault-plugin-database-couchbasecapella executable generated above, into the directory.

Please note: Versions v0.2.0 onwards of this plugin are incompatible with Vault versions before 1.6.0 due to an update of the database plugin interface.

Sample commands for registering and starting to use the plugin:

SHA256=$(shasum -a 256 plugins/couchbasecapella-database-plugin | cut -d' ' -f1)

vault secrets enable database

vault write sys/plugins/catalog/database/couchbasecapella-database-plugin sha256=$SHA256 \
        command=couchbasecapella-database-plugin

At this stage you are now ready to initialize the plugin to connect to couchbase capella cluster using unencrypted or encrypted communications.

Prior to initializing the plugin, ensure that you have created a couchbase capella provisioned cluster along with V4 API keys. Vault will use the user specified settings here to create/update/revoke database credentials. That user must have the appropriate permissions to perform actions upon other database users.

Plugin initialization
Set Vault Address to the local or hosted server
export VAULT_ADDR=http://127.0.0.1:8200
Set the Capella required password policy

cat >password_policy.hcl << EOF
length=64

rule "charset" {
  charset = "abcdefghijklmnopqrstuvwxyz"
  min-chars = 1
}

rule "charset" {
  charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  min-chars = 1
}

rule "charset" {
  charset = "0123456789"
  min-chars = 1
}

rule "charset" {
  charset = "#@%!"
  min-chars = 1
}
EOF

vault write sys/policies/password/couchbasecapella \
   policy=@password_policy.hcl

Success! Data written to: sys/policies/password/couchbasecapella

Initialize the database plugin

# Usage vault write database/config/couchbasecapella-database
plugin_name="couchbasecapella-database-plugin"
cloud_api_base_url="https://cloudapi.dev.nonprod-project-avengers.com/v4"
organization_id="<org_uuid>"
project_id="<proj_uuid>"
cluster_id="<cluster_uuid>"
username=""
password=''
password_policy="couchbasecapella"
allowed_roles="*"

vault write database/config/couchbasecapella-database \
    plugin_name="couchbasecapella-database-plugin" \
    cloud_api_base_url="https://cloudapi.dev.nonprod-project-avengers.com/v4" \
    organization_id="6af08c0a-8cab-4c1c-b257-b521575c16d0" \
    project_id="d352361d-8de1-445b-9969-873b6decb63a" \
    cluster_id="47820643-6e1f-4fea-b63c-625d1e10b536" \
    username="haI3UAw1VEOGvxjBFWDEBhnpB0nF74qf" \
    password='EUlfonfGtx#s1RlqPYryIlmcBgWuTIaMgvJ6%lrQIdu5QwCDW5oJRdeVwa3qynh7' \
    password_policy="couchbasecapella" \
    allowed_roles="*"

Success! Data written to: database/config/couchbasecapella-database

You should consider rotating the root password (same as secretKey). Note that if you do, the new password(secret) will never be made available through Vault, so you should create a vault-specific database admin user for this.

vault write -force database/rotate-root/couchbasecapella-database

Success! Data written to: database/rotate-root/couchbasecapella-database

Dynamic Role Creation

When you create roles, you need to provide a JSON string containing the access with Couchbase RBAC roles which are documented here.

NOTE: if a creation_statement is not provided readonly for all buckets(with all scopes and collections), '{access: [{ privileges: [ data_reader ], resources: { buckets: [ { name :* } ] } }]}'

dynamicrole1 with a specific bucket, scope with both data read and write.
vault write database/roles/dynamicrole1 \
db_name="couchbasecapella-database" \
creation_statements='{"access": [ { "privileges": [ "data_reader", "data_writer" ], "resources": { "buckets": [ { "name": "vault-bucket-1", "scopes": [ { "name": "vault-bucket-1-scope-1", "collections": [ "*" ] } ] } ] } } ]}' \
default_ttl="5m" \
max_ttl="1h"

Success! Data written to: database/roles/dynamicrole1

dynamicrole2 with a list of 3 buckets (its all scopes &collections) access previleges of both data read and write.
vault write database/roles/dynamicrole2 \
db_name="couchbasecapella-database" \
creation_statements='{"access": [ { "privileges": [ "data_reader", "data_writer" ], "resources": { "buckets": [ { "name": "db-cred-test-12Qj", "scopes": [ { "name": "*" } ] }, { "name": "db-cred-test-3zRb", "scopes": [ { "name": "*" } ] }, { "name": "db-cred-test-FcAv", "scopes": [ { "name": "*" } ] } ] } } ]}' \
default_ttl="5m" \
max_ttl="1h" 

Success! Data written to: database/roles/dynamicrole2

dynamicrole3 with all buckets
vault write database/roles/dynamicrole3 \
db_name="couchbasecapella-database" \
creation_statements='{"access": [ { "privileges": [ "data_reader" ], "resources": { "buckets": [ { "name": "*" } ] } } ]}' \
default_ttl="5m" \
max_ttl="1h"

Success! Data written to: database/roles/dynamicrole3

To retrieve the credentials for the dynamic accounts

vault read database/creds/dynamicrole1

Key Value --- ----- lease_id database/creds/dynamicrole1/qyaXNzyh53U1w5zIlSHAR7be lease_duration 5m lease_renewable true password !maOKglPc7IIccb!CftAC7rLsXQlxUvGKgpEnzzAYpbiifcYfVpF3E8jiyNvABtN username V_TOKEN_MYDYNAMICROLE3_OAKVWMKBMT1P9IGJS1TT_1692391736

vault read database/creds/dynamicrole2

Key Value --- ----- lease_id database/creds/dynamicrole2/spZ3NGneJYkptKnTgru8MJlb lease_duration 5m lease_renewable true password AVPuT#oF0cGzPIfBnaqMGsHjm9vorXwaOUw8ezP7b1k@mbTwBcRL72c@7@NDDyr0 username V_TOKEN_MYDYNAMICROLE3_8O0M5CKNWNSF2EA6VYLW_1692391739

vault read database/creds/dynamicrole3

Key Value --- ----- lease_id database/creds/dynamicrole3/5ok4TllgYHg6QH4vsawqt2mY lease_duration 5m lease_renewable true password VVE2T4AkW%LsUgBGsY5c8opt09gB2vWhefUyJ@%qPxy%saO56d4ZPntiHkQDmiUf username V_TOKEN_MYDYNAMICROLE3_ZOFAJPGLNZNQMSZCBUFK_1692391706

Static Role Creation

In order to use static roles, the database credential user must already exist in the Couchbase Capella security settings. The example below assumes that there is an existing user with the name "vault-edu".


# Usage: 
vault write database/static-roles/<role-name> db_name=couchbasecapella-database username="<db-cred-user-name>" rotation_period=<secs> 

Success! Data written to: database/static-roles/

# Example:
vault write database/static-roles/static-account db_name=couchbasecapella-database \
        username="vault-edu" rotation_period="5m"

Success! Data written to: database/static-roles/static-account

To retrieve the credentials for the vault-edu user

vault read database/static-creds/static-account

Key Value --- ----- last_vault_rotation 2023-08-04T19:28:21.229382-07:00 password wFgNaxdH2wGw2i9-B0Qj rotation_period 5m ttl 4m59s username vault-edu

Developing

You can run make dev in the root of the repo to start up a development vault server and automatically register a local build of the plugin. You will need to have a built vault binary available in your $PATH to do so.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CheckForOldCouchbaseCapellaVersion

func CheckForOldCouchbaseCapellaVersion(hostname, username, password string) (is_old bool, err error)

func CreateCapellaDbCredUser

func CreateCapellaDbCredUser(baseUrl string, cloudAPIclustersEndPoint string, accessKey string, secretKey,
	username string, password string, access string) error

func DeleteCapellaDbCredUser

func DeleteCapellaDbCredUser(baseUrl string, cloudAPIclustersEndPoint string, accessKey string, secretKey, username string) error

func New

func New() (interface{}, error)

New implements builtinplugins.BuiltinFactory

func Unmarshal

func Unmarshal(body io.Reader, v interface{}) error

func UpdateCapellaDbCredUser

func UpdateCapellaDbCredUser(baseUrl string, cloudAPIclustersEndPoint string, accessKey string, secretKey, username string, password string) (string, error)

Types

type CapellaClient

type CapellaClient struct {
	// contains filtered or unexported fields
}

func NewCapellaClient

func NewCapellaClient(baseUrl string, accessKey string, secretKey string) *CapellaClient

--

func NewClient

func NewClient(baseURL, access, secret string) *CapellaClient

func (*CapellaClient) Do

func (c *CapellaClient) Do(method, uri string, body interface{}) (*http.Response, error)

type CouchbaseCapellaDB

type CouchbaseCapellaDB struct {
	credsutil.CredentialsProducer
	// contains filtered or unexported fields
}

Type that combines the custom plugins Couchbase Capella database connection configuration options and the Vault CredentialsProducer used for generating user information for the Couchbase Capella database.

func (CouchbaseCapellaDB) Close

func (c CouchbaseCapellaDB) Close() error

Close terminates the database connection with locking

func (CouchbaseCapellaDB) Connection

func (c CouchbaseCapellaDB) Connection(ctx context.Context) (interface{}, error)

func (*CouchbaseCapellaDB) DeleteUser

func (CouchbaseCapellaDB) Init

func (c CouchbaseCapellaDB) Init(ctx context.Context, initConfig map[string]interface{}, verifyConnection bool) (saveConfig map[string]interface{}, err error)

func (*CouchbaseCapellaDB) Initialize

func (*CouchbaseCapellaDB) NewUser

func (*CouchbaseCapellaDB) Type

func (c *CouchbaseCapellaDB) Type() (string, error)

func (*CouchbaseCapellaDB) UpdateUser

type Cursor

type Cursor struct {
	Hrefs Hrefs `json:"hrefs"`
	Pages Pages `json:"pages"`
}

type Hrefs

type Hrefs struct {
	First    string `json:"first"`
	Last     string `json:"last"`
	Next     string `json:"next"`
	Previous string `json:"previous"`
}

type ListDbCredResponse

type ListDbCredResponse struct {
	Cursor Cursor        `json: "cursor"`
	Data   []interface{} `json:"data"`
}

type Pages

type Pages struct {
	// Last Last page number.
	Last int `json:"last"`

	// Next Next page number, it is not set on the last page.
	Next *int `json:"next,omitempty"`

	// Page Current page starting from 1.
	Page int `json:"page"`

	// PerPage How many items are displayed in the page.
	PerPage int `json:"perPage"`

	// Previous Previous page number, it is not set on the first page.
	Previous *int `json:"previous,omitempty"`

	// TotalItems Total items found by the given query.
	TotalItems int `json:"totalItems"`
}

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL