kes

package module
Version: v0.17.2 Latest Latest
Warning

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

Go to latest
Published: Oct 12, 2021 License: AGPL-3.0 Imports: 22 Imported by: 4

README

KES

Go Reference build license latest

KES is a stateless and distributed key-management system for high-performance applications. We built KES as the bridge between modern applications - running as containers on Kubernetes - and centralized KMS solutions. Therefore, KES has been designed to be simple, scalable and secure by default. It has just a few knobs to tweak instead of a complex configuration and does not require a deep understanding of secure key-management or cryptography.

Architecture

KES

Install

Binary Releases
OS ARCH Binary
Linux amd64 linux-amd64
Linux arm64 linux-arm64
Linux ppc64le linux-ppc64le
Linux s390x linux-s390x
Apple M1 arm64 darwin-arm64
Apple amd64 darwin-amd64
Windows amd64 windows-amd64

You can also verify the binary with minisign by downloading the corresponding .minisig signature file. Then run:

minisign -Vm kes-<OS>-<ARCH> -P RWTx5Zr1tiHQLwG9keckT0c45M3AGeHD6IvimQHpyRywVWGbP1aVSGav
Docker

Pull the latest release via:

docker pull minio/kes
Build from source
GO111MODULE=on go get github.com/minio/kes/cmd/kes

You will need a working Go environment. Therefore, please follow How to install Go. Minimum version required is go1.14

Getting Started

We run a public KES server instance at https://play.min.io:7373 for you to experiment with. Just follow the steps below to get a first impression of how easy it is to use KES as a client. All you need is cURL.

If you instead want to run a KES server locally as your first steps then checkout our Getting Started Guide.

1. Fetch the root identity

As an initial step, you will need to download the "private" key and certificate to authenticate to the KES server as the root identity.

curl -sSL --tlsv1.2 \
   -O 'https://raw.githubusercontent.com/minio/kes/master/root.key' \
   -O 'https://raw.githubusercontent.com/minio/kes/master/root.cert'
2. Create a new master key

Then, you can create a new master key named e.g. my-key.

curl -sSL --tlsv1.3 --http2 \
    --key root.key \
    --cert root.cert \
    -X POST 'https://play.min.io:7373/v1/key/create/my-key'

Note that creating a new key will fail with key does already exist if it already exist.

3. Generate a new data encryption key (DEK)

Now, you can use that master key to derive a new data encryption key.

curl -sSL --tlsv1.3 --http2 \
    --key root.key \
    --cert root.cert \
    --data '{}' \
    -X POST 'https://play.min.io:7373/v1/key/generate/my-key'

You will get a plaintext and a ciphertext data key. The ciphertext data key is the encrypted version of the plaintext key. Your application would use the plaintext key to e.g. encrypt some application data but only remember the ciphertext key version.

4. Use the KES CLI client

For more sophisticated tasks, like managing policies or audit log tracing, you may want to use the KES CLI. Therefore, point your CLI to our KES instance:

export KES_SERVER=https://play.min.io:7373
export KES_CLIENT_KEY=root.key
export KES_CLIENT_CERT=root.cert

Then run a KES CLI command. For example:

kes key list

If you want to learn more about KES checkout our documentation.

License

Use of KES is governed by the AGPLv3 license that can be found in the LICENSE file.

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrNotAllowed represents a KES server response returned when the
	// client has not sufficient policy permissions to perform a particular
	// operation.
	ErrNotAllowed = NewError(http.StatusForbidden, "prohibited by policy")

	// ErrKeyNotFound represents a KES server response returned when a client
	// tries to access or use a cryptographic key which does not exist.
	ErrKeyNotFound = NewError(http.StatusNotFound, "key does not exist")

	// ErrKeyExists represents a KES server response returned when a client tries
	// to create a cryptographic key which already exists.
	ErrKeyExists = NewError(http.StatusBadRequest, "key does already exist")

	// ErrPolicyNotFound represents a KES server response returned when a client
	// tries to access a policy which does not exist.
	ErrPolicyNotFound = NewError(http.StatusNotFound, "policy does not exist")

	// ErrDecrypt represents a KES server response returned when the server fails
	// to decrypt an encrypted ciphertext. It may occur when a client uses the
	// the wrong key or the ciphertext has been (maliciously) modified.
	ErrDecrypt = NewError(http.StatusBadRequest, "decryption failed: ciphertext is not authentic")
)

