lowkeyvault

package
v0.44.0 Latest Latest
Warning

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

Go to latest
Published: Aug 7, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Index

Examples

Constants

View Source
const (
	Local = iota
	Network
)

possible access modes

Variables

This section is empty.

Functions

func WithNetworkAlias

func WithNetworkAlias(alias string, forNetwork *testcontainers.DockerNetwork) testcontainers.CustomizeRequestOption

WithNetworkAlias sets the alias of the container for the provided network and adds the specified name as a key vault alias for the default, "localhost", vault.

Types

type Container

type Container struct {
	testcontainers.Container
	// contains filtered or unexported fields
}

Container represents the Lowkey Vault container type used in the module

func Run

Run creates an instance of the Lowkey Vault container type

Example
package main

import (
	"context"
	"fmt"
	"log"

	"github.com/testcontainers/testcontainers-go"
	"github.com/testcontainers/testcontainers-go/modules/azure/lowkeyvault"
)

func main() {
	ctx := context.Background()

	lowkeyVaultContainer, err := lowkeyvault.Run(ctx, "nagyesta/lowkey-vault:7.3.48-ubi10-minimal")
	defer func() {
		if err := testcontainers.TerminateContainer(lowkeyVaultContainer); err != nil {
			log.Printf("failed to terminate container: %s", err)
		}
	}()
	if err != nil {
		log.Printf("failed to start container: %s", err)
		return
	}

	state, err := lowkeyVaultContainer.State(ctx)
	if err != nil {
		log.Printf("failed to get container state: %s", err)
		return
	}

	fmt.Println(state.Running)

}
Output:
true
Example (CertificateOperations)
package main

import (
	"context"
	"crypto/ecdsa"
	"crypto/elliptic"
	"encoding/base64"
	"fmt"
	"log"
	"os"

	"github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
	"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
	"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
	"github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing"
	"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
	"github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azcertificates"
	"github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets"
	"software.sslmate.com/src/go-pkcs12"

	"github.com/testcontainers/testcontainers-go"
	"github.com/testcontainers/testcontainers-go/modules/azure/lowkeyvault"
)

