Documentation
¶
Index ¶
Constants ¶
const KeysMaxBatchSize = 100
KeysMaxBatchSize is a security used to limit the number of keys retrieved by a search operation.
Normally, regular key rotation and well configured expiration should limit the number of keys per batch, so the search request has no pagination. Since we can't overrule an issue that would cause the number of keys in a batch to balloon, this value is used as a security measurement, to guarantee an upper limit of keys retrieved.
Variables ¶
var ErrKeyNotFound = errors.New("key not found")
Functions ¶
Types ¶
type DeleteKeyData ¶
type DeleteKeyData struct {
// ID of the key to delete.
ID uuid.UUID
// Time at which the key is marked as deleted. This time might be set in the near future to delay the deletion.
//
// Once the date is reached, the key is considered as expired and becomes invisible to the application.
Now time.Time
// Comment explaining the circumstances surrounding the deletion of the key.
Comment string
}
DeleteKeyData is the input used to perform the DeleteKeyRepository.DeleteKey action.
type DeleteKeyRepository ¶
type DeleteKeyRepository struct{}
DeleteKeyRepository is the repository used to perform the DeleteKeyRepository.DeleteKey action.
You may create one using the NewDeleteKeyRepository function.
func NewDeleteKeyRepository ¶
func NewDeleteKeyRepository() *DeleteKeyRepository
func (*DeleteKeyRepository) DeleteKey ¶
func (repository *DeleteKeyRepository) DeleteKey(ctx context.Context, data DeleteKeyData) (*KeyEntity, error)
DeleteKey performs a soft delete of a KeyEntity.
A KeyEntity expires naturally through its KeyEntity.ExpiresAt field. However, some circumstances may require a key to be invalidated earlier (e.g. a security breach). In such cases, this method can be used.
Once a key is marked as deleted, it is not removed from the database to allow further investigation. It is simply removed from the main view, which means the application will not see it anymore.
As this method is not intended to be used "normally", a comment giving more details about the circumstance surrounding the deletion is required.
This method also returns an error when the key is not found, so you can be sure something was deleted on success. The deleted key is returned on success.
type InsertKeyData ¶
type InsertKeyData struct {
// ID of the new key. It MUST be unique (random).
ID uuid.UUID
// The private key in JSON Web Key format.
//
// The key MUST BE encrypted, and the result of this encryption is stored as a base64 raw URL encoded string.
PrivateKey string
// The public key in JSON Web Key format. The key is stored as a base64 raw URL encoded string.
//
// This value is OPTIONAL for symmetric keys.
PublicKey *string
// Intended usage of the key. See the type documentation for more details.
Usage models.KeyUsage
// Time at which the key was created. This is important when listing keys, as the most recent keys are
// used in priority.
Now time.Time
// Expiration of the key. Each key pair is REQUIRED to expire past a certain time. Once the expiration date
// is reached, the key pair becomes invisible to the keys view.
Expiration time.Time
}
InsertKeyData is the input used to perform the InsertKeyRepository.InsertKey action.
type InsertKeyRepository ¶
type InsertKeyRepository struct{}
InsertKeyRepository is the repository used to perform the InsertKeyRepository.InsertKey action.
You may create one using the NewInsertKeyRepository function.
func NewInsertKeyRepository ¶
func NewInsertKeyRepository() *InsertKeyRepository
func (*InsertKeyRepository) InsertKey ¶
func (repository *InsertKeyRepository) InsertKey(ctx context.Context, data InsertKeyData) (*KeyEntity, error)
InsertKey inserts a new key pair in the database.
A given key pair is REQUIRED to have an expiration date, as it must be rotated on a regular basis. Only public keys may be exposed to the application.
type KeyEntity ¶
type KeyEntity struct {
bun.BaseModel `bun:"table:keys,select:active_keys"`
// Unique identifier of the key.
ID uuid.UUID `bun:"id,pk,type:uuid"`
// The private key in JSON Web Key format.
//
// The key MUST BE encrypted, and the result of this encryption is stored as a base64 raw URL encoded string.
PrivateKey string `bun:"private_key"`
// The public key in JSON Web Key format. The key is stored as a base64 raw URL encoded string.
//
// This value is OPTIONAL for symmetric keys.
PublicKey *string `bun:"public_key"`
// Intended usage of the key. See the type documentation for more details.
Usage models.KeyUsage `bun:"usage"`
// Time at which the key was created. This is important when listing keys, as the most recent keys are
// used in priority.
CreatedAt time.Time `bun:"created_at"`
// Expiration of the key. Each key pair is REQUIRED to expire past a certain time. Once the expiration date
// is reached, the key pair becomes invisible to the keys view.
ExpiresAt time.Time `bun:"expires_at"`
// Time at which the key is marked as deleted. This field is the result of a manual, unexpected deletion
// consecutive to an abnormal event. Once this field is set, the key is no longer visible to the keys view.
DeletedAt *time.Time `bun:"deleted_at"`
// Comment explaining why the key was deleted. This field is set when the key is marked as deleted.
DeletedComment *string `bun:"deleted_comment"`
}
KeyEntity represents a public/private key pair used for Signature and Encryption purposes.
A given key pair is REQUIRED to have an expiration date, as it must be rotated on a regular basis. Only public keys may be exposed to the application.
type SearchKeysRepository ¶
type SearchKeysRepository struct{}
SearchKeysRepository is the repository used to perform the SearchKeysRepository.SearchKeys action.
You may create one using the NewSearchKeysRepository function.
func NewSearchKeysRepository ¶
func NewSearchKeysRepository() *SearchKeysRepository
func (*SearchKeysRepository) SearchKeys ¶
func (repository *SearchKeysRepository) SearchKeys(ctx context.Context, usage models.KeyUsage) ([]*KeyEntity, error)
SearchKeys lists keys related to a specific usage.
All keys that share the same usage are called a batch. A batch only contains active keys, and is ordered by creation date, from the most recent to the oldest. Most recent keys must be used in priority to issue new values. Older keys are provided for checking older values only.
While a call to SearchKeys should return every active key without exception, an upper limit is set to prevent a potential overhead of the response when too much active keys coexist. This limit is set to KeysMaxBatchSize. If a batch happens to contain more keys, an error is logged, and only the first KeysMaxBatchSize keys are returned.
type SelectKeyRepository ¶
type SelectKeyRepository struct{}
SelectKeyRepository is the repository used to perform the SelectKeyRepository.SelectKey action.
You may create one using the NewSelectKeyRepository function.
func NewSelectKeyRepository ¶
func NewSelectKeyRepository() *SelectKeyRepository
func (*SelectKeyRepository) SelectKey ¶
func (repository *SelectKeyRepository) SelectKey(ctx context.Context, id uuid.UUID) (*KeyEntity, error)
SelectKey returns a public/private key pair based on their unique identifier (ID).
The ID of a key pair is usually carried by the payload they were used on, for example thw KIS field of a JWT header. This allows to retrieve the exact key when performing reverse operations (signature verification or token decryption).