kmssdk

package module
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Jul 21, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

README

kms-sdk-go

Go Reference Go Report Card Tests license

The Go SDK to interact with the INCERT Keys&More KMS service.

NOTE: THIS PROJECT IS CURRENTLY UNDER DEVELOPMENT AND SUBJECT TO BREAKING CHANGES.

How to use

Add it to your project by running

go get github.com/incert-kms/kms-sdk-go@latest

Then connect to your KMS service and start using it:

package main

import (
    "context"
    "fmt"
    "log/slog"
    "os"

    "github.com/google/uuid"
    kmssdk "github.com/incert-kms/kms-sdk-go"
)

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

    logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{
        Level: slog.LevelInfo,
    }))

    client := kmssdk.NewClient(
        kmssdk.WithBaseURL("https://kms.example.com/kms"),
        kmssdk.WithUsernameAndPassword(os.Getenv("KMS_USERNAME"), os.Getenv("KMS_PASSWORD")),
        kmssdk.WithLogger(logger),
    )

    if err := client.Connect(ctx); err != nil {
        panic(err)
    }

    // Create a new AES 256 key in a vslot
    vslotID := uuid.MustParse(os.Getenv("KMS_VSLOT_ID"))
    created, err := client.CreateKey(ctx, vslotID, kmssdk.KeyData{
        Alg:         "AES256",
        Name:        "example-key",
        Persistence: kmssdk.PersistenceExternal,
    })
    if err != nil {
        panic(err)
    }
    fmt.Println("AES KEY:", created.ID)
}

See examples and the package documentation for more.

Features

