azcfg

package module
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Sep 14, 2023 License: MIT Imports: 10 Imported by: 1

README

azcfg

Go Reference

Azure Confidential Field Gatherer - Set Azure Key Vault secrets to a struct

This module is used to get secrets from an Azure Key Vault and set them into a struct. The idea of parsing configuration values into a struct was inspired by env.

To mark a field in a struct to be populated by a secret set the struct tag secret followed by the name of the secret in Azure Key Vault, like so:

`secret:"<secret-name>"`

If the secret does not exist the field will keep the value it had prior to the call to Parse.

The secret can be marked as required, this will make the call to Parse return an error if the secret does not exist:

secret:"<secret-name>,required"

The error message contains all fields that have been marked as required that didn't have a secret associated with them.

Note: Unexported fields will be ignored.

See example for more.

Getting started

Install
go get github.com/KarlGW/azcfg
Prerequisites
  • Go 1.18
  • Azure Key Vault
    • Identity with access to secrets in the Key Vault
Authentication

The module supports several ways of authenticating to Azure and get secrets from the target Key Vault.

  1. Built-in credentials that supports Service Principal (Client Credentials with secret) and managed identity (system and user assigned)
  2. Credentials from azidentity with the submodule authopts
  3. Custom credential handling by implementing the auth.Credential interface.

For more information about option 2 and 3, see Credentials.

Built-in credentials

By default the module will attempt to determine credentials and target Key Vault with environment variables.

Environment variables

Service Principal

  • AZCFG_KEYVAULT_NAME - Name of the Azure Key Vault.
  • AZCFG_TENANT_ID - Tenant ID of the service principal/application registration.
  • AZCFG_CLIENT_ID - Client ID (also called Application ID) of the service principal/application registration.
  • AZCFG_CLIENT_SECRET- Client Secret of the service principal/application registration.

Managed identity

  • AZCFG_KEYVAULT_NAME - Name of the Azure Key Vault.
  • AZCFG_CLIENT_ID - (Optional) Client ID (also called Application ID) of the Managed Identity. Set if using a user assigned managed identity.
Options

If more control is needed, such as custom environment variables or other means of getting the necessary values, options can be used.

Service Principal

azcfg.Parse(
    &cfg,
    azcfg.WithClientSecretCredential(tenantID, clientID, clientSecret),
    WithVault(vault),
)

Managed identity

// System assigned identity.
azcfg.Parse(&cfg, WithManagedIdentity(), azcfg.WithVault(vault))
// User assigned identity.
azcfg.Parse(&cfg, WithManagedIdentity(clientID), azcfg.WithVault(vault))

To use a credential provided from elsewhere, such as the azidentity module see the section about Credentials.

Example
package main

import (
    "github.com/KarlGW/azcfg"
)

type config struct {
    Host string
    Port int

    Username string `secret:"username"`
    Password string `secret:"password"`

    Credential credential
}

type credential struct {
    Key int `secret:"key"`
}

func main() {
    cfg := config{}
    if err := azcfg.Parse(&cfg); err != nil {
        // Handle error.
    }

    fmt.Printf("%+v\n", cfg)
}
{Host: Port:0 Username:username-from-keyvault Password:password-from-keyvault Credential:{Key:12345}}

It is possible to pass options to Parse:

package main

import (
    "github.com/KarlGW/azcfg"
)

func main() {
    cfg := config{}
    if err := azcfg.Parse(&cfg, func(o *Options) {
        o.Credential = cred
        o.Vault = "vault"
        o.Concurrenty = 20
        o.Timeout = time.Millisecond * 1000 * 20
    }); err != nil {
        // Handle error.
    }
}

An independent parser can be created and passed around inside of the application.

package main

import (
    "github.com/KarlGW/azcfg"
)

func main() {
    parser, err := azcfg.NewParser()
    if err != nil {
        // Handle error.
    }

    cfg := config{}
    if err := parser.Parse(&cfg); err != nil {
        // Handle error.
    }
}

The constructor function NewParser supports the same options as the module level Parse function. For supported options see Options struct or list of function options

Usage

Supported types

  • string
  • bool
  • uint, uint8, uint16, uint32, uint64
  • int, int8, int16, int32, int64
  • float32, float64