Functions

This section is empty.

Types

type AuditEvent added in v0.7.0

type AuditEvent struct {
	// Time is the point in time when the
	// audit event has been created.
	Time time.Time `json:"time"`

	// Request contains audit log information
	// about the request received from a client.
	Request AuditEventRequest `json:"request"`

	// Response contains audit log information
	// about the response sent to the client.
	Response AuditEventResponse `json:"response"`
}

AuditEvent is the event type the KES server produces when it has handled a request right before responding to the client.

When a clients subscribes to the KES server audit log it receives a stream of JSON-encoded audit events separated by a newline.

func (*AuditEvent) String added in v0.13.0

func (a *AuditEvent) String() string

String returns the AuditEvent's string representation which is valid JSON.

type AuditEventRequest added in v0.7.0

type AuditEventRequest struct {
	Path     string `json:"path"`
	Identity string `json:"identity"`
}

AuditEventRequest contains the audit information about a request sent by a client to a KES server.

In particular, it contains the identity of the client and other audit-related information.

func (*AuditEventRequest) String added in v0.13.0

func (a *AuditEventRequest) String() string

String returns the AuditEventRequest's string representation which is valid JSON.

type AuditEventResponse added in v0.7.0

type AuditEventResponse struct {
	StatusCode int           `json:"code"`
	Time       time.Duration `json:"time"`
}

AuditEventResponse contains the audit information about a response sent to a client by a KES server.

In particular, it contains the response status code and other audit-related information.

func (*AuditEventResponse) String added in v0.13.0

func (a *AuditEventResponse) String() string

String returns the AuditEventResponse's string representation which is valid JSON.

type AuditStream added in v0.7.0

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

AuditStream provides a convenient interface for iterating over a stream of AuditEvents. Successive calls to the Next method will step through the audit events of an io.Reader.

By default, the AuditStream breaks the underlying stream into lines and expects a JSON-encoded AuditEvent per line - unless the line is empty. Empty lines will be ignored.

Iterating stops at the end of the stream, the first I/O error, an AuditEvent event too large to fit in the buffer, or when the stream gets closed.

Closing an AuditStream closes the underlying io.Reader, if it implements io.Closer, and any subsequent call to Next will return false.

func NewAuditStream added in v0.7.0

func NewAuditStream(r io.Reader) *AuditStream

NewAuditStream returns a new AuditStream that splits r into lines and tries to parse each line as JSON-encoded AuditEvent.

Example
package main

import (
	"fmt"
	"strings"

	"github.com/minio/kes"
)

const AuditStream = `{"time":"2020-03-24T12:37:33Z","request":{"path":"/v1/log/audit/trace","identity":"dd46485bedc9ad2909d2e8f9017216eec4413bc5c64b236d992f7ec19c843c5f"},"response":{"code":200, "time":12106}}
{"time":"2020-03-24T12:38:02Z","request":{"path":"/v1/policy/list/*","identity":"dd46485bedc9ad2909d2e8f9017216eec4413bc5c64b236d992f7ec19c843c5f"},"response":{"code":200, "time":15572}}
{"time":"2020-03-24T12:39:02Z","request":{"path":"/v1/identity/list/*","identity":"dd46485bedc9ad2909d2e8f9017216eec4413bc5c64b236d992f7ec19c843c5f"},"response":{"code":200, "time":15953}}`

func main() {
	reader := strings.NewReader(AuditStream)

	stream := kes.NewAuditStream(reader)
	for stream.Next() {
		event := stream.Event()

		fmt.Println(event.Time)
	}
	if err := stream.Err(); err != nil {
		panic(err) // TODO: error handling
	}
}
Output:

2020-03-24 12:37:33 +0000 UTC
2020-03-24 12:38:02 +0000 UTC
2020-03-24 12:39:02 +0000 UTC

func (*AuditStream) Bytes added in v0.7.0

func (s *AuditStream) Bytes() []byte

Bytes returns the most recent raw AuditEvent content generated by a call to Next. It may not contain valid JSON.

The underlying array may point to data that will be overwritten by a subsequent call to Next. It does no allocation.

func (*AuditStream) Close added in v0.7.0

func (s *AuditStream) Close() (err error)

Close closes the underlying stream - i.e. the io.Reader if if implements io.Closer. After Close has been called once the Next method will return false.

func (*AuditStream) Err added in v0.7.0

func (s *AuditStream) Err() error

Err returns the first non-EOF error that was encountered while iterating over the stream and un-marshaling AuditEvents.

Err does not return any error returned from Close.

func (*AuditStream) Event added in v0.7.0

func (s *AuditStream) Event() AuditEvent

Event returns the most recent AuditEvent generated by a call to Next.

func (*AuditStream) Next added in v0.7.0

func (s *AuditStream) Next() bool

Next advances the stream to the next AuditEvent, which will then be available through the Event and Bytes method. It returns false when the stream iteration stops - i.e. by reaching the end of the stream, closing the stream or in case of an error. After Next returns false, the Err method will return any error that occurred while iterating and parsing the stream.

type Client

type Client struct {
	// Endpoints contains one or multiple KES server
	// endpoints. For example: https://127.0.0.1:7373
	//
	// Each endpoint must be a HTTPS endpoint and
	// should point to different KES server replicas
	// with a common configuration.
	//
	// Multiple endpoints should only be specified
	// when multiple KES servers should be used, e.g.
	// for high availability, but no round-robin DNS
	// is used.
	Endpoints []string

	// HTTPClient is the HTTP client.
	//
	// The HTTP client uses its http.RoundTripper
	// to send requests resp. receive responses.
	//
	// It must not be modified concurrently.
	HTTPClient http.Client
}

Client is a KES client. Usually, a new client is instantiated via the NewClient or NewClientWithConfig functions.

In general, a client just requires:

• a KES server endpoint
• a X.509 certificate for authentication

However, custom transport protocols, timeouts, connection pooling, etc. can be specified via a custom http.RoundTripper. For example:

client := &Client{
    Endpoints:  []string{"https:127.0.0.1:7373"},
    HTTPClient: http.Client{
        Transport: &http.Transport{
           // specify custom behavior...

           TLSClientConfig: &tls.Config{
               Certificates: []tls.Certificates{clientCert},
           },
        },
    },
 }

A custom transport protocol can be used via a custom implemention of the http.RoundTripper interface.

func NewClient

func NewClient(endpoint string, cert tls.Certificate) *Client

NewClient returns a new KES client with the given KES server endpoint that uses the given TLS certificate mTLS authentication.

The TLS certificate must be valid for client authentication.

NewClient uses an http.Transport with reasonable defaults.

func NewClientWithConfig added in v0.8.0

func NewClientWithConfig(endpoint string, config *tls.Config) *Client

NewClientWithConfig returns a new KES client with the given KES server endpoint that uses the given TLS config for mTLS authentication.

Therefore, the config.Certificates must contain a TLS certificate that is valid for client authentication.

NewClientWithConfig uses an http.Transport with reasonable defaults.

func (*Client) AssignIdentity

func (c *Client) AssignIdentity(ctx context.Context, policy string, id Identity) error

func (*Client) AuditLog added in v0.12.0

func (c *Client) AuditLog(ctx context.Context) (*AuditStream, error)

AuditLog returns a stream of audit events produced by the KES server. The stream does not contain any events that happened in the past.

It returns ErrNotAllowed if the client does not have sufficient permissions to subscribe to the audit log.

func (*Client) CreateKey

func (c *Client) CreateKey(ctx context.Context, name string) error

CreateKey tries to create a new cryptographic key with the specified name.

The key will be generated by the server. The client application does not have the cryptographic key at any point in time.

func (*Client) Decrypt added in v0.8.0

func (c *Client) Decrypt(ctx context.Context, name string, ciphertext, context []byte) ([]byte, error)

Decrypt tries to decrypt the given ciphertext with the specified key and returns plaintext on success.

The context value must match the context used when the ciphertext was produced. If no context was used the context value should be set to nil.

func (*Client) DeleteKey

func (c *Client) DeleteKey(ctx context.Context, name string) error

DeleteKey deletes the given key. Once a key has been deleted all data, that has been encrypted with it, cannot be decrypted anymore.

func (*Client) DeletePolicy

func (c *Client) DeletePolicy(ctx context.Context, name string) error

DeletePolicy removes the policy with the given name. It will not return an error if no policy exists.