The SDK exposes the operations needed to manage and use keys through the Keys&More REST API:

  • Authentication
    • Mode auto-discovered from the server's /configs/auth endpoint
    • Self-managed (SELF_MANAGED): login, token refresh and logout against the Keys&More TOKEN API
    • OAuth2 with Keycloak (URL, realm and client id from discovery, password grant)
    • Token caching and refresh handled transparently; on a 401 the request is replayed once with a fresh token
    • Logout invalidates tokens (server-side on self-managed deployments)
  • Vslots
    • List vslots (paged responses iterated transparently)
  • Keys lifecycle
    • Create keys (returns the new key id and, for persistence: NONE, the generated material)
    • Read keys (by ID or by listing/filtering within a vslot)
    • Delete keys (permanent removal via the DELETED lifecycle state)
  • Cryptographic operations
    • Encrypt / Decrypt data with algorithm-specific attributes (iv, counter, aad, label, ...)
    • Sign / Verify with the full signature registry (RSA PKCS#1/PSS, ECDSA, HMAC, CMAC, ML-DSA); verify reports validity as a boolean, PSS-raw parameters travel as numeric PKCS#11 codes

The client is safe for concurrent use by multiple goroutines once Connect has returned.

Configuration

NewClient accepts the following options:

Option Description
WithBaseURL(url) Override the default base URL of the deployment, e.g. https://kms.example.com/kms — without the /api prefix, which is appended internally (the default points at INCERT's UAT environment).
WithUsernameAndPassword(user, pass) Credentials used for the Keycloak password grant.
WithTimeout(d) Overall HTTP timeout of the SDK-managed client (default 10s).
WithHTTPClient(hc) Supply a custom *http.Client; takes precedence over WithTimeout and WithTLSSkipVerify.
WithTLSSkipVerify() Disable TLS verification (development only).
WithLogger(l) Supply a *slog.Logger; without it the SDK is silent.

Error handling

API errors are returned as *kmssdk.APIError and can be inspected with errors.As. Branch on the server error code (ErrCode* constants) rather than on the message:

if err := client.Connect(ctx); err != nil {
    var apiErr *kmssdk.APIError
    switch {
    case errors.As(err, &apiErr) && apiErr.Code == kmssdk.ErrCodeWrongCredentials:
        fmt.Println("check your username/password")
    case errors.As(err, &apiErr):
        fmt.Printf("API error %d (%s): %s\n", apiErr.StatusCode, apiErr.Code, apiErr.Message)
    default:
        fmt.Printf("transport error: %v\n", err) // connection failure, timeout, ...
    }
}

Network-level failures (connection errors, timeouts) are not APIError values; they wrap the underlying transport error, so errors.Is(err, context.DeadlineExceeded) and os.IsTimeout(err) keep working.

License

Licensed under the Apache License, Version 2.0 — see LICENSE.

Documentation

Overview

Package kmssdk provides a Go client for the INCERT Keys&More KMS HTTP API.

The client discovers the server's authentication mode from the public /configs/auth endpoint and picks the matching backend automatically:

  • SELF_MANAGED: tokens are issued by Keys&More itself; the client logs in with username/password (POST /auth/token) and renews the access token via the refresh endpoint.
  • OAUTH2 with a Keycloak provider: the Keycloak URL, realm and client id come from discovery and a token is obtained via the password grant.

In both modes tokens are cached and renewed transparently, and Client.Logout invalidates them (server-side on SELF_MANAGED deployments).

Getting started

Construct a client with the desired options, then call Client.Connect once to bootstrap authentication and verify access:

ctx := context.Background()
client := kmssdk.NewClient(
    kmssdk.WithBaseURL("https://kms.example.com/kms"),
    kmssdk.WithUsernameAndPassword("user", "pass"),
    kmssdk.WithLogger(slog.Default()),
)
if err := client.Connect(ctx); err != nil {
    // handle error
}

Available options:

  • WithBaseURL overrides the default deployment base URL (the /api prefix is appended internally).
  • WithUsernameAndPassword sets the credentials used for the Keycloak password grant.
  • WithTimeout adjusts the HTTP timeout (default 10s).
  • WithTLSSkipVerify disables TLS verification (development only).
  • WithHTTPClient supplies a custom *http.Client (takes precedence over WithTimeout and WithTLSSkipVerify).
  • WithLogger supplies a *slog.Logger; without it the SDK is silent.

Operations

Vslots and keys:

Cryptographic operations are issued through Client.Crypto with either OperationEncrypt or OperationDecrypt:

ciphertext, err := client.Crypto(ctx, kmssdk.OperationEncrypt, keyID, kmssdk.CryptoRequest{
    Data:       plaintext,
    Algorithm:  "AES_GCM",
    Attributes: map[string]any{"iv": iv},
})

Errors

API errors are returned as *APIError. Use errors.As to inspect the HTTP status code, server error code (see the ErrCode constants), and message:

var apiErr *kmssdk.APIError
if errors.As(err, &apiErr) {
    fmt.Printf("API error %d (%s): %s\n", apiErr.StatusCode, apiErr.Code, apiErr.Message)
}

Network-level failures (connection errors, timeouts) are not APIError values; they wrap the underlying transport error, so errors.Is(err, context.DeadlineExceeded) and os.IsTimeout(err) apply.

Concurrency

After Client.Connect returns, the client is safe for concurrent use by multiple goroutines; token renewal is synchronized internally. Connect itself must complete before concurrent calls start.

Context

Every method accepts a context.Context for cancellation and timeouts.

Index

Examples

Constants

View Source
const (
	AuthenticationTypeOAuth2      AuthenticationType = "OAUTH2"
	AuthenticationTypeSelfManaged AuthenticationType = "SELF_MANAGED"
	OAuth2ProviderKeycloak        OAuth2Provider     = "KEYCLOAK"
	KeycloakModeManaged           KeycloakMode       = "MANAGED"
)

Known values of the configuration enums.

View Source
const (
	ErrCodeBadRequest                    = "BAD_REQUEST"                       // 400
	ErrCodeWrongCredentials              = "WRONG_CREDENTIALS"                 //nolint:gosec // server error-code name, not a credential — 401
	ErrCodeInvalidToken                  = "INVALID_TOKEN"                     // 401
	ErrCodeDeactivatedToken              = "DEACTIVATED_TOKEN"                 // 401
	ErrCodeInvalidSignature              = "INVALID_SIGNATURE"                 // 401
	ErrCodeUnauthorized                  = "UNAUTHORIZED"                      // 401
	ErrCodeForbiddenAccess               = "FORBIDDEN_ACCESS"                  // 403
	ErrCodeForbiddenOperation            = "FORBIDDEN_OPERATION"               // 403
	ErrCodeTooManyResults                = "TOO_MANY_RESULTS"                  // 403
	ErrCodeDisabledAccount               = "DISABLED_ACCOUNT"                  // 403
	ErrCodeEmailVerificationTokenInvalid = "EMAIL_VERIFICATION_TOKEN_INVALID"  //nolint:gosec // server error-code name, not a credential — 400/401
	ErrCodeResourceNotFound              = "RESOURCE_NOT_FOUND"                // 404
	ErrCodeConflict                      = "CONFLICT"                          // 409
	ErrCodeInvalidMultipart              = "INVALID_MULTIPART"                 // 415
	ErrCodeQuotaExceeded                 = "QUOTA_EXCEEDED"                    // 429
	ErrCodeInternalServerError           = "INTERNAL_SERVER_ERROR"             // 500
	ErrCodeKeyLifecycle                  = "KEY_LIFECYCLE"                     // 500
	ErrCodeNotImplemented                = "NOT_IMPLEMENTED"                   // 501
	ErrCodeInternalKeyAttributesDiffer   = "INTERNAL_KEY_ATTRIBUTES_DIFFERENT" // 260 (non-standard)
)

Server error codes (the ApiErrorCode enum) carried in APIError.Code. Branch on these rather than on APIError.Message: messages are human-oriented and may change between server versions.

View Source
const (
	KeyStateProvisioned = "PROVISIONED"
	KeyStateActive      = "ACTIVE"
	KeyStateDeactivated = "DEACTIVATED"
	KeyStateDestroyed   = "DESTROYED"
	KeyStateDeleted     = "DELETED"
)

Key lifecycle states. The lifecycle is one-way: PROVISIONED → ACTIVE → DEACTIVATED → DESTROYED → DELETED; a key can never return to an earlier state. DELETED removes both the key material and its metadata immediately.

View Source
const (
	PersistenceInternal = "INTERNAL" // material stored in the crypto provider (e.g. HSM)
	PersistenceExternal = "EXTERNAL" // material stored wrapped in the KMS database
	PersistenceNone     = "NONE"     // material returned to the caller and not stored
)

Key persistence modes: where the key material lives.

View Source
const (
	KeyTypeGenerated = "GENERATED"
	KeyTypeProvider  = "PROVIDER"
	KeyTypeImported  = "IMPORTED"
	KeyTypeWrap      = "WRAP"
)

Key types: how the key entered the system.

Variables

This section is empty.

Functions

This section is empty.

Types

type APIError

type APIError struct {
	// StatusCode is the HTTP status of the response.
	StatusCode int `json:"status_code"`
	// Timestamp is set when the server reports one (framework fallback errors).
	Timestamp string `json:"timestamp"`
	// Message is the human-readable server message.
	Message string `json:"message"`
	// Code is the server error code (one of the ErrCode* constants), or the
	// HTTP status text when the server did not provide one.
	Code string `json:"code"`
	// Errors holds per-field validation messages, populated only for
	// bean-validation failures (Code == ErrCodeBadRequest).
	Errors []string `json:"errors"`
	// ErrorCode and ErrorDescription carry the OAuth2 IdP-native error fields
	// ("error", "error_description") returned by token endpoints.
	ErrorCode        string `json:"error"`
	ErrorDescription string `json:"error_description"`
}

APIError is returned for every HTTP response with status >= 400, from both the KMS API and the OAuth2 token endpoint. Inspect it with errors.As:

var apiErr *kmssdk.APIError
if errors.As(err, &apiErr) {
    switch {
    case apiErr.Code == kmssdk.ErrCodeResourceNotFound:
        // ...
    case apiErr.StatusCode >= 500:
        // server-side failure, possibly transient
    }
}

Errors that never reached the server (connection failures, timeouts) are not APIError values: they wrap the underlying *url.Error, so errors.Is(err, context.DeadlineExceeded) and os.IsTimeout(err) keep working.

Example
package main

import (
	"context"
	"errors"
	"fmt"
	"os"

	kmssdk "github.com/incert-kms/kms-sdk-go"
)

func main() {
	ctx := context.Background()
	client := kmssdk.NewClient(
		kmssdk.WithUsernameAndPassword(os.Getenv("KMS_USERNAME"), os.Getenv("KMS_PASSWORD")),
	)

	if err := client.Connect(ctx); err != nil {
		var apiErr *kmssdk.APIError
		switch {
		case errors.As(err, &apiErr) && apiErr.Code == kmssdk.ErrCodeWrongCredentials:
			fmt.Println("check KMS_USERNAME / KMS_PASSWORD")
		case errors.As(err, &apiErr):
			fmt.Printf("API error %d (%s): %s\n", apiErr.StatusCode, apiErr.Code, apiErr.Message)
		default:
			fmt.Printf("transport error: %v\n", err)
		}
	}
}

func (*APIError) Error

func (e *APIError) Error() string

Error implements the error interface.

type AuthenticationType

type AuthenticationType string

AuthenticationType is the authentication mode of a deployment, discovered from GET /configs/auth.

type Client

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

Client is a client for the Keys&More KMS HTTP API. Construct it with NewClient, then call Client.Connect once before any other method.

After Connect returns, the Client is safe for concurrent use by multiple goroutines. Connect itself must complete before concurrent calls start.

func NewClient

func NewClient(opts ...Option) *Client

NewClient creates a Client configured by the given options. It performs no I/O; call Client.Connect to authenticate against the server.

Example
package main

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

	kmssdk "github.com/incert-kms/kms-sdk-go"
)

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

	client := kmssdk.NewClient(
		kmssdk.WithBaseURL("https://kms.example.com/kms"),
		kmssdk.WithUsernameAndPassword(os.Getenv("KMS_USERNAME"), os.Getenv("KMS_PASSWORD")),
	)
	if err := client.Connect(ctx); err != nil {
		log.Fatal(err)
	}

	vslots, err := client.GetVSlots(ctx)
	if err != nil {
		log.Fatal(err)
	}
	for _, vslot := range vslots {
		fmt.Println(vslot.ID, vslot.ProviderName)
	}
}