Required

The default behaviour of Parse is to ignore secrets that does not exist and let the field contain it's original value. To enforce secrets to be set the option required can be used.

type Example struct {
    FieldA `secret:"field-a"`
    FieldB `secret:"field-b,required"`
}
Options

Option functions are provided by the module for convenience:

  • WithConcurrency
  • WithTimeout
  • WithVault
  • WithClientSecretCredential
  • WithManagedIdentity
  • WithCredential
Credentials

Custom credentials with token retrieval can be used using the option WithCredential. They must satisfy the interface Credential:

// Credential is the interface that wraps around method Token.
type Credential interface {
	Token(ctx context.Context) (Token, error)
}

Since it is reasonable to assume that credentials retrieved with the help of the azidentity module might be used, a submodule, authopts has been provided. This make it easer to reuse credentials from azidentity.

Usage

go get github.com/KarlGW/azcfg/authopts
package main

import (
    "github.com/Azure/azure-sdk-for-go/sdk/azcore"
    "github.com/KarlGW/azcfg"
    "github.com/KarlGW/azcfg/authopts"
)

func main() {
    cred, err := azidentity.NewDefaultAzureCredential(nil)
    if err != nil {
        // Handle error.
    }

    cfg := Config{}
    if err := azcfg.Parse(&cfg, authopts.WithTokenCredential(cred)); err != nil {
        // Handle error.
    }
}

For additional information about how to use azidentity, check its documentation.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrVaultNotSet is returned when no vault is set.
	ErrVaultNotSet = errors.New("a vault must be set")
)

Functions

func NewParser added in v0.6.0

func NewParser(options ...Option) (*parser, error)

NewParser creates and returns a *Parser. With no options provided it will have default settings for timeout and concurrency.

func Parse

func Parse(v any, options ...Option) error

Parse secrets from an Azure Key Vault into a struct.

Types

type Option added in v0.7.0

type Option func(o *Options)

Option is a function that sets Options.

func WithClientSecretCredential added in v0.7.0

func WithClientSecretCredential(tenantID, clientID, clientSecret string) Option

WithClientSecretCredential sets the parser to use client credential with a secret (client secret credential) for the Key Vault.

func WithConcurrency added in v0.7.0

func WithConcurrency(c int) Option

WithConcurrency sets the concurrency of the parser.

func WithCredential added in v0.7.0

func WithCredential(cred auth.Credential) Option

WithCredential sets the provided credential to the parser.

func WithManagedIdentity added in v0.7.0

func WithManagedIdentity(clientID ...string) Option

WithManagedIdentity sets the parser to use a managed identity for credentials for the Key Vault.

func WithTimeout added in v0.7.0

func WithTimeout(d time.Duration) Option

WithTimeout sets the timeout of the parser.

func WithVault added in v0.7.0

func WithVault(vault string) Option

WithVault sets the vault for the parser.

type Options added in v0.4.0

type Options struct {
	// Credential is the credential to be used with the Client. Used to override
	// the default method of aquiring credentials.
	Credential auth.Credential
	// Timeout is the total timeout for retrieval of secrets. Defaults to 5 seconds.
	Timeout time.Duration
	// Concurrency is the amount of secrets that will be retrieved concurrently.
	// Defaults to 10.
	Concurrency int
	// Vault is the name of the vault containing secrets. Used to override the
	// default method of aquiring target vault.
	Vault string
	// TenantID of the Service Principal with access to target Key Vault.
	TenantID string
	// ClientID of the Service Principal or user assigned managed identity with access to target Key Vault.
	ClientID string
	// ClientSecret of the Service Principal with access to target Key Vault.
	ClientSecret string
	// UseManagedIdentity set to use a managed identity. To use a user assigned managed identity, use
	// together with ClientID.
	UseManagedIdentity bool
}

Options contains options for the Parser.

type RequiredError added in v0.5.0

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

RequiredError represents an error when a secret is required.

func (*RequiredError) Error added in v0.5.0

func (e *RequiredError) Error() string

Error implements interface error.

Directories

Path Synopsis
authopts module
internal

Jump to

Keyboard shortcuts

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