kmssdk

package module
v1.4.0 Latest Latest
Warning

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

Go to latest
Published: Sep 7, 2026 License: Apache-2.0 Imports: 22 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)
    • OAuth2 with a generic OIDC provider (provider: OTHER — Auth0, Okta): password grant against the discovered token endpoint, optional client secret for confidential clients
    • 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 — by name, id, alias, type, algorithm, persistence, state, enabled)
    • State management (forward-only transitions, enable/disable) and deletion (permanent removal via the DELETED lifecycle state)
    • Rotation (returns the successor key id) and stable aliases across rotations
    • Import, export (clear or wrapped formats), attach provider-side keys, edit use attributes
    • Derive new keys and transport keys between vslots
    • Query and clean up asynchronous process records
  • 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
    • ICAO SOD, RFC 3161 timestamp and PDF signing (one method per media type)
    • Certificate operations on keys: self-signed or CA-issued generation, CSR generation, certificate upload

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 password grant / self-managed login.
WithClientSecret(secret) OAuth2 client secret for confidential clients (used with provider: OTHER).
WithTimeout(d) Overall HTTP timeout of the SDK-managed client (default 10s).
WithTLSCACert(file) PEM file of trust anchors for the SDK-managed client, replacing the system roots (the identity provider's token requests use the same transport).
WithTLSCAPath(dir) Directory walked recursively for PEM trust anchors; files without certificates are skipped; combines with WithTLSCACert.
WithTLSClientCert(certFile, keyFile) Client certificate and private key for mutual TLS.
WithTLSServerName(name) Server name for SNI and certificate verification.
WithTLSConfig(cfg) Base *tls.Config (cloned) that the other WithTLS* options layer onto — e.g. to keep the system roots via x509.SystemCertPool().
WithTLSSkipVerify() Disable TLS verification (development only).
WithHTTPClient(hc) Supply a custom *http.Client; takes precedence over WithTimeout and every WithTLS* option.
WithLogger(l) Supply a *slog.Logger; without it the SDK is silent.

TLS files are read by NewClient; a load failure is returned by Connect as tls configuration: ... before any request is made.

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.
  • OAUTH2 with a generic OIDC provider (OTHER — e.g. Auth0 or Okta): the password grant runs against the token endpoint from discovery; confidential clients supply WithClientSecret.

In all 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:

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},
})

Client.Sign and Client.Verify cover the signature registry; Client.SignSOD, Client.SignTimestamp and Client.SignPDF produce ICAO SODs, RFC 3161 timestamp responses and signed PDFs; and Client.GenerateCertificate, Client.GenerateCSR and Client.UpdateCertificate handle certificates on a key.

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 (
	AsyncProcessInProgress = "IN_PROGRESS"
	AsyncProcessFinished   = "FINISHED"
	AsyncProcessError      = "ERROR"
)

Async process statuses (AsyncProcess.Status).

