openfaas / of-watchdog

Reverse proxy for STDIO and HTTP microservices
MIT License
259 stars 115 forks source link

feat: add inline auth middleware #148

Open LucasRoesler opened 1 year ago

LucasRoesler commented 1 year ago

Description

This feature adds an authentication middleware to the of-watchdog. The authentication logic is loaded from external OPA policy files, so that function authors can customize the auth logic.

This policy can even be loaded via a Secret.

This middleware is configurable via several new environment variables, the user can customize: the policy, set a list of paths to skip authentication, control what request content is passed to the policy during evaluation (headers, raw body, json body, additional secret values, additional env variables).

In addition to loading and evaluating plain OPA rego policy files, the middleware defines two custom functions to enable more secure policy rules:

  1. bcrypt_eq exposes the bcrypt.CompareHashAndPassword method.
  2. constant_compare exposes the subtle.constant_compare method.

Extensive documentation of the configurations and behavior are now included in the README. Additional, example policies for Basic Auth, HMAC, JWT, and OIDC flows are included in the auth/testdata as well as unit tests that demonstrate how those policies behave.

Motivation and Context

If a function author is using a HTTP mode with a popular language and popular framework, they can probably implement this logic directly in the function. Adding it in the of-watchdog middleware means that:

  1. policies can be applied easily in all modes, for example forking and static modes will more easily support advanced auth flows like OAuth and OIDC.
  2. OPA Rego is language agnositc, so the same policy can be published and shared for any template or language. This reduces the complexity of ensuring that different functions are actually implementing the same policy rules because there is only one implementation.

OPA was chosen because it is part of the CloudNative landscape as a Graduated project and, for example, it is used by Istio.

How Has This Been Tested?

I have tested it locally with various test functions and via unit tests

Types of changes

Checklist: