Documentation
¶
Overview ¶
Package clortho provides key management for clients.
The two most important types in this package are the Resolver and the KeyRing. A KeyRing is essentially a local cache of keys, accessible via the key's kid (key ID) attribute. A Resolver resolves keys by key ID from an external source, optionally using a KeyRing as a cache.
A Refresher can be used to asynchronously update keys in one or more KeyRing instances or arbitrary client code that handles refresh events.
Index ¶
- Constants
- Variables
- func NewKeyProvider(opts ...KeyProviderOption) (jws.KeyProvider, error)
- func SetContentMeta(ctx context.Context, meta ContentMeta) context.Context
- type CancelListenerFunc
- type Config
- type ConfigOption
- type ContentMeta
- type Expander
- type Fetcher
- type FetcherOption
- type FileLoader
- type HTTPClient
- type HTTPEncoder
- type HTTPLoader
- type HTTPLoaderError
- type InvalidFormatError
- type JWKKeyParser
- type JWKSetParser
- type Key
- type KeyAccessor
- type KeyProviderOption
- type KeyRing
- type KeyRingOption
- type Keys
- type Loader
- type LoaderOption
- type NotAFileError
- type Parser
- type ParserOption
- type RefreshConfig
- type RefreshEvent
- type RefreshListener
- type RefreshSource
- type Refresher
- type RefresherOption
- type ResolveConfig
- type ResolveEvent
- type ResolveListener
- type Resolver
- type ResolverOption
- type ResolverRefresherOption
- type ResponseTooLargeError
- type Thumbprinter
- type UnsupportedFormatError
- type UnsupportedSchemeError
Constants ¶
const ( // DefaultRefreshInterval is used as the base interval between key refreshes when an // interval couldn't be determined any other way. DefaultRefreshInterval = time.Hour * 24 // DefaultRefreshMinInterval is the hard minimum for the base interval between key refreshes // regardless of how the base interval was determined. DefaultRefreshMinInterval = time.Minute * 10 // DefaultRefreshJitter is the default randomization factor for key refreshes. DefaultRefreshJitter = 0.1 )
const ( // MediaTypeJSON is the media type for JSON data. By default, content with this media type // may contain either a single JWK or a JWK set. MediaTypeJSON = "application/json" // SuffixJSON is the file suffix for JSON data. By default, files with this suffix may // contain either a single JWK or a JWK Set. SuffixJSON = ".json" // MediaTypeJWK is the media type for a single JWK. MediaTypeJWK = "application/jwk+json" // SuffixJWK is the file suffix for a single JWK. SuffixJWK = ".jwk" // MediaTypeJWKSet is the media type for a JWK set. MediaTypeJWKSet = "application/jwk-set+json" // SuffixJWKSet is the file suffix for a JWK set. SuffixJWKSet = ".jwk-set" // MediaTypePEM is the media type for a PEM-encoded key. MediaTypePEM = "application/x-pem-file" // SuffixPEM is the file suffix for a PEM-encoded key. SuffixPEM = ".pem" )
const (
// KeyIDParameter is the name of the URI template parameter for expanding key URIs.
KeyIDParameterName = "keyID"
)
Variables ¶
var ( ErrMissingConnectionDetails = errors.New("connection tls/trust details are missing") ErrMissingConnectionTrust = errors.New("connection trust value is missing") )
var ( // ErrKeyProviderKeyNotFound indicates that the kid in the protected header is not // on the key ring. ErrKeyProviderKeyNotFound = errors.New("key provider failed to find the request kid in its keyring") // ErrKeyProviderMissingKeyID indicates that the protected header has no kid, so // there is nothing to look up on the ring. ErrKeyProviderMissingKeyID = errors.New(`payload must contain a "kid" field in its protected header`) // ErrKeyProviderMissingAlg indicates that the protected header has no alg, so the // key cannot be offered for verification under any algorithm. ErrKeyProviderMissingAlg = errors.New(`protected header must contain an "alg" field`) // ErrKeyProviderKeyUsage indicates that the key found on the ring is marked, via // its JWK "use" member, for something other than signature verification. This is // only reported when the provider was built with WithEnforceKeyUsage. ErrKeyProviderKeyUsage = errors.New("key is not marked for signature use") // ErrKeyProviderKeyImport indicates that the key found on the ring could not be // converted into a form jwx can verify with. It is joined with the jwx error. ErrKeyProviderKeyImport = errors.New("key provider could not import the key from its keyring") // ErrKeyProviderNoKeyRing indicates that no KeyRing was supplied to NewKeyProvider. // A key ring is required, as it is the only source of keys for verification. ErrKeyProviderNoKeyRing = errors.New("key provider requires a key ring; see WithKeyRing") // ErrNoRefreshSources indicates that a Config supplied to NewKeyProvider has no // refresh sources. Keys are served to the verifier from the refreshed key ring, // not resolved per request, so without sources the ring never fills and every // token fails. Config.Resolve plays no part in verification. ErrNoRefreshSources = errors.New("at least one refresh source is required; keys are served to the verifier from the refreshed key ring, not resolved per request") )
var ( // ErrRefresherStarted is returned by Refresher.Start if the Refresher is running. ErrRefresherStarted = errors.New("that refresher has already been started") // ErrRefresherStopped is returned by Refresher.Stop if the Refresher is not running. ErrRefresherStopped = errors.New("that refresher is not running") )
var ( // ErrNoTemplate indicates that no URI template is available for that Resolver's method. ErrNoTemplate = errors.New("no URI template expander has been configured for that method") // ErrKeyNotFound indicates that a key could not be resolved, e.g. a key ID did not exist. ErrKeyNotFound = errors.New("no such key exists") // ErrFetchPanicked is returned to goroutines that were waiting on a fetch which // panicked in another goroutine. The panic itself propagates in the goroutine // that performed the fetch. ErrFetchPanicked = errors.New("the fetch for that key panicked") )
Functions ¶
func NewKeyProvider ¶ added in v0.3.0
func NewKeyProvider(opts ...KeyProviderOption) (jws.KeyProvider, error)
NewKeyProvider constructs a jws.KeyProvider that draws keys from a KeyRing, matching the kid in a JWS protected header against the keys the ring currently holds.
A KeyRing is required; supply one with WithKeyRing. Note that the ring is the only source of keys for verification: a Resolver is deliberately not consulted, so that an unverified kid cannot trigger an outbound fetch. Keys reach the ring by way of a Refresher configured from Config.Refresh.Sources. Config.Resolve is not involved.
Passing WithConfig makes this function check that the Config has at least one refresh source, returning ErrNoRefreshSources otherwise. That turns the most common misconfiguration, a resolve template with no refresh sources, into a startup error rather than a "key not found" on every token.
If no key ring is supplied, or if any option returns an error, this function returns a nil jws.KeyProvider along with a non-nil error. Callers must not use the returned provider when the error is non-nil.
func SetContentMeta ¶ added in v0.2.0
func SetContentMeta(ctx context.Context, meta ContentMeta) context.Context
SetContentMeta stores the ContentMeta from a previous load in the context, so that a subsequent load of the same location can be conditional (e.g. If-Modified-Since). The Refresher does this between refreshes. It is optional for all other callers.
Types ¶
type CancelListenerFunc ¶
type CancelListenerFunc func()
CancelListenerFunc removes the listener it's associated with and cancels any future events sent to that listener.
A CancelListenerFunc is idempotent: after the first invocation, calling this closure will have no effect.
type Config ¶
type Config struct {
// Resolve is the subset of configuration that establishes how individual
// keys will be resolved (or, fetched) on demand by a Resolver. It is not
// used for JWT verification; see ResolveConfig.
Resolve ResolveConfig `json:"resolve" yaml:"resolve"`
// Refresh is the subset of configuration that configures how keys are
// refreshed asynchronously. This is what feeds the key ring that a
// jws.KeyProvider verifies against; see RefreshConfig.
Refresh RefreshConfig `json:"refresh" yaml:"refresh"`
}
Config configures clortho from (possibly) externally unmarshaled locations.
type ConfigOption ¶ added in v0.3.3
type ConfigOption interface {
ResolverOption
RefresherOption
KeyProviderOption
}
ConfigOption is the return type of WithConfig, and nothing more. Each constructor takes its own option interface, and Go has no way to say "accepted by all three" except an interface that embeds all three. This is the same pattern as ResolverRefresherOption, widened to include NewKeyProvider. Callers never implement, name, or call methods on it; they pass the value straight to a constructor.
func WithConfig ¶ added in v0.0.3
func WithConfig(cfg Config) ConfigOption
WithConfig uses a Config struct to configure a Resolver, a Refresher, or a jws.KeyProvider.
For a Resolver, Config.Resolve supplies the key ID template. For a Refresher, Config.Refresh supplies the sources. For a jws.KeyProvider, the Config is not used to fetch anything; NewKeyProvider only checks that Config.Refresh has at least one source, and returns ErrNoRefreshSources otherwise. Supply it there so that a deployment configured with only a resolve template fails at startup instead of rejecting every token.
type ContentMeta ¶
type ContentMeta struct {
// Format describes the type of key content. This will typically be either
// a file suffix (e.g. .pem, .jwk) or a media type (e.g. application/json, application/json+jwk).
// A custom Loader is free to produce its own format values, which must be
// understood by a corresponding Parser.
Format string
// TTL is the length of time this content is considered current. A Refresher will
// use this value to determine when to load content again.
TTL time.Duration
// LastModified is the modification timestamp of the content. For files, this will be
// the FileInfo.ModTime() value. For HTTP responses, this will be the Last-Modified header.
//
// In the case of HTTP, this field is also used to supply a Last-Modified header in the
// request.
LastModified time.Time
}
ContentMeta holds metadata about a piece of content.
func GetContentMeta ¶ added in v0.2.0
func GetContentMeta(ctx context.Context) (meta ContentMeta, ok bool)
GetContentMeta returns the ContentMeta stored in the context by SetContentMeta. The returned bool is false when none was stored. Loaders treat that case as the zero value, so callers are never required to seed one.
type Expander ¶
type Expander interface {
// Expand takes a value map and returns the URI resulting from that expansion.
Expand(any) (string, error)
}
Expander is the strategy for expanding a URI template.
func NewExpander ¶
NewExpander constructs an Expander from a URI template.
type Fetcher ¶
type Fetcher interface {
// This method ensures that each key has a key ID. For keys that do not have a key ID from their source,
// a key ID is generated using a thumbprint hash.
Fetch(ctx context.Context, location string) (keys []Key, metadata ContentMeta, err error)
}
Fetcher handles fetching keys from URI locations. This is the typical application-layer interface. Generally, clients should use this interface over Loader and Parser.
func NewFetcher ¶
func NewFetcher(options ...FetcherOption) Fetcher
NewFetcher produces a Fetcher from a set of configuration options.
type FetcherOption ¶
type FetcherOption interface {
// contains filtered or unexported methods
}
FetcherOption is a configuration option passed to NewFetcher.
func WithKeyIDHash ¶
func WithKeyIDHash(h crypto.Hash) FetcherOption
WithKeyIDHash sets the cryptographic hash used to generate key IDs for keys which do not have them. By default, crypto.SHA256 is used.
func WithLoader ¶
func WithLoader(l Loader) FetcherOption
WithLoader defines the Loader strategy for a Fetcher. By default, a Fetcher uses a Loader created with no options.
func WithParser ¶
func WithParser(p Parser) FetcherOption
WithParser defines the Parser strategy for a Fetcher. By default, a Fetcher uses a Parser created with no options.
type FileLoader ¶
type FileLoader struct {
// Root is the relative root against which all location paths are resolved.
// This field is required.
//
// The Loader created by NewLoader uses os.DirFS("/") for this field, so
// that absolute paths and file:// URIs resolve naturally.
Root fs.FS
}
FileLoader is a Loader implementation that reads content from a file system. All location paths are relative to a supplied root.
func (FileLoader) LoadContent ¶
func (fl FileLoader) LoadContent(ctx context.Context, location string) ([]byte, ContentMeta, error)
type HTTPClient ¶
HTTPClient is the minimal interface required by a component which can handle HTTP transactions with a server. *http.Client implements this interface.
type HTTPEncoder ¶
HTTPEncoder is a strategy closure type for modifying an HTTP request prior to issuing it through a client.
type HTTPLoader ¶
type HTTPLoader struct {
// Client is the HTTP client used to transact with HTTP servers.
// If unset, http.DefaultClient is used.
Client HTTPClient
// Encoders holds an optional slice of HTTPEncoder instances that are used
// to modify requests prior to sending them to the Client.
Encoders []HTTPEncoder
// Timeout is an optional timeout for each HTTP operation. If unset,
// no timeout is used.
Timeout time.Duration
// MaxReadLimit limits how many bytes are read from responses. A body larger
// than this results in a ResponseTooLargeError. If unset, no limit is applied.
MaxReadLimit int64
}
HTTPLoader is a Loader strategy for obtaining content from HTTP servers.
func (HTTPLoader) LoadContent ¶
func (hl HTTPLoader) LoadContent(ctx context.Context, location string) ([]byte, ContentMeta, error)
type HTTPLoaderError ¶
HTTPLoaderError indicates that an error occurred when transacting with a HTTP-based source of key material.
func (*HTTPLoaderError) Error ¶
func (hle *HTTPLoaderError) Error() string
type InvalidFormatError ¶ added in v0.0.4
type InvalidFormatError struct {
Format string
}
InvalidFormatError indicates that a format cannot be associated with a Parser because the format string is invalid. For example, format strings that contain semi-colons (;) are invalid because matching a Parser by MIME parameters is not supported.
func (InvalidFormatError) Error ¶ added in v0.0.4
func (ife InvalidFormatError) Error() string
Error satisfies the error interface.
type JWKKeyParser ¶
type JWKKeyParser struct {
Options []jwk.ParseOption
}
JWKKeyParser parses content as a single JWK.
type JWKSetParser ¶
type JWKSetParser struct {
Options []jwk.ParseOption
}
JWKSetParser parses content as a JWK set.
type Key ¶
type Key interface {
Thumbprinter
// KeyID is the identifier for this Key. This method corresponds to the kid field of a JWK.
// Note that a KeyID is entirely optional. This method can return the empty string.
KeyID() string
// KeyType is the type of this Key, e.g. EC, RSA, etc. This method corresponds to
// the kty field of a JWK.
//
// A KeyType is required. This method always returns a non-empty string.
KeyType() string
// KeyUsage describes how this key is allowed to be used. This method corresponds to
// the use field of a JWK.
//
// A KeyUsage is optional. This method can return the empty string.
KeyUsage() string
// Raw is the raw key, e.g. *rsa.PublicKey, *rsa.PrivateKey, etc. This is the actual underlying
// cryptographic key that should be used.
Raw() any
// Public is the public portion of the raw key. If this key is already a public key, this method
// returns the same key as Raw.
Public() crypto.PublicKey
}
Key is the minimal interface for cryptographic keys. Once created, a Key is immutable.
func EnsureKeyID ¶
EnsureKeyID conditionally assigns a key ID to a given key. The updated Key is returned, along with any error from the hash.
If k already has a key ID, it is returned as is with no error.
If k does not have a key ID, a thumbprint is generated using the supplied hash. The returned key will be a copy of k with the newly generated key ID. If an error occurred, then k is returned as is.
type KeyAccessor ¶
type KeyAccessor interface {
// Get returns the Key associated with the given key identifier (kid).
// If there is no such key, the second return is false.
Get(keyID string) (Key, bool)
// Len returns the number of keys currently in this collection.
Len() int
}
KeyAccessor is a read-only interface to a set of keys.
type KeyProviderOption ¶ added in v0.3.0
type KeyProviderOption interface {
// contains filtered or unexported methods
}
KeyProviderOption represents a configurable option for building a jws.KeyProvider.
func WithEnforceKeyUsage ¶ added in v0.3.3
func WithEnforceKeyUsage() KeyProviderOption
WithEnforceKeyUsage makes a jws.KeyProvider reject any key whose JWK "use" member is set to something other than "sig", with ErrKeyProviderKeyUsage. RFC 7517 section 4.2 says such keys are not meant for signature verification.
This is off by default: a provider built without this option verifies with any key on its ring regardless of "use", which is what every version so far has done.
func WithRingKey
deprecated
added in
v0.3.0
func WithRingKey(kr KeyRing) KeyProviderOption
WithRingKey associates a KeyRing with a jws.KeyProvider.
Deprecated: the name is backwards; it takes a KeyRing. Use WithKeyRing, which accepts the same argument and is also a ResolverOption. This alias will be removed in a future release.
type KeyRing ¶
type KeyRing interface {
KeyAccessor
RefreshListener
// Add allows ad hoc keys to be added to this ring. Any key that has
// no key ID will be skipped.
//
// This method returns the actual count of keys added. This will include
// keys already in the ring, since those will be overwritten with the new Key object.
Add(...Key) int
// Remove allows add hoc keys to be removed from this ring. Any key ID that isn't
// in this ring is ignored. The actual count of deleted keys is returned.
Remove(keyIDs ...string) int
Clone() []Key
}
KeyRing is a client-side cache of keys. Implementations are always safe for concurrent access.
A KeyRing can consume events from a Refresher, which will update the ring's set of keys.
func NewKeyRing ¶
NewKeyRing constructs a KeyRing with an optional set of initial keys. Any key that has no key ID is skipped.
type KeyRingOption ¶ added in v0.3.3
type KeyRingOption interface {
ResolverOption
KeyProviderOption
}
KeyRingOption is the return type of WithKeyRing, and nothing more. It is an interface embedding both option types so that the one value can be passed to NewResolver or NewKeyProvider; see ConfigOption for the same pattern.
func WithKeyRing ¶
func WithKeyRing(kr KeyRing) KeyRingOption
WithKeyRing associates a KeyRing with a Resolver or a jws.KeyProvider.
For a Resolver, the ring acts as a cache: keys found on it are returned without a fetch, and fetched keys are added to it. By default, a Resolver has no ring.
For a jws.KeyProvider, the ring is the only source of keys, and is required.
type Keys ¶
type Keys []Key
Keys is a sortable slice of Key instances. Sorting is done by keyID, ascending. Keys with no keyID are sorted after those that have a keyID.
func (Keys) AppendKeyIDs ¶ added in v0.0.3
AppendKeyIDs appends the key Id of each key to the supplied slice, then returns the result.
type Loader ¶
type Loader interface {
// LoadContent retrieves the key content from location. Location must be a URL parseable
// with url.Parse.
//
// This method returns a ContentMeta describing useful characteristics of the content, mostly around
// caching. This returned metadata can be passed to subsequent calls to make key retrieval more
// efficient.
LoadContent(ctx context.Context, location string) ([]byte, ContentMeta, error)
}
Loader handles the retrieval of content from an external location.
func NewLoader ¶
func NewLoader(options ...LoaderOption) (Loader, error)
NewLoader builds a Loader from a set of options.
By default, the returned Loader handles http, https, and file locations. The default loader, when there is no scheme, is a file loader.
type LoaderOption ¶
type LoaderOption interface {
// contains filtered or unexported methods
}
LoaderOption represents a configurable option for building a Loader.
func WithSchemes ¶
func WithSchemes(l Loader, schemes ...string) LoaderOption
WithSchemes registers a loader as handling one or more URI schemes. Use this to add custom schemes or to override one of the schemes a loader handles by default.
By default, a Loader created with NewLoader handles the file, http, and https schemes, as well as file paths without a scheme.
type NotAFileError ¶
type NotAFileError struct {
Location string
}
NotAFileError indicates that a file URI didn't refer to a system file, but instead referred to a directory, pipe, etc.
func (*NotAFileError) Error ¶
func (nafe *NotAFileError) Error() string
type Parser ¶
type Parser interface {
// Parse parses data, expected to be in the given format, into zero or more Keys.
// If only one key is present in the data, this method returns a 1-element slice.
//
// Format is an opaque string which used as a key to determine which parsing algorithm
// to apply to the data. Most commonly, format is either a file suffix (including the
// leading '.') or a media type such as application/json. If format contains any MIME
// parameters, e.g. text/xml;charset=utf-8, they are ignored.
//
// Custom parsers should usually avoid trying to validate format. This is because
// a Parser might be registered with a nonstandard format. The format is available to
// custom parser code primarily for debugging.
Parse(format string, data []byte) ([]Key, error)
}
Parser turns raw data into one or more Key instances.
func NewParser ¶
func NewParser(options ...ParserOption) (Parser, error)
NewParser returns a Parser tailored with the given options.
The returned Parser handles the following formats by default:
application/json application/jwk+json application/jwk-set+json application/x-pem-file .json .jwk .jwk-set .pem
A caller can use WithFormats to change the parser associated with a format or to register a Parser for a new, custom format.
type ParserOption ¶
type ParserOption interface {
// contains filtered or unexported methods
}
ParserOption allows tailoring of the Parser returned by NewParser.
func WithFormats ¶
func WithFormats(p Parser, formats ...string) ParserOption
WithFormats associates a Parsers with one or more formats. Each format is an opaque string simply used as a way to look up a parsing algorithm. Typically, a format is a file suffix (including the leading '.') or a media type such as application/json.
type RefreshConfig ¶
type RefreshConfig struct {
// Sources are the set of refresh sources to be polled for key material.
//
// If this slice is empty, a Refresher is still created, but it will
// do nothing. NewKeyProvider rejects a Config with no sources; see
// ErrNoRefreshSources.
//
// If there are multiple sources with the same URI, an error is raised.
Sources []RefreshSource `json:"sources" yaml:"sources"`
}
RefreshConfig configures all aspects of key refresh. This is the only path by which keys reach a jws.KeyProvider: a Refresher polls these sources and fills the key ring the provider reads from.
type RefreshEvent ¶
type RefreshEvent struct {
// URI is the source of the keys.
URI string
// Err is the error that occurred while trying to interact with the URI.
// This field can be nil to indicate no error. When this field is non-nil,
// the Keys field will be populated with the last known valid set of keys
// from the given URI.
Err error
// Keys represents the complete set of keys from the URI. When Err is not nil,
// this field will be set to the last known valid set of keys.
//
// This field will be sorted by KeyID.
Keys Keys
// New are the keys that a brand new with this event. These keys will be
// included in the Keys field.
//
// This field will be sorted by KeyID.
New Keys
// Deleted are the keys that are now missing from the refreshed keys.
// These keys will not be in the Keys field. These keys will have been present
// in the previous event(s).
//
// This field will be sorted by KeyID.
Deleted Keys
}
RefreshEvent represents a set of keys from a given URI that has been asynchronously fetched.
type RefreshListener ¶
type RefreshListener interface {
// OnRefreshEvent receives a refresh event. This method must not panic.
OnRefreshEvent(RefreshEvent)
}
RefreshListener is a sink for RefreshEvents.
type RefreshSource ¶
type RefreshSource struct {
// URI is the location where keys are served. By default, clortho supports
// file://, http://, and https:// URIs, as well as standard file system paths
// such as /etc/foo/bar.jwk.
//
// This field is required and has no default.
URI string `json:"uri" yaml:"uri"`
// Interval is the base time between refreshing keys from this source. This value
// is used when the source URI doesn't specify any sort of time-to-live or expiry.
// For example, if an http source doesn't specify a Cache-Control header, this value is used.
//
// If this field is not positive, DefaultRefreshInterval is used.
Interval time.Duration `json:"interval" yaml:"interval"`
// MinInterval specifies the absolute minimum time between key refreshes from this source.
// Regardless of HTTP headers, the Interval field, etc, key refreshes will not occur more
// often than this field indicates.
//
// If this value is not positive, DefaultRefreshMinInterval is used.
MinInterval time.Duration `json:"minInterval" yaml:"minInterval"`
// Jitter is the randomization factor applied to the interval between refreshes. No matter how
// the interval is determined (e.g. Cache-Control, Interval field, etc), a random value between
// [1-Jitter,1+Jitter]*interval is used as the actual time before the next attempted refresh.
//
// Valid values are between 0.0 and 1.0, exclusive. If this value is outside that range,
// including being unset, DefaultRefreshJitter is used instead.
Jitter float64 `json:"jitter" yaml:"jitter"`
}
RefreshSource describes a single location where keys are retrieved on a schedule.
type Refresher ¶
type Refresher interface {
// Start bootstraps tasks that fetch keys and dispatch events to any listeners.
// Keys will arrive asynchronously to any registered listeners.
//
// If this Refresher has already been started, this method returns ErrRefresherStarted.
Start(context.Context) error
// Stop shuts down all refresh tasks.
//
// If this Refresher is not running, this method returns ErrRefresherStopped.
Stop(context.Context) error
// AddListener registers a channel that receives refresh events. No caching of events
// is done. The supplied listener will receive events the next time any of the key
// sources are queried.
//
// The returned closure can be used to cancel refreshes sent to the listener. Clients
// are not required to use this closure, particularly if the listener is active for the
// life of the application.
AddListener(l RefreshListener) CancelListenerFunc
}
Refresher handles asynchronously refreshing sets of keys from one or more sources.
func NewRefresher ¶
func NewRefresher(options ...RefresherOption) (Refresher, error)
NewRefresher constructs a Refresher using the supplied options. Without any options, a default Loader and Parser are created and used. Whenever the returned error is non-nil, the returned Refresher is nil.
type RefresherOption ¶
type RefresherOption interface {
// contains filtered or unexported methods
}
RefresherOption is a configurable option passed to NewRefresher.
func WithSources ¶
func WithSources(sources ...RefreshSource) RefresherOption
WithSources associates external sources of keys with a Refresher. This option is cumulative: all sources from each call to WithSources will be added to the configured Refresher.
type ResolveConfig ¶
type ResolveConfig struct {
// Template is a URI template used to fetch keys. This template may
// use a single parameter named keyID, e.g. http://keys.com/{keyID}.
//
// If empty, a Resolver built from this configuration serves only keys
// already on its ring, and reports ErrNoTemplate for any other key ID.
Template string `json:"template" yaml:"template"`
// Timeout refers to the maximum time to wait for a refresh operation.
// There is no default for this field. If unset, no timeout is applied.
Timeout time.Duration `json:"timeout" yaml:"timeout"`
}
ResolveConfig configures how to fetch individual keys on demand. It is used by NewResolver, via WithConfig, and by nothing else. A Resolver serves callers that ask for a specific key by ID, such as clients that need a key to verify a particular message.
ResolveConfig plays no part in JWT verification through NewKeyProvider: the provider reads only the key ring, which is filled from RefreshConfig.Sources. A deployment that sets only a resolve template will never have a key to verify with.
type ResolveEvent ¶
type ResolveEvent struct {
// URI is the actual, expanded URI used to obtain the key material.
URI string
// KeyID is the key ID that was resolved.
KeyID string
// Key is the key material that was returned from the URI.
Key Key
// Err holds any error that occurred while trying to fetch key material.
// If this field is set, Key will be nil.
Err error
}
ResolveEvent holds information about a key ID that has been resolved.
type ResolveListener ¶
type ResolveListener interface {
// OnResolveEvent receives notifications for attempts to resolve keys. This
// method must not panic.
OnResolveEvent(ResolveEvent)
}
ResolveListener is a sink for ResolveEvents.
type Resolver ¶
type Resolver interface {
// Resolve attempts to locate a key with a given keyID (kid).
Resolve(ctx context.Context, keyID string) (Key, error)
// AddListener attaches a sink for ResolveEvents. Only events that
// occur after this method call will be dispatched to the given listener.
AddListener(ResolveListener) CancelListenerFunc
}
Resolver allows synchronous resolution of keys.
func NewResolver ¶
func NewResolver(options ...ResolverOption) (Resolver, error)
NewResolver constructs a Resolver from a set of options. By default, a Resolver uses the DefaultLoader() and DefaultParser().
If no URI template option is supplied at all, this function returns ErrNoTemplate. Whenever the returned error is non-nil, the returned Resolver is nil.
An empty template, as from WithConfig with no Resolve.Template set, is accepted and yields a ring-only Resolver: keys already on the ring resolve, and any other key ID fails with ErrNoTemplate rather than an attempted fetch.
type ResolverOption ¶
type ResolverOption interface {
// contains filtered or unexported methods
}
ResolverOption represents a configurable option passed to NewResolver.
func WithKeyIDExpander ¶
func WithKeyIDExpander(e Expander) ResolverOption
WithKeyIDExpander establishes the Expander strategy used for resolving individual keys. Callers may use this option to associate a custom Expander with a Resolver.
func WithKeyIDTemplate ¶
func WithKeyIDTemplate(t string) ResolverOption
WithKeyIDTemplate establishes the URI template used for resolving individual keys. An empty template yields a ring-only Resolver whose misses report ErrNoTemplate; see NewResolver.
type ResolverRefresherOption ¶
type ResolverRefresherOption interface {
ResolverOption
RefresherOption
}
ResolverRefresherOption is a configurable option that applies to both a Refresher and a Resolver.
func WithFetcher ¶
func WithFetcher(f Fetcher) ResolverRefresherOption
WithFetcher configures the Fetcher instance used by either a Resolver or a Refresher. By default, DefaultFetcher() is used.
type ResponseTooLargeError ¶ added in v0.3.3
ResponseTooLargeError indicates that an HTTP response body exceeded the loader's MaxReadLimit.
func (*ResponseTooLargeError) Error ¶ added in v0.3.3
func (rtle *ResponseTooLargeError) Error() string
type Thumbprinter ¶
type Thumbprinter interface {
// Thumbprint produces the RFC 7638 thumbprint hash, using the supplied algorithm. The
// typical value to pass to this method is crypto.SHA256.
//
// The returned byte slice contains the raw bytes of the hash. To convert it to a string
// conforming to RFC 7638, use base64.RawURLEncoding.EncodeToString.
Thumbprint(crypto.Hash) ([]byte, error)
}
Thumbprinter is implemented by anything that can produce a secure thumbprint of itself.
type UnsupportedFormatError ¶
type UnsupportedFormatError struct {
Format string
}
UnsupportedFormatError indicates that a Parser cannot parse a given format.
func (UnsupportedFormatError) Error ¶
func (ufe UnsupportedFormatError) Error() string
Error implements the error interface.
type UnsupportedSchemeError ¶
type UnsupportedSchemeError struct {
Location string
}
UnsupportedSchemeError indicates that a URI's scheme was not registered and couldn't be handled by a Loader.
func (*UnsupportedSchemeError) Error ¶
func (use *UnsupportedSchemeError) Error() string
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package clorthofx provides integration with go.uber.org/fx.
|
Package clorthofx provides integration with go.uber.org/fx. |
|
Package clorthometrics integrates clortho events with Prometheus metrics.
|
Package clorthometrics integrates clortho events with Prometheus metrics. |
|
Package clorthozap provides basic integration with go.uber.org/zap.
|
Package clorthozap provides basic integration with go.uber.org/zap. |