View Source
const (
	AuthenticationTypeOAuth2      AuthenticationType = "OAUTH2"
	AuthenticationTypeSelfManaged AuthenticationType = "SELF_MANAGED"
	OAuth2ProviderKeycloak        OAuth2Provider     = "KEYCLOAK"
	OAuth2ProviderOther           OAuth2Provider     = "OTHER"
	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.

View Source
const (
	KeyValueTypeSecret      = "SECRET"
	KeyValueTypePublic      = "PUBLIC"
	KeyValueTypePrivate     = "PRIVATE"
	KeyValueTypeCertificate = "CERTIFICATE"
	KeyValueTypeRaw         = "RAW"
	KeyValueTypeMulti       = "MULTI" // container formats carrying several values, e.g. PKCS#12
)

Key value types (KeyValueModel.type): the kind of material a KeyValue carries or requests.

View Source
const (
	KeyFormatNone          = "NONE"
	KeyFormatPlain         = "PLAIN"
	KeyFormatPKCS8         = "PKCS8"
	KeyFormatX509          = "X509"
	KeyFormatPKCS12        = "PKCS12"
	KeyFormatOpenSSLPublic = "OPENSSL_PUBLIC"
	KeyFormatWrapped       = "WRAPPED"
	KeyFormatAESCBCPad     = "AES_CBC_PAD"
	KeyFormatAESGCM        = "AES_GCM"

	KeyFormatAESWrapped                    = "AES_WRAPPED"
	KeyFormatAESKWPWrapped                 = "AES_KWP_WRAPPED" //nolint:gosec // server key-format identifier, not a credential
	KeyFormatRSAESOAEPSHA256Wrapped        = "RSAES_OAEP_SHA_256_WRAPPED"
	KeyFormatRSAESOAEPSHA256AESWrapped     = "RSAES_OAEP_SHA_256_AES_WRAPPED"
	KeyFormatRSAESOAEPSHA1Wrapped          = "RSAES_OAEP_SHA_1_WRAPPED"
	KeyFormatRSAESPKCS1V15Wrapped          = "RSAES_PKCS1_V1_5_WRAPPED"
	KeyFormatRSAESPKCS1V15AESCBCPadWrapped = "RSAES_PKCS1_V1_5_AES_CBC_PAD_WRAPPED"
	KeyFormatRSAESPKCS1V15AESGCMWrapped    = "RSAES_PKCS1_V1_5_AES_GCM_WRAPPED"
	KeyFormatQPMLDSAWrapAESKWP             = "QP_MLDSA_WRAP_AESKWP" // quantum-proof: ML-DSA-authenticated AES-KWP
)

Key value formats (KeyValueModel.format and wrapKeyFormat). Clear formats apply to public material; secret and private material leaves the provider only in one of the wrapped formats, with the wrapping key given as an external public key (KeyValue.WrapKey) or an internal key reference (KeyValue.WrapKeyID).

Variables

View Source
var ErrSuccessorUnknown = errors.New("key rotated but successor not identified")

ErrSuccessorUnknown reports that a rotation succeeded but the successor key could not be identified from the rotated key's key links; re-query the key or use an alias to reach the current generation.

Functions

func WithCorrelationID added in v1.3.0

func WithCorrelationID(ctx context.Context, id string) context.Context

WithCorrelationID returns a context that makes the SDK send the given id as the X-Correlation-Id header on every request issued with it. Servers >= 4.3.0.4 echo the id on the response (see APIError.CorrelationID) and reference it in internal-error messages; older servers ignore the header. Without a caller-supplied id the server generates one itself. The same id is reused when a request is replayed after a 401.

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"`
	// CorrelationID is the X-Correlation-Id header echoed on the response by
	// servers >= 4.3.0.4 (empty on older servers). It identifies the request
	// in the server logs; internal-error messages reference it. It comes from
	// the response header, never from the body.
	CorrelationID string `json:"-"`
}

APIError is returned for every HTTP response with status >= 400 — from both the KMS API and the OAuth2 token endpoint — and for the non-standard, success-shaped status 260 (INTERNAL_KEY_ATTRIBUTES_DIFFERENT). 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 AsyncProcess added in v1.3.0

type AsyncProcess struct {
	ID      uuid.UUID `json:"id,omitzero"`
	Status  string    `json:"status,omitempty"`
	KeyID   uuid.UUID `json:"keyId,omitzero"`
	VslotID uuid.UUID `json:"vslotId,omitzero"`
	// Process names the operation the record tracks, e.g. "encrypt".
	Process string `json:"process,omitempty"`
	// ProcessJSONRequest and ProcessJSONResponse carry the operation's JSON
	// request and response bodies as strings; the response is present once
	// Status is FINISHED, unless it was stored on file storage
	// (ProcessResponseEmbeddedInDB false).
	ProcessJSONRequest          string    `json:"processJsonRequest,omitempty"`
	ProcessJSONResponse         string    `json:"processJsonResponse,omitempty"`
	DataFileName                string    `json:"dataFileName,omitempty"`
	DataEmbeddedInDB            bool      `json:"dataEmbeddedInDb,omitempty"`
	ProcessResponseEmbeddedInDB bool      `json:"processResponseEmbeddedInDb,omitempty"`
	CreatedBy                   string    `json:"createdBy,omitempty"`
	CreationDate                time.Time `json:"creationDate,omitzero"`
	StartDate                   time.Time `json:"startDate,omitzero"`
	EndDate                     time.Time `json:"endDate,omitzero"`
	Failures                    int       `json:"failures,omitempty"`
	// LastFailureReason is reset when the process is restarted.
	LastFailureReason string `json:"lastFailureReason,omitempty"`
}

