| Safe Haskell | Safe-Inferred |
|---|---|
| Language | GHC2021 |
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/FromJSONToCBOR/FromCBORSerialise
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
A value the type system refuses to show or serialise.
Instances
| (Forbid "decode from JSON" :: Constraint) => FromJSON (Secret a) Source # | |
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 # | |
Defined in Hydra.Tx.Secret Methods toEncoding :: Secret a -> Encoding toJSONList :: [Secret a] -> Value toEncodingList :: [Secret a] -> Encoding | |
| Typeable a => Show (Secret a) Source # | Renders as |
| (Typeable a, Forbid "CBOR-decode" :: Constraint) => FromCBOR (Secret a) Source # | |
| (Typeable a, Forbid "CBOR-encode" :: Constraint) => ToCBOR (Secret a) Source # | |
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 # | |
| Ord a => Ord (Secret a) Source # | |
Defined in Hydra.Tx.Secret | |
| CanSignTx (Secret (SigningKey PaymentKey)) Source # | |
Defined in Hydra.Tx.Crypto Methods signTx :: Secret (SigningKey PaymentKey) -> Tx -> Tx Source # | |
| (Forbid "Serialise-encode" :: Constraint) => Serialise (Secret a) Source # | |
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 # | |
Defined in Hydra.Tx.Crypto Methods getVerificationKey :: Secret (SigningKey k) -> VerificationKey k Source # | |
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 #