func (*Client) Connect

func (c *Client) Connect(ctx context.Context) error

Connect bootstraps authentication: it discovers the authentication configuration from the server's public /configs/auth endpoint, sets up the matching token backend, obtains a first token, and verifies authenticated access with a vslot listing. Supported modes: SELF_MANAGED (tokens issued by Keys&More itself) and OAUTH2 with provider KEYCLOAK (password grant).

func (*Client) CreateKey

func (c *Client) CreateKey(ctx context.Context, vslotId uuid.UUID, key KeyData) (KeyDataResponse, error)

CreateKey generates a new key in the given vslot (synchronously). The response carries the id of the new key and, for persistence NONE, the generated material in Values — that response is the only chance to capture such material, as it is not stored server-side.

Example
package main

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

	"github.com/google/uuid"
	kmssdk "github.com/incert-kms/kms-sdk-go"
)

func main() {
	ctx := context.Background()
	client := kmssdk.NewClient(
		kmssdk.WithUsernameAndPassword(os.Getenv("KMS_USERNAME"), os.Getenv("KMS_PASSWORD")),
	)
	if err := client.Connect(ctx); err != nil {
		log.Fatal(err)
	}

	vslotID := uuid.MustParse(os.Getenv("KMS_VSLOT_ID"))
	created, err := client.CreateKey(ctx, vslotID, kmssdk.KeyData{
		Name:        "example-key",
		Alg:         "AES256",
		Persistence: kmssdk.PersistenceExternal,
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("new key:", created.ID)
}

func (*Client) Crypto

func (c *Client) Crypto(ctx context.Context, op CryptoOperation, keyID uuid.UUID, request CryptoRequest) ([]byte, error)

Crypto performs an encrypt or decrypt operation with the given key and returns the resulting bytes. Only OperationEncrypt and OperationDecrypt are supported; other operations (sign, verify, derive, ...) use different media types and are not covered by this method.

Example
package main

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

	"github.com/google/uuid"
	kmssdk "github.com/incert-kms/kms-sdk-go"
)

func main() {
	ctx := context.Background()
	client := kmssdk.NewClient(
		kmssdk.WithUsernameAndPassword(os.Getenv("KMS_USERNAME"), os.Getenv("KMS_PASSWORD")),
	)
	if err := client.Connect(ctx); err != nil {
		log.Fatal(err)
	}

	keyID := uuid.MustParse(os.Getenv("KMS_KEY_ID"))
	iv := []byte("0123456789ab") // 12-byte GCM nonce; never reuse with the same key

	ciphertext, err := client.Crypto(ctx, kmssdk.OperationEncrypt, keyID, kmssdk.CryptoRequest{
		Data:       []byte("secret message"),
		Algorithm:  "AES_GCM",
		Attributes: map[string]any{"iv": iv},
	})
	if err != nil {
		log.Fatal(err)
	}

	plaintext, err := client.Crypto(ctx, kmssdk.OperationDecrypt, keyID, kmssdk.CryptoRequest{
		Data:       ciphertext,
		Algorithm:  "AES_GCM",
		Attributes: map[string]any{"iv": iv},
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(plaintext))
}

func (*Client) DeleteKey

func (c *Client) DeleteKey(ctx context.Context, keyID uuid.UUID) error

DeleteKey permanently deletes a key by posting the DELETED lifecycle state: the server immediately removes both the key material and its metadata.

func (*Client) FindKeys

func (c *Client) FindKeys(ctx context.Context, vslotId uuid.UUID, filter KeyFilter) ([]KeySearchResult, error)

FindKeys lists the keys of the given vslot matching the filter, most recently created first, iterating server pages transparently. Zero-valued filter fields are ignored.

func (*Client) GetKey

func (c *Client) GetKey(ctx context.Context, keyId uuid.UUID) (KeyDetail, error)

GetKey fetches the full representation of a key by its id.

func (*Client) GetKeys

func (c *Client) GetKeys(ctx context.Context, vslotId uuid.UUID) ([]KeySearchResult, error)

GetKeys lists all keys of the given vslot. It is shorthand for Client.FindKeys with an empty filter.

func (*Client) GetVSlots

func (c *Client) GetVSlots(ctx context.Context) ([]Vslot, error)

GetVSlots lists all vslots visible to the authenticated user, iterating server pages transparently.

func (*Client) Logout added in v1.1.0

func (c *Client) Logout(ctx context.Context) error

Logout invalidates the client's cached tokens. On SELF_MANAGED deployments the access and refresh tokens are also deactivated server-side (POST /auth/token/logout); on OAuth2 deployments the cached token is only dropped locally. Calling Logout on a client that never connected is a no-op. Further API calls after Logout re-authenticate with the stored credentials.

func (*Client) Sign added in v1.2.0

func (c *Client) Sign(ctx context.Context, keyID uuid.UUID, request SignRequest) ([]byte, error)

Sign signs data with the given key and returns the signature bytes. The algorithm and its parameters come from the request; see SignRequest.

func (*Client) Verify added in v1.2.0

func (c *Client) Verify(ctx context.Context, keyID uuid.UUID, request SignRequest) (bool, error)

Verify checks a signature with the given key. The signature to verify goes in request.Attributes.Signature; the result reports validity — a wrong signature yields (false, nil), not an error (SignatureVerifiedResponseModel).

type Config

type Config struct {
	UniverseAsUsernamePrefix *bool              `json:"universeAsUsernamePrefix"`
	Type                     AuthenticationType `json:"type"`
	OAuth2                   *OAuth2Config      `json:"oauth2,omitempty"`
}

Config is the authentication configuration returned by the server's public /configs/auth endpoint (AuthenticationConfigModel).

type CryptoAlgorithm

type CryptoAlgorithm struct {
	Algorithm   string         `json:"algorithm,omitempty"`
	Description string         `json:"description,omitempty"`
	KeyTypes    []string       `json:"keyTypes,omitempty"`
	KeyUsage    []string       `json:"keyUsage,omitempty"`
	Params      map[string]any `json:"params,omitempty"`
}

CryptoAlgorithm describes one algorithm supported by a key (CryptoAlgorithmModel): the identifier to pass in operation requests, the key types and usages it applies to, and (via Params) the attribute keys it consumes, e.g. "iv".

type CryptoOperation

type CryptoOperation string

CryptoOperation selects the cryptographic operation performed by Client.Crypto.

const (
	OperationEncrypt CryptoOperation = "encrypt"
	OperationDecrypt CryptoOperation = "decrypt"
)

Supported crypto operations.

type CryptoRequest

type CryptoRequest struct {
	Data       []byte         `json:"data"`
	Algorithm  string         `json:"algorithm"`
	Attributes map[string]any `json:"attributes,omitempty"`
}

CryptoRequest is the request body of an encrypt/decrypt operation (EncryptDataModel). Data carries the plaintext (encrypt) or ciphertext (decrypt); Algorithm is an identifier from the key's SupportedAlgorithms (e.g. "AES_GCM", "AES_CBC_PKCS7", "RSA_OAEP_SHA512").

Attributes carries the algorithm-specific parameters named by the key's CryptoAlgorithm.Params, for example:

map[string]any{"iv": iv}                 // AES_CBC*, AES_GCM ([]byte encodes as base64)
map[string]any{"iv": nonce, "counter": 1} // AES_CTR
map[string]any{"iv": nonce, "aad": aad}   // AES_GCM with additional authenticated data
map[string]any{"label": label}            // RSA_OAEP_* (optional OAEP label)

type KeyData added in v1.1.0

type KeyData struct {
	Name          string            `json:"name,omitempty"`
	Type          string            `json:"type,omitempty"`
	UseAttributes *KeyUseAttributes `json:"useAttributes,omitempty"`
	Alg           string            `json:"alg,omitempty"`
	Attributes    map[string]string `json:"attributes,omitempty"`
	AttributesP11 map[string]string `json:"attributesP11,omitempty"`
	ValidFrom     time.Time         `json:"validFrom,omitzero"`
	ValidTo       time.Time         `json:"validTo,omitzero"`
	Labels        map[string]string `json:"labels,omitempty"`
	LogLevelID    *uuid.UUID        `json:"logLevelId,omitempty"`
	Values        []KeyValue        `json:"values,omitempty"`
	Persistence   string            `json:"persistence,omitempty"`
	State         string            `json:"state,omitempty"`
	Data          []byte            `json:"data,omitempty"`
}

KeyData is the request body for key generation via Client.CreateKey (KeyDataModel). For generation, Values is usually omitted; with Persistence == PersistenceNone it describes how the generated material should be returned (wrapped).

type KeyDataResponse added in v1.1.0

type KeyDataResponse struct {
	ID     uuid.UUID  `json:"id"`
	Values []KeyValue `json:"values,omitempty"`
}

KeyDataResponse is the result of a key creation (KeyDataResponseModel): the id of the new key and, when requested (persistence NONE), the exported values.

type KeyDetail

type KeyDetail struct {
	ID                  uuid.UUID         `json:"id,omitzero"`
	AliasID             *uuid.UUID        `json:"aliasId,omitempty"`
	Type                string            `json:"type,omitempty"`
	UseAttributes       *KeyUseAttributes `json:"useAttributes,omitempty"`
	IDProvider          []byte            `json:"idProvider,omitempty"`
	IDUser              []byte            `json:"idUser,omitempty"`
	Name                string            `json:"name,omitempty"`
	VslotID             uuid.UUID         `json:"vslotId,omitzero"`
	Alg                 string            `json:"alg,omitempty"`
	KeySize             *int              `json:"keySize,omitempty"`
	Attributes          map[string]string `json:"attributes,omitempty"`
	AttributesP11       map[string]string `json:"attributesP11,omitempty"`
	Labels              map[string]string `json:"labels,omitempty"`
	ValidFrom           time.Time         `json:"validFrom,omitzero"`
	ValidTo             time.Time         `json:"validTo,omitzero"`
	KeyValues           []KeyValue        `json:"keyValues,omitempty"`
	KeyLinks            []uuid.UUID       `json:"keyLinks,omitempty"`
	Rotated             bool              `json:"rotated,omitempty"`
	KCV                 []byte            `json:"kcv,omitempty"`
	Persistence         string            `json:"persistence,omitempty"`
	State               string            `json:"state,omitempty"`
	Enabled             bool              `json:"enabled,omitempty"`
	LogLevelID          *uuid.UUID        `json:"logLevelId,omitempty"`
	CreationDate        time.Time         `json:"creationDate,omitzero"`
	CreatedBy           string            `json:"createdBy,omitempty"`
	SupportedAlgorithms []CryptoAlgorithm `json:"supportedAlgorithms,omitempty"`
}

KeyDetail is the full representation of a key returned by Client.GetKey (KeyModel). Consult SupportedAlgorithms for the operations and attribute parameters the key supports, and UseAttributes for what it is allowed to do.

type KeyFilter

type KeyFilter struct {
	Name string
	ID   uuid.UUID
}

KeyFilter narrows a Client.FindKeys search. Zero-valued fields are ignored.

type KeySearchResult

type KeySearchResult struct {
	ID             uuid.UUID `json:"id,omitzero"`
	VslotID        uuid.UUID `json:"vslotId,omitzero"`
	Name           string    `json:"name,omitempty"`
	Alg            string    `json:"alg,omitempty"`
	AlgType        string    `json:"algType,omitempty"`
	Persistence    string    `json:"persistence,omitempty"`
	State          KeyState  `json:"state,omitzero"`
	IDProvider     []byte    `json:"idProvider,omitempty"`
	IDUser         []byte    `json:"idUser,omitempty"`
	KCV            []byte    `json:"kcv,omitempty"`
	ValidFrom      time.Time `json:"validFrom,omitzero"`
	ValidTo        time.Time `json:"validTo,omitzero"`
	CreationDate   time.Time `json:"creationDate,omitzero"`
	CreatedBy      string    `json:"createdBy,omitempty"`
	AttachedValues []string  `json:"attachedValues,omitempty"`
}

KeySearchResult is the list/search view of a key returned by Client.FindKeys and Client.GetKeys (KeySearchResultModel) — lighter than KeyDetail.

type KeyState

type KeyState struct {
	State   string `json:"state"`
	Enabled bool   `json:"enabled"`
}

KeyState is the lifecycle state of a key as reported in search results (KeyStateModel).

type KeyUseAttributes

type KeyUseAttributes struct {
	Extractable bool `json:"extractable"`
	Sign        bool `json:"sign"`
	Verify      bool `json:"verify"`
	Encrypt     bool `json:"encrypt"`
	Decrypt     bool `json:"decrypt"`
	Wrap        bool `json:"wrap"`
	Unwrap      bool `json:"unwrap"`
	Derive      bool `json:"derive"`
}

KeyUseAttributes are the PKCS#11-style usage flags of a key (KeyUseAttributesModel). Operations are rejected when the corresponding flag is off. When the struct is present in a request, all eight flags are serialized so that explicit false values reach the server.

type KeyValue

type KeyValue struct {
	ID                      uuid.UUID         `json:"id,omitzero"`
	Type                    string            `json:"type,omitempty"`
	Value                   []byte            `json:"value,omitempty"`
	Format                  string            `json:"format,omitempty"`
	FormatParameters        map[string]string `json:"formatParameters,omitempty"`
	Password                string            `json:"password,omitempty"`
	WrapKey                 []byte            `json:"wrapKey,omitempty"`
	WrapKeyFormat           string            `json:"wrapKeyFormat,omitempty"`
	WrapKeyFormatParameters map[string]string `json:"wrapKeyFormatParameters,omitempty"`
	WrapKeyID               *uuid.UUID        `json:"wrapKeyId,omitempty"`
	WrappingKey             *KeyDetail        `json:"wrappingKeyModel,omitempty"`
}

KeyValue is the envelope for a single piece of key material (KeyValueModel), used both to carry material and to describe requested export formats and wrapping.

type KeycloakMode

type KeycloakMode string

KeycloakMode says whether Keys&More manages the Keycloak users itself (MANAGED) or users are administered directly in Keycloak (NON_MANAGED).

type OAuth2ClaimsConfig added in v1.1.0

type OAuth2ClaimsConfig struct {
	Username string `json:"username"`
	Universe string `json:"universe"`
	Policy   string `json:"policy"`
}

OAuth2ClaimsConfig maps JWT claim paths to the KMS identity values (username, universe, policy).

type OAuth2Config added in v1.1.0

type OAuth2Config struct {
	Provider OAuth2Provider        `json:"provider"`
	Claims   OAuth2ClaimsConfig    `json:"claims"`
	Keycloak *OAuth2KeycloakConfig `json:"keycloak,omitempty"`
	Other    *OAuth2OtherConfig    `json:"other,omitempty"`
}

OAuth2Config carries the OAuth2 coordinates when Config.Type is OAUTH2.

type OAuth2KeycloakConfig added in v1.1.0

type OAuth2KeycloakConfig struct {
	URL      string       `json:"url"`
	Realm    string       `json:"realm"`
	ClientID string       `json:"clientId"`
	Mode     KeycloakMode `json:"mode"`
}

OAuth2KeycloakConfig is set when the provider is KEYCLOAK. URL may be absolute, root-relative, or relative to the KMS base URL; Connect resolves it accordingly.

type OAuth2OtherConfig added in v1.1.0

type OAuth2OtherConfig struct {
	URL                   string `json:"url"`
	ClientID              string `json:"clientId"`
	Audience              string `json:"audience"`
	TokenEndpoint         string `json:"tokenEndpoint"`
	AuthorizationEndpoint string `json:"authorizationEndpoint"`
	LogoutEndpoint        string `json:"logoutEndpoint"`
	RedirectURI           string `json:"redirectUri"`
	AccessTokenProperty   string `json:"accessTokenProperty"`
}

OAuth2OtherConfig is set when the provider is OTHER (generic OAuth2/OIDC, e.g. Auth0 or Okta). Not yet consumed by this SDK.

type OAuth2Provider added in v1.1.0

type OAuth2Provider string

OAuth2Provider identifies the IdP family of an OAuth2 deployment.

type Option

type Option func(*Client)

Option configures a Client during NewClient.

func WithBaseURL

func WithBaseURL(url string) Option

WithBaseURL overrides the default base URL of the Keys&More deployment, e.g. "https://kms.example.com/kms". The /api prefix common to every REST path is appended internally and must NOT be part of the URL; a trailing slash is removed.

func WithHTTPClient

func WithHTTPClient(hc *http.Client) Option

WithHTTPClient supplies a custom *http.Client, replacing the SDK-managed one. It takes precedence over WithTimeout and WithTLSSkipVerify: configure timeouts and TLS on the custom client directly.

func WithLogger

func WithLogger(logger *slog.Logger) Option

WithLogger supplies a *slog.Logger for diagnostic output; without it the SDK is silent.

func WithTLSSkipVerify

func WithTLSSkipVerify() Option

WithTLSSkipVerify disables TLS certificate verification on the SDK-managed HTTP client. Development only — never use it in production. Ignored (with a logged warning) when WithHTTPClient is used.

func WithTimeout added in v1.1.0

func WithTimeout(d time.Duration) Option

WithTimeout sets the overall timeout of the SDK-managed HTTP client (default 10s). It covers the full request including reading the response body; raise it when running synchronous key generation against slow providers. Ignored when WithHTTPClient is used.

func WithUsernameAndPassword

func WithUsernameAndPassword(username, password string) Option

WithUsernameAndPassword sets the credentials used for the OAuth2 password grant during Client.Connect.

type SignRequest added in v1.2.0

type SignRequest struct {
	Data       []byte               `json:"data"`
	Algorithm  string               `json:"algorithm"`
	Attributes *SignatureAttributes `json:"attributes,omitempty"`
}

SignRequest is the request body of a sign or verify operation (SignatureDataModel). Data carries the payload — or, for the *_RAW algorithms, the caller-prepared digest; Algorithm is an identifier from the key's SupportedAlgorithms (e.g. "RSA_PKCS_SHA256", "EC_SHA256", "HMAC_SHA256", "AES_CMAC", "RSA_PKCS-PSS_RAW").

type SignatureAttributes added in v1.2.0

type SignatureAttributes struct {
	Signature  []byte `json:"signature,omitempty"`
	HashAlg    *int   `json:"hashAlg,omitempty"`
	MGF        *int   `json:"mgf,omitempty"`
	SaltLength *int   `json:"saltLength,omitempty"`
}

SignatureAttributes carries the algorithm-specific signature parameters. Verify puts the signature to check in Signature; RSA-PSS over a caller-prepared digest (RSA_PKCS-PSS_RAW) uses HashAlg/MGF/SaltLength with numeric PKCS#11 codes (e.g. HashAlg 592 = CKM_SHA256, MGF 2 = CKG_MGF1_SHA256), per 05-crypto-operations.md.

type TokenSource added in v1.1.0

type TokenSource interface {
	GetToken(ctx context.Context) (string, error)
}

TokenSource supplies a currently valid bearer token for API requests. Implementations must be safe for concurrent use.

type Vslot

type Vslot struct {
	ID           uuid.UUID  `json:"id"`
	Provider     uuid.UUID  `json:"provider"`
	ProviderName string     `json:"providerName"`
	LogLevelID   *uuid.UUID `json:"logLevelId"`
	Universe     string     `json:"universe"`
	CreationDate time.Time  `json:"creationDate"`
	CreatedBy    string     `json:"createdBy"`
}

Vslot is a virtual slot: the container in which keys live, bound to one crypto provider and one universe (VSlotSearchResultModel).

Directories

Path Synopsis
Command example exercises the SDK end-to-end against a real deployment: connect, create an AES key, encrypt/decrypt a message, and delete the key.
Command example exercises the SDK end-to-end against a real deployment: connect, create an AES key, encrypt/decrypt a message, and delete the key.

Jump to

Keyboard shortcuts

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