AsyncProcess is the tracking record of a plugin operation executed asynchronously (AsyncKeyProcessModel / AsyncVslotProcessModel). Exactly one of KeyID and VslotID is set, matching the endpoint family the record came from. List results omit the ProcessJSON* fields; fetch a single process to see them. Finished records are retained for a deployment-configured period (24 hours by default), so poll promptly.

type AuthenticationType

type AuthenticationType string

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

type CertificateRequest added in v1.3.0

type CertificateRequest struct {
	CommonName       string `json:"commonName,omitempty"`
	OrganisationUnit string `json:"organisationUnit,omitempty"`
	OrganisationName string `json:"organisationName,omitempty"`
	LocalityName     string `json:"localityName,omitempty"`
	StateName        string `json:"stateName,omitempty"`
	CountryCode      string `json:"countryCode,omitempty"` // ISO 3166-1 alpha-2, e.g. "LU"
	EmailAddress     string `json:"emailAddress,omitempty"`
	// IssuerKeyID selects an issuer key whose crypto provider is a CA;
	// IssuerAttributes carries the CA coordinates the provider needs (e.g.
	// EJBCA end-entity and profile names).
	IssuerKeyID        uuid.UUID      `json:"issuerKeyId,omitzero"`
	IssuerAttributes   map[string]any `json:"issuerAttributes,omitempty"`
	SignatureAlgorithm string         `json:"signatureAlgorithm,omitempty"`
	ValidFrom          time.Time      `json:"validFrom,omitzero"`
	ValidTo            time.Time      `json:"validTo,omitzero"`
	SerialNumber       *int           `json:"serialNumber,omitempty"`
	Challenge          string         `json:"challenge,omitempty"`
	UnstructuredName   string         `json:"unstructuredName,omitempty"`
	// Encoded is the X.509 certificate (DER) uploaded by a certificate
	// update.
	Encoded []byte `json:"encoded,omitempty"`
	// StoreInDB additionally stores the certificate in the KMS database
	// regardless of the key's persistence (servers >= 4.3.2.1; meaningful for
	// INTERNAL keys only, whose certificates otherwise live in the provider).
	StoreInDB bool   `json:"storeInDb,omitempty"`
	Data      []byte `json:"data,omitempty"`
}

CertificateRequest is the request body of the certificate operations on a key (CertificateDataModel). Client.GenerateCertificate uses the subject-DN, validity, serial and issuer fields (self-signed when IssuerKeyID is empty); Client.GenerateCSR additionally honors Challenge and UnstructuredName; Client.UpdateCertificate builds its own request from Encoded and StoreInDB. Field names and JSON tags follow the server's British spellings.

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 network I/O; the only files it reads are the certificates and keys named by the WithTLS* options, and a failure to load them is deferred to Client.Connect, which reports it before contacting 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) AttachKey added in v1.3.0

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

AttachKey registers a key that already exists inside the vslot's crypto provider (KeyDataModel). The provider-side key is selected via key.Attributes; the attribute name is provider-dependent: "prov_id" (generic; for PKCS#11 the CKA_ID as a hex string), "hsm_id" (PKCS#11 HSMs) or "kms_id" (key UUID on a remote KMS). HTTP 260 is reported as for Client.ImportKey.

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 or OTHER (generic OIDC, e.g. Auth0 or Okta), both via the password grant. A TLS option that failed to load in NewClient is reported here first.

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) CreateKeyAlias added in v1.3.0

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

CreateKeyAlias creates a new alias pointing at the given key and returns it (AliasKeySearchResultModel). Re-point an existing alias with Client.MoveKeyAlias.

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) DeleteKeyAsyncProcess added in v1.3.0

