I think the approach of defining a custom type is the most idiomatic one.
It may be slightly more safe to have something like
module Sec : sig
type t [@@deriving yojson]
val of_string : string -> t
val to_string : t -> string
end
just to prevent accidental type conversion, and maybe provide extra documentation around the intentions you have with the type