lowkeyvault

package
v0.42.0 Latest Latest
Warning

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

Go to latest
Published: Apr 9, 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
ctx := context.Background()

lowkeyVaultContainer, err := lowkeyvault.Run(ctx, "nagyesta/lowkey-vault:7.0.9-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)
ctx := context.Background()

lowkeyVaultContainer, err := lowkeyvault.Run(ctx, "nagyesta/lowkey-vault:7.0.9-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)
ctx := context.Background()

lowkeyVaultContainer, err := lowkeyvault.Run(ctx, "nagyesta/lowkey-vault:7.0.9-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)
ctx := context.Background()

// createContainerWithLocalMode {
lowkeyVaultContainer, err := lowkeyvault.Run(ctx, "nagyesta/lowkey-vault:7.0.9-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)
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.0.9-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