func (c *Client) DeleteKeyAsyncProcess(ctx context.Context, id uuid.UUID) error

DeleteKeyAsyncProcess deletes the stored content (request, response, output) of a finished key-scoped async process.

func (*Client) DeleteVSlotAsyncProcess added in v1.3.0

func (c *Client) DeleteVSlotAsyncProcess(ctx context.Context, id uuid.UUID) error

DeleteVSlotAsyncProcess deletes the stored content (request, response, output) of a finished vslot-scoped async process.

func (*Client) DeriveKey added in v1.3.0

func (c *Client) DeriveKey(ctx context.Context, keyID uuid.UUID, request DeriveRequest) (KeyDataResponse, error)

DeriveKey derives a new key (or transient value) from an existing key and returns the derived key's id and, for persistence NONE, its values (KeyDataResponseModel). Derivation is gated by the base key's derive use attribute.

func (*Client) EditKey added in v1.3.0

func (c *Client) EditKey(ctx context.Context, keyID uuid.UUID, useAttributes KeyUseAttributes) (KeyDataResponse, error)

EditKey applies the given use-attribute flags to the key through the provider plugin (KeyDataModel — the server processes only useAttributes). Unlike a metadata-only update, the change propagates into the crypto provider; for INTERNAL keys some transitions are one-way (providers commonly forbid flipping extractable back to true) and fail with ErrCodeBadRequest. All eight flags are always sent.

func (*Client) ExportKey added in v1.3.0

func (c *Client) ExportKey(ctx context.Context, keyID uuid.UUID, values []KeyValue) (KeyDataResponse, error)

ExportKey exports key values in the formats described by values — each entry names the requested Type and Format, plus WrapKey or WrapKeyID for the wrapped formats (KeyDataModel). Public values may leave in clear formats; secret and private values only wrapped, and only when the key is extractable. The exported material is carried in the response Values.

func (*Client) FindKeyAliases added in v1.3.0

func (c *Client) FindKeyAliases(ctx context.Context, filter KeyAliasFilter) ([]KeyAlias, error)

FindKeyAliases lists the key aliases matching the filter, iterating server pages transparently (AliasKeySearchResultModel). Zero-valued filter fields are ignored.

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) GenerateCSR added in v1.3.0

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

GenerateCSR generates a PKCS#10 certificate signing request for the key and returns it DER-encoded (CertificateResponseDataModel).

func (*Client) GenerateCertificate added in v1.3.0

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

GenerateCertificate generates an X.509 certificate for the key — self-signed, or issued through IssuerKeyID/IssuerAttributes when the issuer key's crypto provider is a CA — and returns the DER-encoded certificate (CertificateResponseDataModel). Certificates apply to asymmetric keys; where the certificate is stored follows the key's persistence unless request.StoreInDB is set.

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) GetKeyAsyncProcess added in v1.3.0

func (c *Client) GetKeyAsyncProcess(ctx context.Context, id uuid.UUID) (AsyncProcess, error)

GetKeyAsyncProcess fetches one key-scoped async process record, including its request and response bodies (AsyncKeyProcessModel). Poll it until Status is AsyncProcessFinished or AsyncProcessError; the SDK deliberately provides no polling loop.

func (*Client) GetKeyAsyncProcesses added in v1.3.0

func (c *Client) GetKeyAsyncProcesses(ctx context.Context) ([]AsyncProcess, error)

GetKeyAsyncProcesses lists the async processes of key-scoped plugin operations, iterating server pages transparently (AsyncKeyProcessSearchResultModel).

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) GetVSlotAsyncProcess added in v1.3.0

func (c *Client) GetVSlotAsyncProcess(ctx context.Context, id uuid.UUID) (AsyncProcess, error)

GetVSlotAsyncProcess fetches one vslot-scoped async process record, including its request and response bodies (AsyncVslotProcessModel).

func (*Client) GetVSlotAsyncProcesses added in v1.3.0

func (c *Client) GetVSlotAsyncProcesses(ctx context.Context) ([]AsyncProcess, error)

GetVSlotAsyncProcesses lists the async processes of vslot-scoped plugin operations, iterating server pages transparently (AsyncVslotProcessSearchResultModel).

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) ImportKey added in v1.3.0

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

ImportKey imports caller-supplied key material as a new key in the given vslot (KeyDataModel): the material travels in key.Values, plain or wrapped. An HTTP 260 consistency warning — attributes of the imported material differ from the request — surfaces as an APIError with Code ErrCodeInternalKeyAttributesDiffer; the key may nonetheless have been created, so re-query to inspect it.

func (*Client) ImportKeyValues added in v1.3.0

func (c *Client) ImportKeyValues(ctx context.Context, keyID uuid.UUID, values []KeyValue) (KeyDataResponse, error)

ImportKeyValues imports material into an existing key — filling an empty IMPORTED shell, or replacing a value referenced by its KeyValue.ID (KeyDataModel). HTTP 260 is reported as for Client.ImportKey.

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) MoveKeyAlias added in v1.3.0

func (c *Client) MoveKeyAlias(ctx context.Context, aliasID, fromKeyID, toKeyID uuid.UUID) (KeyAlias, error)

MoveKeyAlias re-points an existing alias from one key to another (AliasKeyModel): fromKeyID is the key the alias currently references, toKeyID the new target. It returns the updated alias.

func (*Client) RotateKey added in v1.3.0

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

RotateKey deactivates the key and creates a linked successor, returning the successor's id. The rotate endpoint itself returns an empty response, so the successor is discovered by comparing the key's key links before and after the rotation (KeyModel). When the rotation succeeded but no single new link appeared, the returned error matches ErrSuccessorUnknown — the rotation itself has still happened.

func (*Client) SetKeyState added in v1.3.0

func (c *Client) SetKeyState(ctx context.Context, keyID uuid.UUID, state string, enabled bool) error

SetKeyState advances the lifecycle state of a key and/or toggles its enabled flag (KeyStateModel). The lifecycle is strictly forward-only (PROVISIONED → ACTIVE → DEACTIVATED → DESTROYED → DELETED); an illegal transition fails with ErrCodeKeyLifecycle (HTTP 500). To toggle enabled within the current state, pass the current state unchanged.

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) SignPDF added in v1.3.0

func (c *Client) SignPDF(ctx context.Context, keyID uuid.UUID, pdf []byte) ([]byte, error)

SignPDF signs a PDF document with the given key and returns the signed PDF bytes. The request body is a plain data envelope carrying the PDF; the operation is deployment-documented and absent from some API exports.

func (*Client) SignSOD added in v1.3.0

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

SignSOD signs an ICAO Document Security Object with the given key and returns the assembled, encoded SOD (SignatureDataResponseModel). It shares the sign endpoint with Client.Sign but uses its own media type and request schema.

func (*Client) SignTimestamp added in v1.3.0

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

SignTimestamp produces an RFC 3161 timestamp response (DER TimeStampResp) signed by the given key (SignatureDataResponseModel). The key must carry a certificate; deployment configuration constrains accepted policies and extensions.

func (*Client) TransportKey added in v1.3.0

func (c *Client) TransportKey(ctx context.Context, keyID, targetVslotID uuid.UUID) (KeyDataResponse, error)

TransportKey copies the key into another vslot, re-wrapping it for the destination crypto provider (KeyTransportModel). Feasibility depends on the source and destination providers.

func (*Client) UpdateCertificate added in v1.3.0

func (c *Client) UpdateCertificate(ctx context.Context, keyID uuid.UUID, certificate []byte, storeInDB bool) ([]byte, error)

UpdateCertificate uploads a certificate (DER) for the key — typically the one received from a CA for a previously generated CSR (CertificateDataModel, fields encoded and storeInDb only). storeInDB additionally stores the certificate in the KMS database regardless of the key's persistence (servers >= 4.3.2.1; meaningful for INTERNAL keys only).

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 DeriveRequest added in v1.3.0