If there are identities assigned to the deleted policies then these identities will be removed as well.

Therefore, setting an empty policy and deleting a policy have slightly different implications. The former will revoke any access permission for all identities assigned to the policy. The later will remove the policy as well as all identities assigned to it.

func (*Client) Encrypt added in v0.10.0

func (c *Client) Encrypt(ctx context.Context, name string, plaintext, context []byte) ([]byte, error)

Encrypt encrypts and authenticates the given plaintext with the specified key and returns the corresponding ciphertext on success.

An optional context value gets authenticated but is not encrypted. Therefore, the same context value must be provided for decryption. Clients should remember or be able to re-generate the context value.

func (*Client) ErrorLog added in v0.12.0

func (c *Client) ErrorLog(ctx context.Context) (*ErrorStream, error)

ErrorLog returns a stream of error events produced by the KES server. The stream does not contain any events that happened in the past.

It returns ErrNotAllowed if the client does not have sufficient permissions to subscribe to the error log.

func (*Client) ForgetIdentity

func (c *Client) ForgetIdentity(ctx context.Context, id Identity) error

func (*Client) GenerateKey added in v0.8.0

func (c *Client) GenerateKey(ctx context.Context, name string, context []byte) (DEK, error)

GenerateKey generates a new data encryption key (DEK). The context is cryptographically bound to the DEK.

A DEK has a plaintext and a ciphertext representation. The plaintext should be used to perform a cryptographic operation - for example: encrypt some data.

The ciphertext is the result of encrypting the plaintext with the given key. It should be stored at a durable location but does not need to stay secret. The ciphertext can only be decrypted with the given key at the server.

Whenever an application needs the DEK's plaintext representation it should send the ciphertext to the server via the Decrypt method.

The context is cryptographically bound to the ciphertext and the same context value must be provided whenever the ciphertext should be decrypted. An application either must remember the context or must be able to re-generate it.

If an application does not wish to specify a context value it can set it to nil.

Example
package main

import (
	"context"
	"crypto/aes"
	"crypto/cipher"
	"crypto/rand"
	"crypto/tls"
	"io"
	"log"

	"github.com/minio/kes"
)

func main() {
	// First, load the client TLS private key / certificate to
	// authenticate against the KES server.
	const (
		keyFile  = "./root.key"
		certFile = "./root.cert"
	)
	certificate, err := tls.LoadX509KeyPair(certFile, keyFile)
	if err != nil {
		log.Fatalf("Failed to load TLS certificate for client (mTLS) authentication: %v", err)
	}

	// Then, generate a new data encryption key (DEK). The DEK contains a
	// plaintext key as well as a ciphertext version. The ciphertext is the
	// plaintext key encrypted by the KES server with the key named 'keyName'.
	// Only the KES server can decrypt the ciphertext key.
	const (
		endpoint = "https://play.min.io:7373"
		keyName  = "my-key"
	)
	client := kes.NewClient(endpoint, certificate)
	key, err := client.GenerateKey(context.Background(), keyName, nil)
	if err != nil {
		log.Fatalf("Failed to generate a new data encryption key: %v", err)
	}

	// Finally, use AES-GCM to encrypt a short message using the plaintext key.
	// The actual ciphertext, the encrypted key, the nonce and the associated data
	// can be stored on some untrusted location. The ciphertext can only be decrypted
	// by contacting the KES server - once the plaintext key is no longer accessible.
	block, err := aes.NewCipher(key.Plaintext)
	if err != nil {
		log.Fatalf("Failed to create AES instance: %v", err)
	}
	gcm, err := cipher.NewGCM(block)
	if err != nil {
		log.Fatalf("Failed to create AES-GCM instance: %v", err)
	}

	var (
		message        = []byte("Hello World")
		nonce          = mustRandom(rand.Reader, gcm.NonceSize())
		associatedData = []byte("my-file.text")
	)
	ciphertext := gcm.Seal(nil, nonce, message, associatedData)

	// Now store the ciphertext as well as the key.Ciphertext, the nonce
	// and the associatedData. The key.Ciphertext contains the encrypted
	// version of the key used to encrypt the message.
	// It needs to be sent to the KES server to obtain the plaintext key
	// which is needed to decrypt the ciphertext (using the nonce and
	// associatedData) and obtain the message again.
	_, _, _, _ = ciphertext, key.Ciphertext, nonce, associatedData
}

func mustRandom(random io.Reader, size int) []byte {
	v := make([]byte, size)
	if _, err := io.ReadFull(random, v); err != nil {
		panic(err)
	}
	return v
}
Output:

func (*Client) GetPolicy added in v0.10.1

func (c *Client) GetPolicy(ctx context.Context, name string) (*Policy, error)

GetPolicy returns the policy with the given name. If no such policy exists then GetPolicy returns ErrPolicyNotFound.

func (*Client) ImportKey added in v0.5.0

func (c *Client) ImportKey(ctx context.Context, name string, key []byte) error

ImportKey tries to import the given key as cryptographic key with the specified name.

In contrast to CreateKey, the client specifies, and therefore, knows the value of the cryptographic key.

func (*Client) ListIdentities

func (c *Client) ListIdentities(ctx context.Context, pattern string) (*IdentityIterator, error)

func (*Client) ListKeys added in v0.13.0

func (c *Client) ListKeys(ctx context.Context, pattern string) (*KeyIterator, error)

ListKeys returns a new KeyIterator that iterates over all keys matching the given glob pattern.

The KeyIterator will stop once the given context.Done() completes, an error occurs while iterating or once there are no more KeyDescription objects - whatever happens first.

If the pattern is empty it defaults to "*".

func (*Client) ListPolicies

func (c *Client) ListPolicies(ctx context.Context, pattern string) ([]string, error)

ListPolicies returns a list of policies with names that match the given glob pattern. For example

policies, err := client.ListPolicies("*") // '*' matches any

returns the names of all existing policies.

If no / an empty pattern is provided then ListPolicies uses the pattern '*' as default.

func (*Client) Metrics added in v0.13.2

func (c *Client) Metrics(ctx context.Context) (Metric, error)

Metrics returns a KES server metric snapshot.

It returns ErrNotAllowed if the client does not have sufficient permissions to fetch server metrics.

func (*Client) SetPolicy added in v0.10.1

func (c *Client) SetPolicy(ctx context.Context, name string, policy *Policy) error

SetPolicy adds the given policy to the set of policies. There can be just one policy with one particular name at one point in time.

If there is already a policy with the given name then SetPolicy overwrites the existing policy with the given one.

If there are identities assigned to an existing policy then SetPolicy will not remove those identities before overwriting the policy. Instead, it will just updated the policy entry such that the given policy automatically applies to those identities.

func (*Client) Version added in v0.6.0

func (c *Client) Version(ctx context.Context) (string, error)

Version tries to fetch the version information from the KES server.

type DEK added in v0.8.0

type DEK struct {
	Plaintext  []byte
	Ciphertext []byte
}

DEK is a data encryption key. It has a plaintext and a ciphertext representation.

Applications should use the plaintext for cryptographic operations and store the ciphertext at a durable location.

If the DEK is used to e.g. encrypt some data then it's safe to store the DEK's ciphertext representation next to the encrypted data. The ciphertext representation does not need to stay secret.

DEK implements binary as well as text marshaling. However, only the ciphertext representation gets encoded. The plaintext should never be stored anywhere. Therefore, after un-marshaling there will be no plaintext representation. To obtain it the ciphertext must be decrypted.

func (DEK) MarshalBinary added in v0.8.0

func (d DEK) MarshalBinary() ([]byte, error)

MarshalBinary returns DEK's ciphertext representation. It never returns an error.

func (DEK) MarshalText added in v0.8.0

func (d DEK) MarshalText() ([]byte, error)

MarshalText encodes the DEK's ciphertext into a base64-encoded text and returns the result.

It never returns an error.

func (*DEK) UnmarshalBinary added in v0.8.0

func (d *DEK) UnmarshalBinary(data []byte) error

UnmarshalBinary sets DEK's ciphertext to the given data. It never returns an error and DEK's plaintext will be nil.

func (*DEK) UnmarshalText added in v0.8.0

func (d *DEK) UnmarshalText(text []byte) (err error)

UnmarshalText tries to decode a base64-encoded text and sets DEK's ciphertext to the decoded data.

It returns an error if text is not base64-encoded.

UnmarshalText sets DEK's plaintext to nil.

type Error added in v0.6.0

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

Error is the type of client-server API errors. A Client returns an Error if a server responds with a well-formed error message.

An Error contains the HTTP status code sent by the server. Errors with the same status code and error message are equal. In particular:

ErrKeyExists == NewError(400, "key does already exist") // true

The client may distinguish errors as following:

switch err := client.CreateKey("example-key"); err {
    case nil: // Success!
    case ErrKeyExists:
       // The key "example-key" already exists.
    case ErrNotAllowed:
       // We don't have the permission to create this key.
    default:
       // Something else went wrong.
}

func NewError

func NewError(code int, msg string) Error

NewError returns a new Error with the given HTTP status code and error message.

Two errors with the same status code and error message are equal.

func (Error) Error added in v0.6.0

func (e Error) Error() string

func (Error) Status added in v0.6.0

func (e Error) Status() int

Status returns the HTTP status code of the error.

type ErrorEvent added in v0.7.0

type ErrorEvent struct {
	Message string `json:"message"` // The logged error message
}

ErrorEvent is the event type the KES server produces when it encounters and logs an error.

When a clients subscribes to the KES server error log it receives a stream of JSON-encoded error events separated by a newline.

type ErrorStream added in v0.7.0

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

ErrorStream provides a convenient interface for iterating over a stream of ErrorEvents. Successive calls to the Next method will step through the error events of an io.Reader.

By default, the ErrorStream breaks the underlying stream into lines and expects a JSON-encoded ErrorEvent per line - unless the line is empty. Empty lines will be ignored.

Iterating stops at the end of the stream, the first I/O error, a ErrorEvent event too large to fit in the buffer, or when the stream gets closed.

Closing an ErrorStream closes the underlying io.Reader, if it implements io.Closer, and any subsequent call to Next will return false.

func NewErrorStream added in v0.7.0

func NewErrorStream(r io.Reader) *ErrorStream

NewErrorStream returns an new ErrorStream that splits r into lines and tries to parse each line as JSON-encoded ErrorEvent.

Example
package main

import (
	"fmt"
	"strings"

	"github.com/minio/kes"
)

const ErrorStream = `{"message":"2020/03/24 14:46:10 aws: secret was not encrypted with '4f9147d9-a676-47cd-ad3f-3485abf9123d'"}
{"message":"2020/03/24 14:46:17 aws: the CMK 'ff8e2c25-b259-4f74-a001-c7b62d17e0a4' does not exist"}
{"message":"2020/03/24 14:46:25 aws: the CMK '8fc17745-9647-4797-b170-afd8b52ed7c0' cannot be used for decryption"}`

func main() {
	reader := strings.NewReader(ErrorStream)

	stream := kes.NewErrorStream(reader)
	for stream.Next() {
		event := stream.Event()

		fmt.Println(event.Message)
	}
	if err := stream.Err(); err != nil {
		panic(err) // TODO: error handling
	}
}
Output:

2020/03/24 14:46:10 aws: secret was not encrypted with '4f9147d9-a676-47cd-ad3f-3485abf9123d'
2020/03/24 14:46:17 aws: the CMK 'ff8e2c25-b259-4f74-a001-c7b62d17e0a4' does not exist
2020/03/24 14:46:25 aws: the CMK '8fc17745-9647-4797-b170-afd8b52ed7c0' cannot be used for decryption

func (*ErrorStream) Bytes added in v0.7.0

func (s *ErrorStream) Bytes() []byte

Bytes returns the most recent raw ErrorEvent content generated by a call to Next. It may not contain valid JSON.

The underlying array may point to data that will be overwritten by a subsequent call to Next. It does no allocation.

func (*ErrorStream) Close added in v0.7.0

func (s *ErrorStream) Close() (err error)

Close closes the underlying stream - i.e. the io.Reader if if implements io.Closer. After Close has been called once the Next method will return false.

func (*ErrorStream) Err added in v0.7.0

func (s *ErrorStream) Err() error

Err returns the first non-EOF error that was encountered while iterating over the stream and un-marshaling ErrorEvents.

Err does not return any error returned from Close.

func (*ErrorStream) Event added in v0.7.0

func (s *ErrorStream) Event() ErrorEvent

Event returns the most recent ErrorEvent generated by a call to Next.

func (*ErrorStream) Next added in v0.7.0

func (s *ErrorStream) Next() bool

Next advances the stream to the next ErrorEvent, which will then be available through the Event and Bytes method. It returns false when the stream iteration stops - i.e. by reaching the end of the stream, closing the stream or in case of an error. After Next returns false, the Err method will return any error that occurred while iterating and parsing the stream.

type Identity

type Identity string

An Identity should uniquely identify a client and is computed from the X.509 certificate presented by the client during the TLS handshake using an IdentityFunc.

const IdentityUnknown Identity = ""

IdentityUnknown is the identity returned by an IdentityFunc if it cannot map a particular X.509 certificate to an actual identity.

func (Identity) IsUnknown

func (id Identity) IsUnknown() bool

IsUnknown returns true if and only if the identity is IdentityUnknown.

func (Identity) String

func (id Identity) String() string

String returns the string representation of the identity.

type IdentityDescription added in v0.15.0

type IdentityDescription struct {
	Identity Identity `json:"identity"`
	Policy   string   `json:"policy"`
}

IdentityDescription describes an identity at a KES server.

type IdentityIterator added in v0.15.0

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

IdentityIterator iterates over list of IdentityDescription objects.

for iterator.Next() {
    _ = iterator.Value() // Use the IdentityDescription
}
if err := iterator.Err(); err != nil {
}
if err := iterator.Close(); err != nil {
}

Once done with iterating over the list of IdentityDescription objects, an iterator should be closed using the Close method.

In general, an IdentityIterator does not provide any guarantees about ordering or the when its underlying source is modified concurrently. Particularly, if an identity is created or deleted at the KES server the IdentityIterator may or may not be affected by this change.

func (*IdentityIterator) Close added in v0.15.0

func (i *IdentityIterator) Close() error

Close closes the underlying connection to the KES server and returns any encountered error.

func (*IdentityIterator) Err added in v0.15.0

func (i *IdentityIterator) Err() error

Err returns the first error encountered by the IdentityIterator, if any.

func (*IdentityIterator) Next added in v0.15.0

func (i *IdentityIterator) Next() bool

Next returns true if there is another IdentityDescription. This IdentityDescription can be retrieved via the Value method.

It returns false once there are no more IdentityDescriptions or if the IdentityIterator encountered an error. The error, if any, can beretrieved via the Err method.

func (*IdentityIterator) Value added in v0.15.0

Value returns the current IdentityDescription. It returns the same IdentityDescription until Next is called again.

If the IdentityIterator has been closed or if Next has not been called once resp. Next returns false then the behavior of Value is undefined.

type KeyDescription added in v0.13.0

type KeyDescription struct {
	// Name is the name of the cryptographic key.
	Name string `json:"name"`
}

KeyDescription describes a cryptographic key at a KES server.

type KeyIterator added in v0.13.0

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

KeyIterator iterates over list of KeyDescription objects.

for iterator.Next() {
    _ = iterator.Value() // Use the KeyDescription
}
if err := iterator.Err(); err != nil {
}
if err := iterator.Close(); err != nil {
}

Once done with iterating over the list of KeyDescription objects, an iterator should be closed using the Close method.

In general, a KeyIterator does not provide any guarantees about ordering or the when its underlying source is modified concurrently. Particularly, if a key is created or deleted at the KES server the KeyIterator may or may not be affected by this change.

func (*KeyIterator) Close added in v0.13.0

func (i *KeyIterator) Close() error

Close closes the underlying connection to the KES server and returns any encountered error.

func (*KeyIterator) Err added in v0.13.0

func (i *KeyIterator) Err() error

Err returns the first error encountered by the KeyIterator, if any.

func (*KeyIterator) Next added in v0.13.0

func (i *KeyIterator) Next() bool

Next returns true if there is another KeyDescription. This KeyDescription can be retrieved via the Value method.

It returns false once there is no more KeyDescription or if the KeyIterator encountered an error. The error, if any, can be retrieved via the Err method.

func (*KeyIterator) Value added in v0.13.0

func (i *KeyIterator) Value() KeyDescription

Value returns the current KeyDescription. It returns the same KeyDescription until Next is called again.

If KeyIterator has been closed or if Next has not been called once resp. once Next returns false then the behavior of Value is undefined.

type Metric added in v0.13.2

