package resto-acl

  1. Overview
  2. Docs
Legend:
Library
Module
Module type
Parameter
Class
Class type

Access Control Lists (ACL): types and values to allow or deny access to specific parts of an API based on path matching.

type chunk_matcher =
  1. | Literal of string
  2. | Wildcard

path_matcher is the type of values that describe a path or a set of paths. Specifically,

  • Literal s matches path chunks that are identical to s,
  • Wildcard matches any single path chunk,
  • Exact chunks matches any path the chunks of which match chunks one-by-one,
  • FollowedByAnySuffix chunks matches any path that is a suffix of a path matched by Exact chunks.

E.g., Exact [Literal "users"; Wildcard; Literal "display-name"] matches the path "/users/Alice/display-name" and "/users/Bob/display-name", but not "/users/foo/preferences/", nor "/users/Bar/display-name/normalised".

E.g., FollowedByAnySuffix [Literal "admin"; Literal "keys"] matches the path "/admin/keys" and "admin/keys/gpg".

It is recommended that you use FollowedByAnySuffix in order to match a whole directory attached to a given prefix, or a whole set of services that are register under a common prefix.

It is recommended that you use Wildcard to match path-parameters (such as with the path "/users/<user-id>/".

It is _NOT_ recommended that you use Literal _ to match on the specific value of a parameter.

type path_matcher =
  1. | Exact of chunk_matcher list
  2. | FollowedByAnySuffix of chunk_matcher list
type meth_matcher =
  1. | Exact of Resto.meth
  2. | Any

meth_matcher is the type of values that describe a method or a set of methods. Exact m matches m whilst Any matches any method.

type matcher = {
  1. meth : meth_matcher;
  2. path : path_matcher;
}
val parse : string -> matcher

parse s parses the string s as a matcher. It raises Invalid_argument if the argument s is not in line with the following format.

A string representation of a matcher has the following components one after the other.

1. An optional method. If the method is absent, then Any is the method matcher. If the method is present it must be one of "GET"; "POST"; "DELETE"; "PUT"; "PATCH". 2. Any number (including none (0)) of spaces ( ). 3. A path which must start with a slash (/) and be followed by a sequence of chunks separated by slashes (/). Each chunk is either a single asterisk (*) (for Wildcard) or a non-empty sequence of characters (for Literal _). Special characters (see below) must be percentage-encoded. 4. An optional suffix slash-star-star ("/**") indicates FollowedByAnySuffix and it's absence is for Exact.

E.g., "/**" is a matcher for any method and any path. E.g., " /**" is the same matcher with extra (ignored) space (for alignment). E.g., "GET /**" is a matcher for the GET method and any path. E.g., "POST /admin/**" is a matcher for the POST method on any suffix of "/admin". E.g., "PATCH/*" is a matcher for the PATCH method on any single-chunk path. E.g., "/users/*/display-name" is a matcher for any method on paths that fit in the "/users/<user-id>/display-name" pattern.

Chunks cannot contain the following special characters. These characters must be represented percent-encoded. (Note that chunks are percent-decoded and the character percent (%) should appear percent-encoded (%25).

  • slash (/, represented by %2F)
  • asterisk (*, represented by %2A)
  • question mark (?, represented by %3F)
  • ampersand (&, represented by %26)
  • hash (#, represented by %23)
  • equal (=, represented by %3D)

Also note that each chunk is percent-decoded.

E.g., "GET /entries/by/year/2020/*/*" is a matcher for the GET method on paths that fit in the "/entries/by/year/2020/<month>/<day>" pattern. E.g., "GET /entries/by/year/20*/*/*" is not a valid matcher. The character asterisk (*) is not allowed within literal chunks. To match on the specific string "20*" use the percent-encoding 20%2A. You cannot match on regular expressions nor glob expansions using this Acl module.

  • raises {!Invalid_argument}

    if the path does not follow the format described above.

type t =
  1. | Allow_all of {
    1. except : matcher list;
    }
    (*

    Allow all by default but deny requests matched by the exception list.

    *)
  2. | Deny_all of {
    1. except : matcher list;
    }
    (*

    Deny all by default but allow requests matched by the exception list.

    *)

access policy

val allowed : t -> meth:Resto.meth -> path:string list -> bool