type DeriveRequest struct {
	Algorithm    string            `json:"algorithm"`
	KeyAlgorithm string            `json:"keyAlgorithm,omitempty"`
	Persistence  string            `json:"persistence,omitempty"`
	Attributes   map[string]string `json:"attributes,omitempty"`
	Values       []KeyValue        `json:"values,omitempty"`
	Data         []byte            `json:"data,omitempty"`
}

DeriveRequest is the request body of a key derivation (DeriveDataModel). Algorithm is a derivation identifier from the base key's supported algorithms (e.g. "DERIVE_SHA256", "DERIVE_AES_CBC", "DERIVE_KCV"); KeyAlgorithm sets the algorithm of the derived key. Attributes carries string-valued parameters such as "label" (name of the derived key), "data" (base64 derivation input, required for the DERIVE_AES_* algorithms) and "iv" (DERIVE_AES_CBC) — unlike CryptoRequest.Attributes, the wire model maps to strings, not arbitrary values. With Persistence == PersistenceNone, Values describes how the derived material is returned (e.g. wrapped).

type KeyAlias added in v1.3.0

type KeyAlias struct {
	ID           uuid.UUID `json:"id,omitzero"`
	KeyID        uuid.UUID `json:"key,omitzero"` // the wire field is "key"
	Universe     string    `json:"universe,omitempty"`
	CreationDate time.Time `json:"creationDate,omitzero"`
	CreatedBy    string    `json:"createdBy,omitempty"`
}

KeyAlias is a stable UUID handle that can be re-pointed from one key to another, e.g. across rotations (AliasKeySearchResultModel).

type KeyAliasFilter added in v1.3.0

type KeyAliasFilter struct {
	ID    uuid.UUID // the alias id itself
	KeyID uuid.UUID // the key the alias currently points to
}