type Metric struct {
	RequestOK     uint64 `json:"kes_http_request_success"` // Requests that succeeded
	RequestErr    uint64 `json:"kes_http_request_error"`   // Requests that failed with a well-defined error
	RequestFail   uint64 `json:"kes_http_request_failure"` // Requests that failed unexpectedly due to an internal error
	RequestActive uint64 `json:"kes_http_request_active"`  // Requests that are currently active and haven't completed yet

	AuditEvents uint64 `json:"kes_log_audit_events"` // Number of generated audit events
	ErrorEvents uint64 `json:"kes_log_error_events"` // Number of generated error events

	// Histogram of the KES server response latency.
	// It shows how fast the server can handle requests.
	//
	// The KES server response latency is the time
	// it takes to reply with a response once a request
	// has been received.
	//
	// The histogram consists of n time buckets. Each
	// time bucket contains the number of responses
	// that took the time T or less. For example:
	//
	//   10ms │ 50ms │ 100ms │ 250ms │ 500ms │ ...
	//   ─────┼──────┼───────┼───────┼───────┼────
	//    100 │  115 │  121  │  126  │  130  │
	//
	//   Here, there were 100 responses that took
	//   10ms or less to generate. There were also
	//   115 responses that took 50ms or less.
	//
	//   So, there were 15 responses in the window
	//   >10ms and <=50ms.
	//
	LatencyHistogram map[time.Duration]uint64 `json:"kes_http_response_time"`

	UpTime time.Duration `json:"kes_system_up_time"` // The time the KES server has been up and running
}

Metric is a KES server metric snapshot.

func (*Metric) RequestN added in v0.13.2

func (m *Metric) RequestN() uint64

RequestN returns the total number of received requests.

type Policy

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

Policy contains a set of rules that explicitly allow or deny HTTP requests.

These rules are specified as glob patterns. The rule applies if the pattern matches the request URL path. For more details on the glob syntax in general see [1] and for the specific pattern syntax see [2].

A policy contains two different rule sets:

• Allow rules
• Deny  rules

A policy determines whether a request should be allowed or denied in two steps. First, it iterates over all deny rules. If any deny rules matches the given request then the request is rejected. Then it iterates over all allow rules. If any allow rule matches the given request then the request is accepted. Otherwise, the request is rejected by default. Hence, a request is only accepted if at least one allow rules and no deny rule matches the request. Also, a deny rule takes precedence over an allow rule.

[1]: https://en.wikipedia.org/wiki/Glob_(programming) [2]: https://golang.org/pkg/path/#Match

func NewPolicy

func NewPolicy(patterns ...string) (*Policy, error)

NewPolicy returns a new policy that accepts requests if at least one of the given patterns matches the with request URL path. It returns an error if one of the patterns contains invalid glob syntax.

func (*Policy) Allow added in v0.15.0

func (p *Policy) Allow(patterns ...string) error

Allow adds the given patterns to the list of allow rules. It ignores empty patterns and returns an error if one of the patterns contains invalid glob syntax.

func (*Policy) Deny added in v0.15.0

func (p *Policy) Deny(patterns ...string) error

Deny adds the given patterns to the list of deny rules. It ignores empty patterns and returns an error if one of the patterns contains invalid glob syntax.

func (Policy) MarshalJSON

func (p Policy) MarshalJSON() ([]byte, error)

func (*Policy) UnmarshalJSON

func (p *Policy) UnmarshalJSON(b []byte) error

func (*Policy) Verify

func (p *Policy) Verify(r *http.Request) error

Verify determines whether a request should be accepted or rejected. It returns ErrNotAllowed if any deny rule or no allow rule matches the given request.

Directories

Path Synopsis
cmd
kes
internal
aws
fs
Package fs implements a key-value store that stores keys as file names and values as file content.
Package fs implements a key-value store that stores keys as file names and values as file content.
gcp
gemalto
Package gemalto implements a key store that fetches/stores cryptographic keys on a Gemalto KeySecure instance.
Package gemalto implements a key store that fetches/stores cryptographic keys on a Gemalto KeySecure instance.
key
log
mem
Package mem implements an in-memory key-value store.
Package mem implements an in-memory key-value store.
vault
Package vault implements a secret key store that stores secret keys as key-value entries on the Hashicorp Vault K/V secret backend.
Package vault implements a secret key store that stores secret keys as key-value entries on the Hashicorp Vault K/V secret backend.

Jump to

Keyboard shortcuts

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