Module Webs_authenticatable

Authenticatable data.

This module defines a simple US-ASCII compatible encoding scheme to publish non-encrypted, expirable data bytes that can be authentified with a private key. Human readability and secrecy is a non-goal, storing state in non-trusted environments is.

The data is not encrypted.

Note. The encoding scheme and module is designed with extensibility in mind. But for now only an HMAC-SHA-256 based scheme is defined.

type time = int

The type for some notion of time to expire data.

The semantics is left to the client. One can use a logical notion of time or the number of seconds since the Unix epoch.

module Private_key : sig ... end

Private keys.

Authenticatable

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 defined by:

exp = match expire with None -> "" | Some e -> string_of_int e
msg = exp ^ ":" ^ data
hs256 = "HS256:" ^ (hmac_sha_256 private_key msg)
auth = base64url (hs256 ^ msg)

Encode

val encode : private_key:Private_key.t -> expire:time option -> string -> t

encode ~private_key ~expire data makes data data expire at expire (if any) and authenticatable via the private key and scheme defined by private_key.

Decode

type format_error = [
  1. | `Base64url of Webs.Http.Base64.error
    (*

    base64url decode error.

    *)
  2. | `Scheme of string option
    (*

    Scheme name, if one was found.

    *)
]

The type for decode format errors.

val format_error_message : format_error -> string

format_error_message e is an english error message for e.

type error = [
  1. | `Authentication
    (*

    Authentication error.

    *)
  2. | `Expired of time
    (*

    Expiration time.

    *)
  3. | `Missing_now_for of time
    (*

    Expiration time.

    *)
  4. | `Format of format_error
    (*

    Decode format error

    *)
]

The type for decode and authentication errors. See decode.

val error_message : error -> string

error_message e is an english error message for e.

val error_string : ('a, error) Stdlib.result -> ('a, string) Stdlib.result

error_string r is Result.map_error error_message r.

val decode : private_key:Private_key.t -> now:time option -> t -> (time option * string, error) Stdlib.result

decode ~private_key ~now s authenticates data s with the private key and scheme defined by private_key and expires it (if applicable) according to now. If now is None and s has an expiration timestamp, the result errors. More precisely the result is:

  • Ok (expire, data) with data the authenticated bytes and expire the expiration timestamp iff s is authenticated by private_key and either:

    • expire is None
    • expire is Some t and now is Some now with now < t.
  • Error `Authentication if s cannot be authenticated by private_key.
  • Error (`Expired t), if s is authenticated by private_key and expires at t but now is Some now with now >= t.
  • Error (`Missing_now_for t), if s is authenticated by private_key and expires at t but now is None.
  • Error (`Format _) if any other decoding error occurs.

Untrusted decode

type untrusted = [
  1. | `Untrusted_hs256 of Webs_hash.Sha_256.t * time option * string
]

The type for untrusted decode results.

val untrusted_decode : t -> (untrusted, format_error) Stdlib.result

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