func main() {
	ctx := context.Background()

	lowkeyVaultContainer, err := lowkeyvault.Run(ctx, "nagyesta/lowkey-vault:7.3.48-ubi10-minimal")
	defer func() {
		if err := testcontainers.TerminateContainer(lowkeyVaultContainer); err != nil {
			log.Printf("failed to terminate container: %s", err)
		}
	}()
	if err != nil {
		log.Printf("failed to start container: %s", err)
		return
	}

	// prepareTheCertClient {
	connURL, err := lowkeyVaultContainer.ConnectionURL(ctx, lowkeyvault.Local)
	if err != nil {
		log.Printf("failed to get connection url: %s", err)
		return
	}

	identityEndpoint, err := lowkeyVaultContainer.IdentityEndpoint(ctx, lowkeyvault.Local)
	if err != nil {
		log.Printf("failed to get identity endpoint: %s", err)
		return
	}
	err = os.Setenv("IDENTITY_ENDPOINT", identityEndpoint)
	if err != nil {
		log.Printf("failed to set managed identity endpoint variable: %s", err)
		return
	}
	err = os.Setenv("IDENTITY_HEADER", lowkeyVaultContainer.IdentityHeader())
	if err != nil {
		log.Printf("failed to set managed identity header variable: %s", err)
		return
	}

	httpClient, err := lowkeyVaultContainer.Client(ctx)
	if err != nil {
		log.Printf("failed to get client: %s", err)
		return
	}

	cred, err := azidentity.NewDefaultAzureCredential(nil) // Will use Managed Identity via the Assumed Identity container
	if err != nil {
		log.Printf("failed to create credential: %v", err)
		return
	}
	certClient, err := azcertificates.NewClient(connURL,
		cred,
		&azcertificates.ClientOptions{ClientOptions: struct {
			APIVersion                      string
			Cloud                           cloud.Configuration
			InsecureAllowCredentialWithHTTP bool
			Logging                         policy.LogOptions
			Retry                           policy.RetryOptions
			Telemetry                       policy.TelemetryOptions
			TracingProvider                 tracing.Provider
			Transport                       policy.Transporter
			PerCallPolicies                 []policy.Policy
			PerRetryPolicies                []policy.Policy
		}{Transport: &httpClient}, DisableChallengeResourceVerification: true})
	if err != nil {
		log.Printf("failed to create certificate client: %v", err)
		return
	}
	// }

	// createCertificate {
	certName := "ec-cert"
	subject := "CN=example.com"
	_, err = certClient.CreateCertificate(ctx, certName, azcertificates.CreateCertificateParameters{
		CertificatePolicy: &azcertificates.CertificatePolicy{
			IssuerParameters: &azcertificates.IssuerParameters{
				Name: to.Ptr("Self"),
			},
			KeyProperties: &azcertificates.KeyProperties{
				Curve:    to.Ptr(azcertificates.CurveNameP256),
				KeyType:  to.Ptr(azcertificates.KeyTypeEC),
				ReuseKey: to.Ptr(true),
			},
			SecretProperties: &azcertificates.SecretProperties{
				ContentType: to.Ptr("application/x-pkcs12"),
			},
			X509CertificateProperties: &azcertificates.X509CertificateProperties{
				Subject: &subject,
				SubjectAlternativeNames: &azcertificates.SubjectAlternativeNames{
					DNSNames: []*string{to.Ptr("localhost")},
				},
				ValidityInMonths: to.Ptr(int32(12)),
			},
		},
	}, nil)
	if err != nil {
		log.Printf("failed to create a certificate: %v", err)
		return
	}
	// }

	secretClient, err := azsecrets.NewClient(connURL,
		cred,
		&azsecrets.ClientOptions{ClientOptions: struct {
			APIVersion                      string
			Cloud                           cloud.Configuration
			InsecureAllowCredentialWithHTTP bool
			Logging                         policy.LogOptions
			Retry                           policy.RetryOptions
			Telemetry                       policy.TelemetryOptions
			TracingProvider                 tracing.Provider
			Transport                       policy.Transporter
			PerCallPolicies                 []policy.Policy
			PerRetryPolicies                []policy.Policy
		}{Transport: &httpClient}, DisableChallengeResourceVerification: true})
	if err != nil {
		log.Printf("failed to create secret client: %v", err)
		return
	}

	// fetchCertDetails {
	base64Secret, err := secretClient.GetSecret(ctx, certName, "", nil)
	if err != nil {
		log.Printf("failed to get the secret with certificate store: %v", err)
		return
	}
	base64Value := *base64Secret.Value
	bytes, err := base64.StdEncoding.DecodeString(base64Value)
	if err != nil {
		log.Printf("failed to decode the certificate store: %v", err)
		return
	}
	// use SSLMate library to decode the certificate store as the x/crypto
	// library is not fully compatible with the Java PKCS12 format
	key, cert, err := pkcs12.Decode(bytes, "")
	if err != nil {
		log.Printf("failed to open certificate store: %v", err)
		return
	}
	ecKey, ok := key.(*ecdsa.PrivateKey)
	if !ok {
		log.Printf("unexpected key type: %T", key)
		return
	}
	// }

	fmt.Println(cert.Subject.String() == subject && ecKey.Curve == elliptic.P256())

}
Output:
true
Example (KeyOperations)
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
	"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
	"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
	"github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing"
	"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
	"github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys"

	"github.com/testcontainers/testcontainers-go"
	"github.com/testcontainers/testcontainers-go/modules/azure/lowkeyvault"
)

func main() {
	ctx := context.Background()

	lowkeyVaultContainer, err := lowkeyvault.Run(ctx, "nagyesta/lowkey-vault:7.3.48-ubi10-minimal")
	defer func() {
		if err := testcontainers.TerminateContainer(lowkeyVaultContainer); err != nil {
			log.Printf("failed to terminate container: %s", err)
		}
	}()
	if err != nil {
		log.Printf("failed to start container: %s", err)
		return
	}

	// prepareTheKeyClient {
	connURL, err := lowkeyVaultContainer.ConnectionURL(ctx, lowkeyvault.Local)
	if err != nil {
		log.Printf("failed to get connection url: %s", err)
		return
	}

	identityEndpoint, err := lowkeyVaultContainer.IdentityEndpoint(ctx, lowkeyvault.Local)
	if err != nil {
		log.Printf("failed to get identity endpoint: %s", err)
		return
	}
	err = os.Setenv("IDENTITY_ENDPOINT", identityEndpoint)
	if err != nil {
		log.Printf("failed to set managed identity endpoint variable: %s", err)
		return
	}
	err = os.Setenv("IDENTITY_HEADER", lowkeyVaultContainer.IdentityHeader())
	if err != nil {
		log.Printf("failed to set managed identity header variable: %s", err)
		return
	}

	httpClient, err := lowkeyVaultContainer.Client(ctx)
	if err != nil {
		log.Printf("failed to get client: %s", err)
		return
	}

	cred, err := azidentity.NewDefaultAzureCredential(nil) // Will use Managed Identity via the Assumed Identity container
	if err != nil {
		log.Printf("failed to create credential: %v", err)
		return
	}
	keyClient, err := azkeys.NewClient(connURL,
		cred,
		&azkeys.ClientOptions{ClientOptions: struct {
			APIVersion                      string
			Cloud                           cloud.Configuration
			InsecureAllowCredentialWithHTTP bool
			Logging                         policy.LogOptions
			Retry                           policy.RetryOptions
			Telemetry                       policy.TelemetryOptions
			TracingProvider                 tracing.Provider
			Transport                       policy.Transporter
			PerCallPolicies                 []policy.Policy
			PerRetryPolicies                []policy.Policy
		}{Transport: &httpClient}, DisableChallengeResourceVerification: true})
	if err != nil {
		log.Printf("failed to create key client: %v", err)
		return
	}
	// }

	// createKey {
	keyName := "rsa-key"
	rsaKeyParams := azkeys.CreateKeyParameters{
		Kty:     to.Ptr(azkeys.KeyTypeRSA),
		KeySize: to.Ptr(int32(2048)),
		KeyOps: []*azkeys.KeyOperation{
			to.Ptr(azkeys.KeyOperationDecrypt),
			to.Ptr(azkeys.KeyOperationEncrypt),
			to.Ptr(azkeys.KeyOperationUnwrapKey),
			to.Ptr(azkeys.KeyOperationWrapKey),
		},
	}
	createdKey, err := keyClient.CreateKey(ctx, keyName, rsaKeyParams, nil)
	if err != nil {
		log.Printf("failed to create a key: %v", err)
		return
	}
	// }

	// encryptMessage {
	secretMessage := "a secret message"
	encryptionParameters := azkeys.KeyOperationParameters{
		Value:     []byte(secretMessage),
		Algorithm: to.Ptr(azkeys.EncryptionAlgorithmRSAOAEP256),
	}
	encrResp, err := keyClient.Encrypt(ctx, keyName, createdKey.Key.KID.Version(), encryptionParameters, nil)
	if err != nil {
		log.Printf("failed to encrypt a message: %v", err)
		return
	}
	cipherText := encrResp.Result
	// }

	// decryptCipherText {
	decryptionParameters := azkeys.KeyOperationParameters{
		Value:     cipherText,
		Algorithm: to.Ptr(azkeys.EncryptionAlgorithmRSAOAEP256),
	}
	decrResp, err := keyClient.Decrypt(ctx, keyName, createdKey.Key.KID.Version(), decryptionParameters, nil)
	if err != nil {
		log.Printf("failed to decrypt a message: %v", err)
		return
	}
	decryptedMessage := string(decrResp.Result)
	// }

	fmt.Println(decryptedMessage == secretMessage)

}
Output:
true
Example (SecretOperations)
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
	"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
	"github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing"
	"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
	"github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets"

	"github.com/testcontainers/testcontainers-go"
	"github.com/testcontainers/testcontainers-go/modules/azure/lowkeyvault"
)

func main() {
	ctx := context.Background()

	// createContainerWithLocalMode {
	lowkeyVaultContainer, err := lowkeyvault.Run(ctx, "nagyesta/lowkey-vault:7.3.48-ubi10-minimal")
	defer func() {
		if err := testcontainers.TerminateContainer(lowkeyVaultContainer); err != nil {
			log.Printf("failed to terminate container: %s", err)
		}
	}()
	if err != nil {
		log.Printf("failed to start container: %s", err)
		return
	}
	// }

	// prepareTheSecretClient {
	connURL, err := lowkeyVaultContainer.ConnectionURL(ctx, lowkeyvault.Local)
	if err != nil {
		log.Printf("failed to get connection url: %s", err)
		return
	}

	identityEndpoint, err := lowkeyVaultContainer.IdentityEndpoint(ctx, lowkeyvault.Local)
	if err != nil {
		log.Printf("failed to get identity endpoint: %s", err)
		return
	}
	err = os.Setenv("IDENTITY_ENDPOINT", identityEndpoint)
	if err != nil {
		log.Printf("failed to set managed identity endpoint variable: %s", err)
		return
	}
	err = os.Setenv("IDENTITY_HEADER", lowkeyVaultContainer.IdentityHeader())
	if err != nil {
		log.Printf("failed to set managed identity header variable: %s", err)
		return
	}

	httpClient, err := lowkeyVaultContainer.Client(ctx)
	if err != nil {
		log.Printf("failed to get client: %s", err)
		return
	}

	cred, err := azidentity.NewDefaultAzureCredential(nil) // Will use Managed Identity via the Assumed Identity container
	if err != nil {
		log.Printf("failed to create credential: %v", err)
		return
	}
	secretClient, err := azsecrets.NewClient(connURL,
		cred,
		&azsecrets.ClientOptions{ClientOptions: struct {
			APIVersion                      string
			Cloud                           cloud.Configuration
			InsecureAllowCredentialWithHTTP bool
			Logging                         policy.LogOptions
			Retry                           policy.RetryOptions
			Telemetry                       policy.TelemetryOptions
			TracingProvider                 tracing.Provider
			Transport                       policy.Transporter
			PerCallPolicies                 []policy.Policy
			PerRetryPolicies                []policy.Policy
		}{Transport: &httpClient}, DisableChallengeResourceVerification: true})
	if err != nil {
		log.Printf("failed to create secret client: %v", err)
		return
	}
	// }

	// setAndFetchTheSecret {
	secretName := "secret-name"
	secretValue := "a secret value"
	created, err := secretClient.SetSecret(ctx, secretName, azsecrets.SetSecretParameters{Value: &secretValue}, nil)
	if err != nil {
		log.Printf("failed to set the secret %s", err.Error())
		return
	}

	fetched, err := secretClient.GetSecret(ctx, secretName, created.ID.Version(), nil)
	if err != nil {
		log.Printf("failed to get the secret %s", err.Error())
		return
	}
	fetchedValue := *fetched.Value
	// }

	fmt.Println(fetchedValue == secretValue)

}
Output:
true
Example (SecretOperationsNetwork)
package main

import (
	"context"
	"fmt"
	"log"

	"github.com/testcontainers/testcontainers-go"
	"github.com/testcontainers/testcontainers-go/modules/azure/lowkeyvault"
	"github.com/testcontainers/testcontainers-go/network"
	"github.com/testcontainers/testcontainers-go/wait"
)

func main() {
	ctx := context.Background()

	aNetwork, err := network.New(ctx)
	defer func() {
		err := aNetwork.Remove(ctx)
		if err != nil {
			log.Printf("failed to remove network: %s", err)
			return
		}
	}()
	if err != nil {
		log.Printf("failed to setup network: %s", err)
		return
	}

	// createContainerWithNetwork {
	lowkeyVaultContainer, err := lowkeyvault.Run(ctx, "nagyesta/lowkey-vault:7.3.48-ubi10-minimal",
		lowkeyvault.WithNetworkAlias("lowkey-vault", aNetwork),
	)
	defer func() {
		if err := testcontainers.TerminateContainer(lowkeyVaultContainer); err != nil {
			log.Printf("failed to terminate container: %s", err)
		}
	}()
	if err != nil {
		log.Printf("failed to start container: %s", err)
		return
	}
	// }

	// obtainEndpointUrls {
	connURL, err := lowkeyVaultContainer.ConnectionURL(ctx, lowkeyvault.Network)
	if err != nil {
		log.Printf("failed to get connection url: %s", err)
		return
	}

	identityEndpoint, err := lowkeyVaultContainer.IdentityEndpoint(ctx, lowkeyvault.Network)
	if err != nil {
		log.Printf("failed to get token url: %s", err)
		return
	}
	// }

	networkContainer, err := testcontainers.Run(ctx, "",
		testcontainers.WithDockerfile(
			testcontainers.FromDockerfile{
				Context:    "testdata",
				Dockerfile: "Dockerfile",
				KeepImage:  false,
			}),
		// configureClient {
		testcontainers.WithEnv(map[string]string{
			"IDENTITY_ENDPOINT": identityEndpoint,
			"IDENTITY_HEADER":   lowkeyVaultContainer.IdentityHeader(),
			"CONNECTION_URL":    connURL,
		}),
		// }
		network.WithNetwork(nil, aNetwork),
		testcontainers.WithWaitStrategy(
			wait.ForLog("true"),
		),
	)
	defer func() {
		if err := testcontainers.TerminateContainer(networkContainer); err != nil {
			log.Printf("failed to terminate container: %s", err)
		}
	}()
	if err != nil {
		log.Printf("failed to start container: %s", err)
		return
	}
	state, err := networkContainer.State(ctx)
	if err != nil {
		log.Printf("failed to get container state: %s", err)
		return
	}

	fmt.Println(state.ExitCode == 0)

}
Output:
true

func (*Container) Client

func (c *Container) Client(ctx context.Context) (http.Client, error)

Client prepares a client which will accept insecure (self-signed) certificates.

func (*Container) ConnectionURL

func (c *Container) ConnectionURL(ctx context.Context, accessMode int) (string, error)

ConnectionURL returns the connection URL for the Lowkey Vault API based on the provided access mode.

func (*Container) IdentityEndpoint

func (c *Container) IdentityEndpoint(ctx context.Context, accessMode int) (string, error)

IdentityEndpoint returns the URL value of the IDENTITY_ENDPOINT environment variable for the managed identity simulation. This will be used to obtain an access token for the Lowkey Vault API.

func (*Container) IdentityHeader

func (c *Container) IdentityHeader() string

IdentityHeader returns the value of the IDENTITY_HEADER environment variable for the managed identity simulation.

Jump to

Keyboard shortcuts

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