Module Webs_kit.Authenticatable

Authenticatable data.

This module defines a simple US-ASCII compatible encoding scheme to publish non-secret, expirable data bytes authenticatable via a secret private key. Human readability is a non-goal, storing your state in non-trusted environments is.

The data is not encrypted.



type time = int

The type for some notion of time to expire data. For example you can use a logical notion of time or the number of seconds since the epoch.


type private_key = string

The type for private keys. This is used with HMAC-SHA-256, so it should be at least 32 bytes long.

val random_private_key : unit -> private_key

random_private_key () are 64 bytes random bytes sourced after having called Stdlib.Random.self_init.


type t = string

The type for authenticatable bytes. The encoding scheme for bytes data and an optional expiration timestamp expire and private key private_key is:

expire = match expire with None -> "" | Some e -> string_of_int e
msg = expire + ":" + data
authenticatable = (base64|base64url)(hmac-sha-256(private_key, msg) + msg)
val encode : ?base64url:bool -> private_key:private_key -> expire:time option -> string -> t

encode ~private_key ~expire data makes data data expire at expire (if any) and authenticatable via the private key private_key. If base64url is true (defaults to false) the base64url encoding scheme is used instead of base64 (see Webs.Http.Base64).

val decode : ?base64url:bool -> private_key:private_key -> now:time -> t -> (time option * string, [ `Expired | `Decode | `Authentication ]) Stdlib.result

decode ~key ~now s authenticates data s with the private key key and makes it expire (if applicable) according to now. The result is:

  • Ok (expire, data) with data authenticated by private_key and now stricly smaller than expire (if any).
  • Error `Expired if the data could be authenticated but now is larger or equal to expire (if any).
  • Error `Authentication if s cannot be authenticated by key.
  • Error `Decode if any other decoding error occurs.

If base64url is true (defaults to false) the base64url encoding scheme is used instead of base64.

Untrusted decode

val untrusted_decode : ?base64url:bool -> t -> ([ `Untrusted of Sha_256.t * time option * string ][ `Decode ]) Stdlib.result

untrusted_decode s decodes the encoding structure of s but neither authenticates nor expires the data.