# APIac
APIac: API access control for elixir

APIac is a standard interface for API access control and is composed of:
- `APIac.Authenticator`: an Elixir behaviour for API authentication plugs
- `APIac.Filter`: an Elixir behaviour for API filter plugs
- Convenience functions for working with APIac plugs and for HTTP APIs

The following APIac plugs are available:
- `APIac.Authenticator`:
  - [APIacAuthBasic]( implementatoin of the
  Basic HTTP authentication scheme ([RFC7617](
  - [APIacAuthBearer]( implementation of the
  Bearer HTTP authentication scheme ([RFC6750]( and the
  OAuth 2.0 Token Introspection ([RFC7662]( token
  verification method
  - [APIacAuthMTLS]( implementation of the
  OAuth 2.0 Mutual TLS Client Authentication and Certificate Bound Access Tokens
  - [APIacAuthClientJWT]( implementation
  of the client authentication part of [RFC7523](
  (JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants)
  - [APIacAuthClientSecretPost](
  implementation of the OAuth2 client secret post scheme
- `APIac.Filter`:
  - [APIacFilterIPWhitelist](
  IPv4 and IPv6 address whitelisting
  - [APIacFilterIPBlacklist](
  IPv4 and IPv6 address blacklisting
  - [APIacFilterThrottler]( throttler that
  can throttle on IP address, client, subject, URI, etc.

## Usage

Just use one or more of these aforementioned APIac plugs, this library will be automatically

## Chaining plugs

`APIac` interfaces are designed so that you can chain APIac plugs. Example:

pipeline :api_public do
  plug APIacAuthBasic,
    realm: "Public API",
    callback: &MyApp.get_client_secret/2,
    set_error_response: APIacAuthBasic.set_WWWauthenticate_header/3,
    error_response_verbosity: :debug},
  plug APIacAuthBearer,
      {APIacAuthBearer.Validator.Introspect, [
        issuer: ""
          {Tesla.Middleware.BasicAuth, [username: "client_id_123", password: "WN2P3Ci+meSLtVipc1EZhbFm2oZyMgWIx/ygQhngFbo"]}
    bearer_extract_methods: [:header, :body],
    required_scopes: ["article:write", "comments:moderate"],
    forward_bearer: true,
    cache: {APIacAuthBearerCacheCachex, []}
  plug APIacFilterThrottler,
    key: &APIacFilterThrottler.Functions.throttle_by_ip_path/1,
    scale: 60_000,
    limit: 50,
    exec_cond: &APIac.machine_to_machine?/1,
    error_response_verbosity: :debug}

## Terminology

APIac uses the OAuth2 terminology:
- the *client* is the server, the machine, accessing the API
- the *subject* is the pysical user (real life person) on behalf on who the API access is performed. Note even though in most cases the subject has authenticated, but it should not be used as a proof of authentication since:
  - this may have be a long time ago (using OAuth2 `refresh_token`)
  - this may not be true at all:
    - in case the subject is impersonnated
    - when using UMA2 flows
  - OAuth2 is an access control protocol, not a federated authentication protocol

APIac plugs are designed for API accesses. Therefore, **do not use it for end-user authentication** as this may lead to **security vulnerabilities**. For example, the `APIacAuthBasic` authenticator does not handle weak user passwords and using it for browser-based authentication by end-user **will** result in **security flaws**.

## Authenticators

The following table summarizes the information of the APIac authenticators:

| Authenticator    | Machine-to-machine         | Accesses of subjects (real persons)                                       |
| APIacAuthBasic | ✔ | |
| APIacAuthBearer | OAuth2 client credentials flow | OAuth2 authorization code, implicit and password flows<br/>OpenID Connect flows |
| APIacAuthMTLS | ✔ | |
| APIacAuthClientJWT | ✔ | |
| APIacAuthClientSecretPost | ✔ | |

Machine-to-machine (also known as server-to-server or s2s) refers to access when only machines are involved, without subject.