KeyAliasFilter narrows a Client.FindKeyAliases search. Zero-valued fields are ignored.

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
	// AliasID matches the key currently reachable under the given alias.
	AliasID uuid.UUID
	// Type filters by key type (a KeyType* constant).
	Type string
	// Alg filters by key algorithm, e.g. "AES256".
	Alg string
	// Persistence filters by persistence mode (a Persistence* constant).
	Persistence string
	// State filters by lifecycle state (a KeyState* constant).
	State string
	// Enabled filters by the enabled flag; nil means no filter (false is a
	// meaningful filter value).
	Enabled *bool
}

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). TokenEndpoint may be absolute or relative to URL; AccessTokenProperty names the token-response property carrying the usable token, in camel case (default "accessToken", e.g. "idToken" when the IdP's id_token is the one to use).

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 WithClientSecret added in v1.3.0

func WithClientSecret(secret string) Option

WithClientSecret sets the OAuth2 client secret sent to the identity provider's token endpoint. It is currently used only on deployments with provider OTHER (generic OIDC), where confidential clients (e.g. Auth0) require one; leave it unset for public clients.

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 every WithTLS* option (a warning is logged when both are given): 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 WithTLSCACert added in v1.4.0

func WithTLSCACert(path string) Option

WithTLSCACert sets the PEM file whose certificates become the trust anchors of the SDK-managed HTTP client, replacing the system roots. The same transport carries the identity provider's token requests, so those are verified against these anchors too. The file is read by NewClient; a read or parse failure is reported by Client.Connect before any request is made. Ignored (with a logged warning) when WithHTTPClient is used.

func WithTLSCAPath added in v1.4.0

func WithTLSCAPath(dir string) Option

WithTLSCAPath sets a directory of PEM files whose certificates become the trust anchors of the SDK-managed HTTP client, replacing the system roots. The directory is walked recursively; files without PEM certificates are skipped, and it is an error when no certificate is found at all. It combines with WithTLSCACert. Ignored (with a logged warning) when WithHTTPClient is used.

func WithTLSClientCert added in v1.4.0

func WithTLSClientCert(certFile, keyFile string) Option

WithTLSClientCert sets the PEM-encoded certificate and private key files the SDK-managed HTTP client presents for mutual TLS. Both must be given; they are loaded by NewClient and a failure is reported by Client.Connect. Ignored (with a logged warning) when WithHTTPClient is used.

func WithTLSConfig added in v1.4.0

func WithTLSConfig(cfg *tls.Config) Option

WithTLSConfig supplies a base *tls.Config for the SDK-managed HTTP client, for settings the other WithTLS* options do not cover (cipher suites, minimum version, in-memory certificates, ...). The config is cloned and the other WithTLS* options layer onto the clone: CA material is added to its RootCAs, the client certificate is appended to its Certificates, and the server name and skip-verify flag are set when given. A nil config is ignored. Ignored (with a logged warning) when WithHTTPClient is used.

func WithTLSServerName added in v1.4.0

func WithTLSServerName(name string) Option

WithTLSServerName sets the server name sent in the TLS handshake (SNI) and verified against the server certificate, for deployments reached through an address that differs from the certificate's names. Combined with WithTLSSkipVerify it only affects SNI. Ignored (with a logged warning) when WithHTTPClient is used.

func WithTLSSkipVerify

func WithTLSSkipVerify() Option

WithTLSSkipVerify disables TLS certificate verification on the SDK-managed HTTP client, including verification against the anchors from WithTLSCACert and WithTLSCAPath. 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 SignSODRequest added in v1.3.0

type SignSODRequest struct {
	Algorithm       string `json:"algorithm"`
	DigestAlgorithm string `json:"digestAlgorithm"`
	LDSVersion      string `json:"ldsVersion,omitempty"`
	UnicodeVersion  string `json:"unicodeVersion,omitempty"`
	DG1Hash         []byte `json:"dg1hash,omitempty"`
	DG2Hash         []byte `json:"dg2hash,omitempty"`
	DG3Hash         []byte `json:"dg3hash,omitempty"`
	DG4Hash         []byte `json:"dg4hash,omitempty"`
	DG5Hash         []byte `json:"dg5hash,omitempty"`
	DG6Hash         []byte `json:"dg6hash,omitempty"`
	DG7Hash         []byte `json:"dg7hash,omitempty"`
	DG8Hash         []byte `json:"dg8hash,omitempty"`
	DG9Hash         []byte `json:"dg9hash,omitempty"`
	DG10Hash        []byte `json:"dg10hash,omitempty"`
	DG11Hash        []byte `json:"dg11hash,omitempty"`
	DG12Hash        []byte `json:"dg12hash,omitempty"`
	DG13Hash        []byte `json:"dg13hash,omitempty"`
	DG14Hash        []byte `json:"dg14hash,omitempty"`
	DG15Hash        []byte `json:"dg15hash,omitempty"`
	DG16Hash        []byte `json:"dg16hash,omitempty"`
	Data            []byte `json:"data,omitempty"`
}

SignSODRequest is the request body of an ICAO Document Security Object signature (SignatureSodDataModel). Algorithm (a sign identifier supported by the key) and DigestAlgorithm (e.g. "SHA256" — correctness is the caller's responsibility) are required, and at least one data-group hash must be set. The server assembles and signs the SOD from the supplied hashes of ICAO Doc 9303 Data Groups 1–16.

type SignTimestampRequest added in v1.3.0

type SignTimestampRequest struct {
	Algorithm       string `json:"algorithm"`
	TSQ             []byte `json:"tsq,omitempty"`
	Digest          []byte `json:"digest,omitempty"`
	DigestAlgorithm string `json:"digestAlgorithm,omitempty"`
	Data            []byte `json:"data,omitempty"`
}

SignTimestampRequest is the request body of an RFC 3161 timestamp signature (SignatureTimestampDataModel). Provide either a complete DER TimeStampReq in TSQ, or Digest plus DigestAlgorithm (accepted: MD5, SHA1, SHA224, SHA256, SHA384, SHA512); when TSQ is set, the digest fields are ignored. Algorithm is a sign identifier supported by the key (e.g. "EC_SHA256"), and the signing key must carry a certificate.

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); see SPEC.md for the algorithm registry.

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