hydra-tx
Safe HaskellSafe-Inferred
LanguageGHC2021

Hydra.Tx.Secret

Description

A type-level barrier around values that must never be shown, logged, or serialised.

Wrapping a value in Secret makes the following a compile-time error (via TypeError) with a custom message:

  • ToJSON / FromJSON
  • ToCBOR / FromCBOR
  • Serialise

Show is provided but renders as a redacted placeholder ("<Secret field of type <typename>>"), so enclosing records can still deriving stock (Show) for free.

The only way to read the wrapped value is withSecret, a continuation- style accessor: there is intentionally no revealSecret :: Secret a -> a. That forces every consumption site to be a small lexical scope and keeps raw values from outliving the use site.

Synopsis
  • data Secret a
  • mkSecret :: a -> Secret a
  • withSecret :: Secret a -> (a -> r) -> r
  • type Forbid op = TypeError ((((((((('Text "Refusing to " ':<>: 'Text op) ':<>: 'Text " a value marked as secret.") ':$$: 'Text "Secret values (e.g. signing keys) must not be") ':$$: 'Text "shown, logged, or serialised. Use `withSecret` from") ':$$: 'Text "Hydra.Tx.Secret to consume the inner value at its") ':$$: 'Text "point of use (e.g. signing). If you got here from a") ':$$: 'Text "derived `Show` / `ToJSON` on an enclosing record,") ':$$: 'Text "either drop that deriving clause or write a") ':$$: 'Text "hand-rolled instance that omits the secret field.")

Documentation

data Secret a Source #

A value the type system refuses to show or serialise.

Instances

Instances details
(Forbid "decode from JSON" :: Constraint) => FromJSON (Secret a) Source # 
Instance details

Defined in Hydra.Tx.Secret

Methods

parseJSON :: Value -> Parser (Secret a)

parseJSONList :: Value -> Parser [Secret a]

omittedField :: Maybe (Secret a)

(Forbid "encode to JSON" :: Constraint) => ToJSON (Secret a) Source # 
Instance details

Defined in Hydra.Tx.Secret

Methods

toJSON :: Secret a -> Value

toEncoding :: Secret a -> Encoding

toJSONList :: [Secret a] -> Value

toEncodingList :: [Secret a] -> Encoding

omitField :: Secret a -> Bool

Typeable a => Show (Secret a) Source #

Renders as "<Secret field of type <typename>>". The Typeable constraint lets the instance name the wrapped type without ever touching the value. Enclosing records can keep using 'deriving stock (Show)' and get a redacted rendering for free.

Instance details

Defined in Hydra.Tx.Secret

(Typeable a, Forbid "CBOR-decode" :: Constraint) => FromCBOR (Secret a) Source # 
Instance details

Defined in Hydra.Tx.Secret

Methods

fromCBOR :: Decoder s (Secret a)

label :: Proxy (Secret a) -> Text

(Typeable a, Forbid "CBOR-encode" :: Constraint) => ToCBOR (Secret a) Source # 
Instance details

Defined in Hydra.Tx.Secret

Methods

toCBOR :: Secret a -> Encoding

encodedSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size) -> Proxy (Secret a) -> Size

encodedListSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size) -> Proxy [Secret a] -> Size

Eq a => Eq (Secret a) Source # 
Instance details

Defined in Hydra.Tx.Secret

Methods

(==) :: Secret a -> Secret a -> Bool Source #

(/=) :: Secret a -> Secret a -> Bool Source #

Ord a => Ord (Secret a) Source # 
Instance details

Defined in Hydra.Tx.Secret

Methods

compare :: Secret a -> Secret a -> Ordering Source #

(<) :: Secret a -> Secret a -> Bool Source #

(<=) :: Secret a -> Secret a -> Bool Source #

(>) :: Secret a -> Secret a -> Bool Source #

(>=) :: Secret a -> Secret a -> Bool Source #

max :: Secret a -> Secret a -> Secret a Source #

min :: Secret a -> Secret a -> Secret a Source #

CanSignTx (Secret (SigningKey PaymentKey)) Source # 
Instance details

Defined in Hydra.Tx.Crypto

Methods

signTx :: Secret (SigningKey PaymentKey) -> Tx -> Tx Source #

(Forbid "Serialise-encode" :: Constraint) => Serialise (Secret a) Source # 
Instance details

Defined in Hydra.Tx.Secret

Methods

encode :: Secret a -> Encoding

decode :: Decoder s (Secret a)

encodeList :: [Secret a] -> Encoding

decodeList :: Decoder s [Secret a]

(Key k, HasTypeProxy k) => HasVerificationKey (Secret (SigningKey k)) k Source # 
Instance details

Defined in Hydra.Tx.Crypto

withSecret :: Secret a -> (a -> r) -> r Source #

The only escape hatch. Continuation-style so the raw value is never bound at the call site outside the supplied function.

type Forbid op = TypeError ((((((((('Text "Refusing to " ':<>: 'Text op) ':<>: 'Text " a value marked as secret.") ':$$: 'Text "Secret values (e.g. signing keys) must not be") ':$$: 'Text "shown, logged, or serialised. Use `withSecret` from") ':$$: 'Text "Hydra.Tx.Secret to consume the inner value at its") ':$$: 'Text "point of use (e.g. signing). If you got here from a") ':$$: 'Text "derived `Show` / `ToJSON` on an enclosing record,") ':$$: 'Text "either drop that deriving clause or write a") ':$$: 'Text "hand-rolled instance that omits the secret field.") Source #