api

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Jul 31, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package api reaches the extension servers an operator runs: gRPC services implementing one of the contracts published under api/, currently api.kms.v1.EncryptionService.

Extension servers exist so an operator can plug in a backend the proxy has no built-in support for, such as an on-prem HSM or an internal key service.

Module dials every server named in the configuration and publishes the results as Connections, keyed by server name. Callers build their own clients over those connections rather than receiving finished ones, because the two do not correspond one-to-one: KMS is the client for the encryption service, and one is built per key, several of which may live on one server.

Dialing happens when the connections are first demanded rather than on the first call over them, so a bad address, certificate, or credential is caught during construction. The connections outlive this package and are closed with the application, not by any client built over them.

Index

Constants

This section is empty.

Variables

View Source
var Module = fx.Options(
	fx.Provide(func(p APIParams) (Connections, error) {

		if err := p.Config.ExtensionServers.Validate(); err != nil {
			return nil, fmt.Errorf("invalid extension server configuration: %w", err)
		}

		out := make(Connections, len(p.Config.ExtensionServers))
		conns := make([]*connect.Conn, 0, len(p.Config.ExtensionServers))

		for i := range p.Config.ExtensionServers {
			es := &p.Config.ExtensionServers[i]

			conn, err := extensionConn(p.Pool, es)
			if err != nil {
				return nil, err
			}

			out[es.Name] = conn
			conns = append(conns, conn)
		}

		p.Lifecycle.Append(fx.StartHook(func(ctx context.Context) error {
			if err := connect.WaitReady(ctx, conns...); err != nil {
				return fmt.Errorf("extension server connection not ready: %w", err)
			}

			return nil
		}))

		return out, nil
	}),
)

Module provides the pooled connection for every configured extension server, built when the provider runs rather than on first use, so a bad dial target surfaces at construction instead of on the first encryption call, and opened on start so an unreachable server (or one whose certificate this proxy will not accept) fails startup. Per-call credentials are still only exercised by a real request.

Functions

This section is empty.

Types

type APIParams

type APIParams struct {
	fx.In

	Config    *config.Config
	Lifecycle fx.Lifecycle
	Pool      *connect.Pool
}

APIParams collects the fx-provided dependencies needed to reach the configured extension servers. Pool is shared with the proxy's upstream connections; connect.Module owns it and closes every pooled connection on shutdown, which is why KMS.Close is a no-op.

type Connections

type Connections map[string]grpc.ClientConnInterface

Connections maps an extension server name to a connection to that server. It carries no lifecycle: closing a connection is the owner's responsibility, not the caller's.

Callers get connections rather than finished clients because the two do not correspond one-to-one: several keys may live on one extension server, so a caller builds one KMS per key over the shared connection.

type KMS

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

KMS wraps and unwraps data encryption keys on an extension server implementing api.kms.v1.EncryptionService. Only key material crosses the wire; payload plaintext never reaches the server.

The id names the key this client addresses. It is recorded in every DEK the key wraps and is what selects the key again when unwrapping, so it must stay stable for as long as any sealed payload references it.

func NewKMS

func NewKMS(id string, cc grpc.ClientConnInterface) *KMS

NewKMS returns a KMS addressing the key named by id over cc. Several keys may live on one extension server and share a connection, so cc is not owned here.

func (*KMS) Close

func (k *KMS) Close() error

Close is a no-op. The gRPC connection passed to NewKMS is owned by the caller that dialed it, which remains responsible for closing it; a KEKRegistry closing this KEK must not tear down a connection it does not own.

func (*KMS) Decrypt

func (k *KMS) Decrypt(ctx context.Context, ct []byte) ([]byte, error)

Decrypt decrypts a DEK previously produced by Encrypt.

func (*KMS) Encrypt

func (k *KMS) Encrypt(ctx context.Context, ns string, pt []byte) ([]byte, error)

Encrypt wraps a DEK via the remote provider, returning the ciphertext. The namespace is forwarded so the provider can select a per-namespace key.

func (*KMS) ID

func (k *KMS) ID() string

ID returns a unique ID for this KEK, e.g. a KMS ARN.

Jump to

Keyboard shortcuts

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