Documentation
¶
Overview ¶
Package jwk implements JWK as described in https://tools.ietf.org/html/rfc7517
Index ¶
- Constants
- func AssignKeyID(key Key, options ...AssignKeyIDOption) error
- func AvailableCurves() []elliptic.Curve
- func CurveForAlgorithm(alg jwa.EllipticCurveAlgorithm) (elliptic.Curve, bool)
- func DecodePEM(src []byte) (interface{}, []byte, error)
- func EncodePEM(v interface{}) ([]byte, error)
- func EncodeX509(v interface{}) (string, []byte, error)
- func Equal(k1, k2 Key) bool
- func IsKeyValidationError(err error) bool
- func IsPrivateKey(k Key) (bool, error)
- func NewKeyValidationError(err error) error
- func ParseRawKey(data []byte, rawkey interface{}) error
- func Pem(v interface{}) ([]byte, error)
- func PublicRawKeyOf(v interface{}) (interface{}, error)
- func RegisterCustomField(name string, object interface{})
- func SetGlobalFetcher(f httprc.Fetcher)
- type AssignKeyIDOption
- type AsymmetricKey
- type Cache
- func (c *Cache) Get(ctx context.Context, u string) (Set, error)
- func (c *Cache) IsRegistered(u string) bool
- func (c *Cache) Refresh(ctx context.Context, u string) (Set, error)
- func (c *Cache) Register(u string, options ...RegisterOption) error
- func (c *Cache) Snapshot() *httprc.Snapshot
- func (c *Cache) Unregister(u string) error
- type CacheOption
- type CachedSet
- func (*CachedSet) AddKey(_ Key) error
- func (*CachedSet) Clear() error
- func (cs *CachedSet) Clone() (Set, error)
- func (cs *CachedSet) Get(name string) (interface{}, bool)
- func (cs *CachedSet) Index(key Key) int
- func (cs *CachedSet) Iterate(ctx context.Context) HeaderIterator
- func (cs *CachedSet) Key(idx int) (Key, bool)
- func (cs *CachedSet) Keys(ctx context.Context) KeyIterator
- func (cs *CachedSet) Len() int
- func (cs *CachedSet) LookupKeyID(kid string) (Key, bool)
- func (*CachedSet) Remove(_ string) error
- func (*CachedSet) RemoveKey(_ Key) error
- func (*CachedSet) Set(_ string, _ interface{}) error
- type DecodeCtx
- type ECDSAPrivateKey
- type ECDSAPublicKey
- type ErrSink
- type FetchFunc
- type FetchOption
- type Fetcher
- type HTTPClient
- type HeaderIterator
- type HeaderPair
- type HeaderVisitor
- type HeaderVisitorFunc
- type InsecureWhitelist
- type Key
- type KeyIterator
- type KeyOperation
- type KeyOperationList
- type KeyPair
- type KeyUsageType
- type KeyWithDecodeCtx
- type MapWhitelist
- type OKPPrivateKey
- type OKPPublicKey
- type Option
- type ParseOption
- type PostFetchFunc
- type PostFetcher
- type PublicKeyer
- type RSAPrivateKey
- type RSAPublicKey
- type ReadFileOption
- type RegexpWhitelist
- type RegisterOption
- type Set
- func Fetch(ctx context.Context, u string, options ...FetchOption) (Set, error)
- func NewCachedSet(cache *Cache, url string) Set
- func NewSet() Set
- func Parse(src []byte, options ...ParseOption) (Set, error)
- func ParseReader(src io.Reader, options ...ParseOption) (Set, error)
- func ParseString(s string, options ...ParseOption) (Set, error)
- func PublicSetOf(v Set) (Set, error)
- func ReadFile(path string, options ...ReadFileOption) (Set, error)
- type SymmetricKey
- type Transformer
- type Whitelist
- type WhitelistFunc
Constants ¶
const ( ECDSACrvKey = "crv" ECDSADKey = "d" ECDSAXKey = "x" ECDSAYKey = "y" )
const ( KeyTypeKey = "kty" KeyUsageKey = "use" KeyOpsKey = "key_ops" AlgorithmKey = "alg" KeyIDKey = "kid" X509URLKey = "x5u" X509CertChainKey = "x5c" X509CertThumbprintKey = "x5t" X509CertThumbprintS256Key = "x5t#S256" )
const ( OKPCrvKey = "crv" OKPDKey = "d" OKPXKey = "x" )
const ( RSADKey = "d" RSADPKey = "dp" RSADQKey = "dq" RSAEKey = "e" RSANKey = "n" RSAPKey = "p" RSAQIKey = "qi" RSAQKey = "q" )
const (
SymmetricOctetsKey = "k"
)
Variables ¶
This section is empty.
Functions ¶
func AssignKeyID ¶
func AssignKeyID(key Key, options ...AssignKeyIDOption) error
AssignKeyID is a convenience function to automatically assign the "kid" section of the key, if it already doesn't have one. It uses Key.Thumbprint method with crypto.SHA256 as the default hashing algorithm
func AvailableCurves ¶
func CurveForAlgorithm ¶
func CurveForAlgorithm(alg jwa.EllipticCurveAlgorithm) (elliptic.Curve, bool)
func EncodePEM ¶
EncodePEM encodes the key into a PEM encoded ASN.1 DER format. The key can be a jwk.Key or a raw key instance, but it must be one of the types supported by `x509` package.
Internally, it uses the same routine as `jwk.EncodeX509()`, and therefore the same caveats apply
func EncodeX509 ¶
EncodeX509 encodes the key into a byte sequence in ASN.1 DER format suitable for to be PEM encoded. The key can be a jwk.Key or a raw key instance, but it must be one of the types supported by `x509` package.
This function will try to do the right thing depending on the key type (i.e. switch between `x509.MarshalPKCS1PrivateKey` and `x509.MarshalECPrivateKey`), but for public keys, it will always use `x509.MarshalPKIXPublicKey`. Please manually perform the encoding if you need more fine-grained control
The first return value is the name that can be used for `(pem.Block).Type`. The second return value is the encoded byte sequence.
func Equal ¶ added in v2.0.13
Equal compares two keys and returns true if they are equal. The comparison is solely done against the thumbprints of k1 and k2. It is possible for keys that have, for example, different key IDs, key usage, etc, to be considered equal.
func IsKeyValidationError ¶ added in v2.0.16
func IsPrivateKey ¶ added in v2.0.14
IsPrivateKey returns true if the supplied key is a private key of an asymmetric key pair. The argument `k` must implement the `AsymmetricKey` interface.
An error is returned if the supplied key is not an `AsymmetricKey`.
func NewKeyValidationError ¶ added in v2.0.16
NewKeyValidationError wraps the given error with an error that denotes `key.Validate()` has failed. This error type should ONLY be used as return value from the `Validate()` method.
func ParseRawKey ¶
ParseRawKey is a combination of ParseKey and Raw. It parses a single JWK key, and assigns the "raw" key to the given parameter. The key must either be a pointer to an empty interface, or a pointer to the actual raw key type such as *rsa.PrivateKey, *ecdsa.PublicKey, *[]byte, etc.
func Pem ¶
Pem serializes the given jwk.Key in PEM encoded ASN.1 DER format, using either PKCS8 for private keys and PKIX for public keys. If you need to encode using PKCS1 or SEC1, you must do it yourself.
Argument must be of type jwk.Key or jwk.Set ¶
Currently only EC (including Ed25519) and RSA keys (and jwk.Set comprised of these key types) are supported.
func PublicRawKeyOf ¶
func PublicRawKeyOf(v interface{}) (interface{}, error)
PublicRawKeyOf returns the corresponding public key of the given value `v` (e.g. given *rsa.PrivateKey, *rsa.PublicKey is returned) If `v` is already a public key, the key itself is returned.
The returned value will always be a pointer to the public key, except when a []byte (e.g. symmetric key, ed25519 key) is passed to `v`. In this case, the same []byte value is returned.
func RegisterCustomField ¶
func RegisterCustomField(name string, object interface{})
RegisterCustomField allows users to specify that a private field be decoded as an instance of the specified type. This option has a global effect.
For example, suppose you have a custom field `x-birthday`, which you want to represent as a string formatted in RFC3339 in JSON, but want it back as `time.Time`.
In that case you would register a custom field as follows
jwk.RegisterCustomField(`x-birthday`, timeT)
Then `key.Get("x-birthday")` will still return an `interface{}`, but you can convert its type to `time.Time`
bdayif, _ := key.Get(`x-birthday`) bday := bdayif.(time.Time)
func SetGlobalFetcher ¶ added in v2.0.10
SetGlobalFetcher allows users to specify a custom global fetcher, which is used by the `Fetch` function. Assigning `nil` forces the default fetcher to be (re)created when the next call to `jwk.Fetch` occurs
You only need to call this function when you want to either change the fetching behavior (for example, you want to change how the default whitelist is handled), or when you want to control the lifetime of the global fetcher, for example for tests that require a clean shutdown.
If you do use this function to set a custom fetcher, and you control its termination, make sure that you call `jwk.SetGlobalFetcher()` one more time (possibly with `nil`) to assign a valid fetcher. Otherwise, once the fetcher is invalidated, subsequent calls to `jwk.Fetch` may hang, causing very hard to debug problems.
If you are sure you no longer need `jwk.Fetch` after terminating the fetcher, then you the above caution is not necessary.
Types ¶
type AssignKeyIDOption ¶
type AssignKeyIDOption interface { Option // contains filtered or unexported methods }
func WithThumbprintHash ¶
func WithThumbprintHash(v crypto.Hash) AssignKeyIDOption
type AsymmetricKey ¶ added in v2.0.14
type AsymmetricKey interface {
IsPrivate() bool
}
AsymmetricKey describes a Key that represents a key in an asymmetric key pair, which in turn can be either a private or a public key. This interface allows those keys to be queried if they are one or the other.
type Cache ¶
type Cache struct {
// contains filtered or unexported fields
}
Cache is a container that keeps track of Set object by their source URLs. The Set objects are stored in memory, and are refreshed automatically behind the scenes.
Before retrieving the Set objects, the user must pre-register the URLs they intend to use by calling `Register()`
c := jwk.NewCache(ctx) c.Register(url, options...)
Once registered, you can call `Get()` to retrieve the Set object.
All JWKS objects that are retrieved via this mechanism should be treated read-only, as they are shared among all consumers, as well as the `jwk.Cache` object.
There are cases where `jwk.Cache` and `jwk.CachedSet` should and should not be used.
First and foremost, do NOT use a cache for those JWKS objects that need constant checking. For example, unreliable or user-provided JWKS (i.e. those JWKS that are not from a well-known provider) should not be fetched through a `jwk.Cache` or `jwk.CachedSet`.
For example, if you have a flaky JWKS server for development that can go down often, you should consider alternatives such as providing `http.Client` with a caching `http.RoundTripper` configured (see `jwk.WithHTTPClient`), setting up a reverse proxy, etc. These techniques allow you to set up a more robust way to both cache and report precise causes of the problems than using `jwk.Cache` or `jwk.CachedSet`. If you handle the caching at the HTTP level like this, you will be able to use a simple `jwk.Fetch` call and not worry about the cache.
User-provided JWKS objects may also be problematic, as it may go down unexpectedly (and frequently!), and it will be hard to detect when the URLs or its contents are swapped.
A good use-case for `jwk.Cache` and `jwk.CachedSet` are for "stable" JWKS objects.
When we say "stable", we are thinking of JWKS that should mostly be ALWAYS available. A good example are those JWKS objects provided by major cloud providers such as Google Cloud, AWS, or Azure. Stable JWKS may still experience intermittent network connectivity problems, but you can expect that they will eventually recover in relatively short period of time. They rarely change URLs, and the contents are expected to be valid or otherwise it would cause havoc to those providers
We also know that these stable JWKS objects are rotated periodically, which is a perfect use for `jwk.Cache` and `jwk.CachedSet`. The caches can be configured to periodically refresh the JWKS thereby keeping them fresh without extra intervention from the developer.
Notice that for these recommended use-cases the requirement to check the validity or the availability of the JWKS objects are non-existent, as it is expected that they will be available and will be valid. The caching mechanism can hide intermittent connectivity problems as well as keep the objects mostly fresh.
func NewCache ¶
func NewCache(ctx context.Context, options ...CacheOption) *Cache
NewCache creates a new `jwk.Cache` object.
Please refer to the documentation for `httprc.New` for more details.
func (*Cache) Get ¶
Get returns the stored JWK set (`Set`) from the cache.
Please refer to the documentation for `(httprc.Cache).Get` for more details.
func (*Cache) IsRegistered ¶
IsRegistered returns true if the given URL `u` has already been registered in the cache.
Please refer to the documentation for `(httprc.Cache).IsRegistered` for more details.
func (*Cache) Refresh ¶
Refresh is identical to Get(), except it always fetches the specified resource anew, and updates the cached content
Please refer to the documentation for `(httprc.Cache).Refresh` for more details
func (*Cache) Register ¶
func (c *Cache) Register(u string, options ...RegisterOption) error
Register registers a URL to be managed by the cache. URLs must be registered before issuing `Get`
This method is almost identical to `(httprc.Cache).Register`, except it accepts some extra options.
Use `jwk.WithParser` to configure how the JWKS should be parsed, such as passing it extra options.
Please refer to the documentation for `(httprc.Cache).Register` for more details.
Register does not check for the validity of the url being registered. If you need to make sure that a url is valid before entering your main loop, call `Refresh` once to make sure the JWKS is available.
_ = cache.Register(url) if _, err := cache.Refresh(ctx, url); err != nil { // url is not a valid JWKS panic(err) }
func (*Cache) Unregister ¶
Unregister removes the given URL `u` from the cache.
Please refer to the documentation for `(httprc.Cache).Unregister` for more details.
type CacheOption ¶
type CacheOption interface { Option // contains filtered or unexported methods }
CacheOption is a type of Option that can be passed to the the `jwk.NewCache()` function.
func WithErrSink ¶
func WithErrSink(v ErrSink) CacheOption
WithErrSink specifies the `httprc.ErrSink` object that handles errors that occurred during the cache's execution.
See the documentation in `httprc.WithErrSink` for more details.
func WithRefreshWindow ¶
func WithRefreshWindow(v time.Duration) CacheOption
WithRefreshWindow specifies the interval between checks for refreshes.
See the documentation in `httprc.WithRefreshWindow` for more details.
type CachedSet ¶
type CachedSet struct {
// contains filtered or unexported fields
}
CachedSet is a thin shim over jwk.Cache that allows the user to cloak jwk.Cache as if it's a `jwk.Set`. Behind the scenes, the `jwk.Set` is retrieved from the `jwk.Cache` for every operation.
Since `jwk.CachedSet` always deals with a cached version of the `jwk.Set`, all operations that mutate the object (such as AddKey(), RemoveKey(), et. al) are no-ops and return an error.
Note that since this is a utility shim over `jwk.Cache`, you _will_ lose the ability to control the finer details (such as controlling how long to wait for in case of a fetch failure using `context.Context`)
Make sure that you read the documentation for `jwk.Cache` as well.
func (*CachedSet) AddKey ¶
Add is a no-op for `jwk.CachedSet`, as the `jwk.Set` should be treated read-only
func (*CachedSet) Clear ¶
Clear is a no-op for `jwk.CachedSet`, as the `jwk.Set` should be treated read-only
func (*CachedSet) Remove ¶
Remove is a no-op for `jwk.CachedSet`, as the `jwk.Set` should be treated read-only
type ECDSAPrivateKey ¶
type ECDSAPrivateKey interface { Key FromRaw(*ecdsa.PrivateKey) error Crv() jwa.EllipticCurveAlgorithm D() []byte X() []byte Y() []byte }
type ECDSAPublicKey ¶
type FetchOption ¶
type FetchOption interface { Option // contains filtered or unexported methods }
FetchOption is a type of Option that can be passed to `jwk.Fetch()` FetchOption also implements the `RegisterOption`, and thus can safely be passed to `(*jwk.Cache).Register()`
func WithFetchWhitelist ¶
func WithFetchWhitelist(v Whitelist) FetchOption
WithFetchWhitelist specifies the Whitelist object to use when fetching JWKs from a remote source. This option can be passed to both `jwk.Fetch()`, `jwk.NewCache()`, and `(*jwk.Cache).Configure()`
func WithHTTPClient ¶
func WithHTTPClient(v HTTPClient) FetchOption
WithHTTPClient allows users to specify the "net/http".Client object that is used when fetching jwk.Set objects.
type HTTPClient ¶
type HTTPClient = httprc.HTTPClient
type HeaderIterator ¶
type HeaderPair ¶
type HeaderVisitor ¶
type HeaderVisitor = iter.MapVisitor
type HeaderVisitorFunc ¶
type HeaderVisitorFunc = iter.MapVisitorFunc
type InsecureWhitelist ¶
type InsecureWhitelist struct{}
InsecureWhitelist allows any URLs to be fetched. This is the default behavior of `jwk.Fetch()`, but this exists to allow other libraries (such as jws, via jws.VerifyAuto) and users to be able to explicitly state that they intend to not check the URLs that are being fetched
func (InsecureWhitelist) IsAllowed ¶
func (InsecureWhitelist) IsAllowed(string) bool
type Key ¶
type Key interface { // Get returns the value of a single field. The second boolean return value // will be false if the field is not stored in the source // // This method, which returns an `interface{}`, exists because // these objects can contain extra _arbitrary_ fields that users can // specify, and there is no way of knowing what type they could be Get(string) (interface{}, bool) // Set sets the value of a single field. Note that certain fields, // notably "kty", cannot be altered, but will not return an error // // This method, which takes an `interface{}`, exists because // these objects can contain extra _arbitrary_ fields that users can // specify, and there is no way of knowing what type they could be Set(string, interface{}) error // Remove removes the field associated with the specified key. // There is no way to remove the `kty` (key type). You will ALWAYS be left with one field in a jwk.Key. Remove(string) error // Validate performs _minimal_ checks if the data stored in the key are valid. // By minimal, we mean that it does not check if the key is valid for use in // cryptographic operations. For example, it does not check if an RSA key's // `e` field is a valid exponent, or if the `n` field is a valid modulus. // Instead, it checks for things such as the _presence_ of some required fields, // or if certain keys' values are of particular length. // // Note that depending on th underlying key type, use of this method requires // that multiple fields in the key are properly populated. For example, an EC // key's "x", "y" fields cannot be validated unless the "crv" field is populated first. // // Validate is never called by `UnmarshalJSON()` or `Set`. It must explicitly be // called by the user Validate() error // Raw creates the corresponding raw key. For example, // EC types would create *ecdsa.PublicKey or *ecdsa.PrivateKey, // and OctetSeq types create a []byte key. // // If you do not know the exact type of a jwk.Key before attempting // to obtain the raw key, you can simply pass a pointer to an // empty interface as the first argument. // // If you already know the exact type, it is recommended that you // pass a pointer to the zero value of the actual key type (e.g. &rsa.PrivateKey) // for efficiency. Raw(interface{}) error // Thumbprint returns the JWK thumbprint using the indicated // hashing algorithm, according to RFC 7638 Thumbprint(crypto.Hash) ([]byte, error) // Iterate returns an iterator that returns all keys and values. // See github.com/lestrrat-go/iter for a description of the iterator. Iterate(ctx context.Context) HeaderIterator // Walk is a utility tool that allows a visitor to iterate all keys and values Walk(context.Context, HeaderVisitor) error // AsMap is a utility tool that returns a new map that contains the same fields as the source AsMap(context.Context) (map[string]interface{}, error) // PrivateParams returns the non-standard elements in the source structure // WARNING: DO NOT USE PrivateParams() IF YOU HAVE CONCURRENT CODE ACCESSING THEM. // Use `AsMap()` to get a copy of the entire header, or use `Iterate()` instead PrivateParams() map[string]interface{} // Clone creates a new instance of the same type Clone() (Key, error) // PublicKey creates the corresponding PublicKey type for this object. // All fields are copied onto the new public key, except for those that are not allowed. // // If the key is already a public key, it returns a new copy minus the disallowed fields as above. PublicKey() (Key, error) // KeyType returns the `kty` of a JWK KeyType() jwa.KeyType // KeyUsage returns `use` of a JWK KeyUsage() string // KeyOps returns `key_ops` of a JWK KeyOps() KeyOperationList // Algorithm returns the value of the `alg` field // // This field may contain either `jwk.SignatureAlgorithm` or `jwk.KeyEncryptionAlgorithm`. // This is why there exists a `jwa.KeyAlgorithm` type that encompasses both types. Algorithm() jwa.KeyAlgorithm // KeyID returns `kid` of a JWK KeyID() string // X509URL returns `x5u` of a JWK X509URL() string // X509CertChain returns `x5c` of a JWK X509CertChain() *cert.Chain // X509CertThumbprint returns `x5t` of a JWK X509CertThumbprint() string // X509CertThumbprintS256 returns `x5t#S256` of a JWK X509CertThumbprintS256() string // contains filtered or unexported methods }
Key defines the minimal interface for each of the key types. Their use and implementation differ significantly between each key types, so you should use type assertions to perform more specific tasks with each key
func FromRaw ¶
FromRaw creates a jwk.Key from the given key (RSA/ECDSA/symmetric keys).
The constructor auto-detects the type of key to be instantiated based on the input type:
- "crypto/rsa".PrivateKey and "crypto/rsa".PublicKey creates an RSA based key
- "crypto/ecdsa".PrivateKey and "crypto/ecdsa".PublicKey creates an EC based key
- "crypto/ed25519".PrivateKey and "crypto/ed25519".PublicKey creates an OKP based key
- []byte creates a symmetric key
func ParseKey ¶
func ParseKey(data []byte, options ...ParseOption) (Key, error)
ParseKey parses a single key JWK. Unlike `jwk.Parse` this method will report failure if you attempt to pass a JWK set. Only use this function when you know that the data is a single JWK.
Given a WithPEM(true) option, this function assumes that the given input is PEM encoded ASN.1 DER format key.
Note that a successful parsing of any type of key does NOT necessarily guarantee a valid key. For example, no checks against expiration dates are performed for certificate expiration, no checks against missing parameters are performed, etc.
func PublicKeyOf ¶
PublicKeyOf returns the corresponding public version of the jwk.Key. If `v` is a SymmetricKey, then the same value is returned. If `v` is already a public key, the key itself is returned.
If `v` is a private key type that has a `PublicKey()` method, be aware that all fields will be copied onto the new public key. It is the caller's responsibility to remove any fields, if necessary
If `v` is a raw key, the key is first converted to a `jwk.Key`
type KeyIterator ¶
type KeyOperation ¶
type KeyOperation string
const ( KeyOpSign KeyOperation = "sign" // (compute digital signature or MAC) KeyOpVerify KeyOperation = "verify" // (verify digital signature or MAC) KeyOpEncrypt KeyOperation = "encrypt" // (encrypt content) KeyOpDecrypt KeyOperation = "decrypt" // (decrypt content and validate decryption, if applicable) KeyOpWrapKey KeyOperation = "wrapKey" // (encrypt key) KeyOpUnwrapKey KeyOperation = "unwrapKey" // (decrypt key and validate decryption, if applicable) KeyOpDeriveKey KeyOperation = "deriveKey" // (derive key) KeyOpDeriveBits KeyOperation = "deriveBits" // (derive bits not to be used as a key) )
type KeyOperationList ¶
type KeyOperationList []KeyOperation
func (*KeyOperationList) Accept ¶
func (ops *KeyOperationList) Accept(v interface{}) error
func (*KeyOperationList) Get ¶
func (ops *KeyOperationList) Get() KeyOperationList
type KeyUsageType ¶
type KeyUsageType string
KeyUsageType is used to denote what this key should be used for
const ( // ForSignature is the value used in the headers to indicate that // this key should be used for signatures ForSignature KeyUsageType = "sig" // ForEncryption is the value used in the headers to indicate that // this key should be used for encrypting ForEncryption KeyUsageType = "enc" )
func (*KeyUsageType) Accept ¶
func (k *KeyUsageType) Accept(v interface{}) error
func (KeyUsageType) String ¶
func (k KeyUsageType) String() string
type KeyWithDecodeCtx ¶
type MapWhitelist ¶
type MapWhitelist struct {
// contains filtered or unexported fields
}
MapWhitelist is a jwk.Whitelist object comprised of a map of strings. If the URL exists in the map, then the URL is allowed to be fetched.
func NewMapWhitelist ¶
func NewMapWhitelist() *MapWhitelist
func (*MapWhitelist) Add ¶
func (w *MapWhitelist) Add(pat string) *MapWhitelist
func (*MapWhitelist) IsAllowed ¶
func (w *MapWhitelist) IsAllowed(u string) bool
type OKPPrivateKey ¶
type OKPPublicKey ¶
type OKPPublicKey interface { Key FromRaw(interface{}) error Crv() jwa.EllipticCurveAlgorithm X() []byte }
type ParseOption ¶
type ParseOption interface { Option // contains filtered or unexported methods }
ParseOption is a type of Option that can be passed to `jwk.Parse()` ParseOption also implements the `ReadFileOption` and `CacheOption`, and thus safely be passed to `jwk.ReadFile` and `(*jwk.Cache).Configure()`
func WithIgnoreParseError ¶
func WithIgnoreParseError(v bool) ParseOption
WithIgnoreParseError is only applicable when used with `jwk.Parse()` (i.e. to parse JWK sets). If passed to `jwk.ParseKey()`, the function will return an error no matter what the input is.
DO NOT USE WITHOUT EXHAUSTING ALL OTHER ROUTES FIRST.
The option specifies that errors found during parsing of individual keys are ignored. For example, if you had keys A, B, C where B is invalid (e.g. it does not contain the required fields), then the resulting JWKS will contain keys A and C only.
This options exists as an escape hatch for those times when a key in a JWKS that is irrelevant for your use case is causing your JWKS parsing to fail, and you want to get to the rest of the keys in the JWKS.
Again, DO NOT USE unless you have exhausted all other routes. When you use this option, you will not be able to tell if you are using a faulty JWKS, except for when there are JSON syntax errors.
func WithPEM ¶
func WithPEM(v bool) ParseOption
WithPEM specifies that the input to `Parse()` is a PEM encoded key.
func WithTypedField ¶
func WithTypedField(name string, object interface{}) ParseOption
WithTypedField allows a private field to be parsed into the object type of your choice. It works much like the RegisterCustomField, but the effect is only applicable to the jwt.Parse function call which receives this option.
While this can be extremely useful, this option should be used with caution: There are many caveats that your entire team/user-base needs to be aware of, and therefore in general its use is discouraged. Only use it when you know what you are doing, and you document its use clearly for others.
First and foremost, this is a "per-object" option. Meaning that given the same serialized format, it is possible to generate two objects whose internal representations may differ. That is, if you parse one _WITH_ the option, and the other _WITHOUT_, their internal representation may completely differ. This could potentially lead to problems.
Second, specifying this option will slightly slow down the decoding process as it needs to consult multiple definitions sources (global and local), so be careful if you are decoding a large number of tokens, as the effects will stack up.
type PostFetchFunc ¶
PostFetchFunc is a PostFetcher based on a function.
type PostFetcher ¶
type PostFetcher interface { // PostFetch receives the URL and the JWKS, after a successful // fetch and parse. // // It should return a `Set`, optionally modified, to be stored // in the cache for subsequent use PostFetch(string, Set) (Set, error) }
PostFetcher is an interface for objects that want to perform operations on the `Set` that was fetched.
type PublicKeyer ¶
type RSAPrivateKey ¶
type RSAPublicKey ¶
type ReadFileOption ¶
type ReadFileOption interface { Option // contains filtered or unexported methods }
ReadFileOption is a type of `Option` that can be passed to `jwk.ReadFile`
func WithFS ¶
func WithFS(v fs.FS) ReadFileOption
WithFS specifies the source `fs.FS` object to read the file from.
type RegexpWhitelist ¶
type RegexpWhitelist struct {
// contains filtered or unexported fields
}
RegexpWhitelist is a jwk.Whitelist object comprised of a list of *regexp.Regexp objects. All entries in the list are tried until one matches. If none of the *regexp.Regexp objects match, then the URL is deemed unallowed.
func NewRegexpWhitelist ¶
func NewRegexpWhitelist() *RegexpWhitelist
func (*RegexpWhitelist) Add ¶
func (w *RegexpWhitelist) Add(pat *regexp.Regexp) *RegexpWhitelist
func (*RegexpWhitelist) IsAllowed ¶
func (w *RegexpWhitelist) IsAllowed(u string) bool
IsAllowed returns true if any of the patterns in the whitelist returns true.
type RegisterOption ¶
type RegisterOption interface { Option // contains filtered or unexported methods }
RegisterOption describes options that can be passed to `(jwk.Cache).Register()`
func WithMinRefreshInterval ¶
func WithMinRefreshInterval(v time.Duration) RegisterOption
WithMinRefreshInterval specifies the minimum refresh interval to be used when using `jwk.Cache`. This value is ONLY used if you did not specify a user-supplied static refresh interval via `WithRefreshInterval`.
This value is used as a fallback value when tokens are refreshed.
When we fetch the key from a remote URL, we first look at the max-age directive from Cache-Control response header. If this value is present, we compare the max-age value and the value specified by this option and take the larger one.
Next we check for the Expires header, and similarly if the header is present, we compare it against the value specified by this option, and take the larger one.
Finally, if neither of the above headers are present, we use the value specified by this option as the next refresh timing
If unspecified, the minimum refresh interval is 1 hour
func WithPostFetcher ¶
func WithPostFetcher(v PostFetcher) RegisterOption
WithPostFetcher specifies the PostFetcher object to be used on the jwk.Set object obtained in `jwk.Cache`. This option can be used to, for example, modify the jwk.Set to give it key IDs or algorithm names after it has been fetched and parsed, but before it is cached.
func WithRefreshInterval ¶
func WithRefreshInterval(v time.Duration) RegisterOption
WithRefreshInterval specifies the static interval between refreshes of jwk.Set objects controlled by jwk.Cache.
Providing this option overrides the adaptive token refreshing based on Cache-Control/Expires header (and jwk.WithMinRefreshInterval), and refreshes will *always* happen in this interval.
type Set ¶
type Set interface { // AddKey adds the specified key. If the key already exists in the set, // an error is returned. AddKey(Key) error // Clear resets the list of keys associated with this set, emptying the // internal list of `jwk.Key`s, as well as clearing any other non-key // fields Clear() error // Get returns the key at index `idx`. If the index is out of range, // then the second return value is false. Key(int) (Key, bool) // Get returns the value of a private field in the key set. // // For the purposes of a key set, any field other than the "keys" field is // considered to be a private field. In other words, you cannot use this // method to directly access the list of keys in the set Get(string) (interface{}, bool) // Set sets the value of a single field. // // This method, which takes an `interface{}`, exists because // these objects can contain extra _arbitrary_ fields that users can // specify, and there is no way of knowing what type they could be. Set(string, interface{}) error // Remove removes the specified non-key field from the set. // Keys may not be removed using this method. See RemoveKey for // removing keys. Remove(string) error // Index returns the index where the given key exists, -1 otherwise Index(Key) int // Len returns the number of keys in the set Len() int // LookupKeyID returns the first key matching the given key id. // The second return value is false if there are no keys matching the key id. // The set *may* contain multiple keys with the same key id. If you // need all of them, use `Iterate()` LookupKeyID(string) (Key, bool) // RemoveKey removes the key from the set. // RemoveKey returns an error when the specified key does not exist // in set. RemoveKey(Key) error // Keys creates an iterator to iterate through all keys in the set. Keys(context.Context) KeyIterator // Iterate creates an iterator to iterate through all fields other than the keys Iterate(context.Context) HeaderIterator // Clone create a new set with identical keys. Keys themselves are not cloned. Clone() (Set, error) }
Set represents JWKS object, a collection of jwk.Key objects.
Sets can be safely converted to and from JSON using the standard `"encoding/json".Marshal` and `"encoding/json".Unmarshal`. However, if you do not know if the payload contains a single JWK or a JWK set, consider using `jwk.Parse()` to always get a `jwk.Set` out of it.
Since v1.2.12, JWK sets with private parameters can be parsed as well. Such private parameters can be accessed via the `Field()` method. If a resource contains a single JWK instead of a JWK set, private parameters are stored in _both_ the resulting `jwk.Set` object and the `jwk.Key` object .
func Fetch ¶
Fetch fetches a JWK resource specified by a URL. The url must be pointing to a resource that is supported by `net/http`.
If you are using the same `jwk.Set` for long periods of time during the lifecycle of your program, and would like to periodically refresh the contents of the object with the data at the remote resource, consider using `jwk.Cache`, which automatically refreshes jwk.Set objects asynchronously.
Please note that underneath the `jwk.Fetch` function, it uses a global object that spawns goroutines that are present until the go runtime exits. Initially this global variable is uninitialized, but upon calling `jwk.Fetch` once, it is initialized and goroutines are spawned. If you want to control the lifetime of these goroutines, you can call `jwk.SetGlobalFetcher` with a custom fetcher which is tied to a `context.Context` object that you can control.
func NewCachedSet ¶
func Parse ¶
func Parse(src []byte, options ...ParseOption) (Set, error)
Parse parses JWK from the incoming []byte.
For JWK sets, this is a convenience function. You could just as well call `json.Unmarshal` against an empty set created by `jwk.NewSet()` to parse a JSON buffer into a `jwk.Set`.
This function exists because many times the user does not know before hand if a JWK(s) resource at a remote location contains a single JWK key or a JWK set, and `jwk.Parse()` can handle either case, returning a JWK Set even if the data only contains a single JWK key
If you are looking for more information on how JWKs are parsed, or if you know for sure that you have a single key, please see the documentation for `jwk.ParseKey()`.
func ParseReader ¶
func ParseReader(src io.Reader, options ...ParseOption) (Set, error)
ParseReader parses a JWK set from the incoming byte buffer.
func ParseString ¶
func ParseString(s string, options ...ParseOption) (Set, error)
ParseString parses a JWK set from the incoming string.
func PublicSetOf ¶
PublicSetOf returns a new jwk.Set consisting of public keys of the keys contained in the set.
This is useful when you are generating a set of private keys, and you want to generate the corresponding public versions for the users to verify with.
Be aware that all fields will be copied onto the new public key. It is the caller's responsibility to remove any fields, if necessary.
type Transformer ¶
type Transformer = httprc.Transformer
type Whitelist ¶
Whitelist describes a set of rules that allows users to access a particular URL. By default all URLs are blocked for security reasons. You will HAVE to provide some sort of whitelist. See the documentation for github.com/lestrrat-go/httprc for more details.
type WhitelistFunc ¶
WhitelistFunc is a jwk.Whitelist object based on a function. You can perform any sort of check against the given URL to determine if it can be fetched or not.
func (WhitelistFunc) IsAllowed ¶
func (w WhitelistFunc) IsAllowed(u string) bool