rangerguard

package
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 23, 2024 License: MPL-2.0 Imports: 12 Imported by: 0

README

Ranger Guard Middleware

Both humans and agents can be authenticated and authorized for API access. When a request reaches the endpoint, it goes through several stages. The following diagram illustrates the flow:

            ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
                               ranger guard                  │
            │

┌─────────────┐ │ │ │ │ ┌─────────────┐ ┌─────────────┐ │ Human │───┬───▶│ authn 1 │ ┌───▶│ authz 1 │ │ │ │ │ │ └─────────────┘ │ └─────────────┘ ┌─────────────┐ └─────────────┘ │ │ │ │ │ │ │ │ │ │ │ │ ┌──▶│ Service │ ┌─────────────┐ │ ▼ │ ▼ ││ │ │ │ │ │ │ ┌─────────────┐ │ ┌─────────────┐ │ └─────────────┘ │ Agent │───┘ │ authn 2 │───┘ │ authz 2 │───┘│ │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─

Ranger Guard allows the specification of multiple authentication and authorization modules. Authentication modules are called in sequence until one of authentication middleware succeeds. If the incoming request cannot be authenticated, it is rejected with 401 HTTP status code. Otherwise the user is authenticated and its identifier is made available to subsequent authorization steps. If no authentication middleware is configured, the request is just denied.

Until now, we authenticated the user, the incoming request must still be authorized. If no authorization middleware is defined, all request are denied. If multiple authorization modules are configured, Ranger Guard checks each one, and if any module authorizes the request, then the request can proceed. If all of the modules deny the request, then the request is denied with 403 HTTP status code.

Authenticators

Ranger Guard uses Ranger's plugin mechanism to register its authentication modules. The aim of the authentication modules is to:

  1. ensure the entity is the right one
  2. ensure nobody tampered with the data in transit

This allows the server to cover 3 use cases:

  1. the server is able to verify that only valid clients are talking to its api
  2. ranger-generated client signs the request payload
  3. ranger-generated client use using cert pinning and verifies https cert to ensure it is the correct server

Out-of-the-box the following authentication method are available:

  • Certificate Authenticator
  • Static Token Authenticator
                                                            ┌───────────┐
                                                            │Google/Okta│
                                         ┌─────────────────▶│ /Keycloak │
                                         │                  └───────────┘
┌───────────────┐                 ┌─────────────┐
│      UI       │   Auth Header   │             │
│               │────────────────▶│OIDC Verifier│─────┐     ┌───────────┐
│               │                 │             │     │     │           │
└───────────────┘                 └─────────────┘     │     │           │
                                                      ├────▶│    API    │
┌───────────────┐                 ┌─────────────┐     │     │           │
│ Client + Cert │                 │             │     │     │           │
│               │────────────────▶│Cert Verifier│─────┘     └───────────┘
│               │                 │             │
└───────────────┘  Auth Header +  └─────────────┘
                  Signed Messages        │                  ┌───────────┐
                                         └─────────────────▶│    AMS    │
                                                            └───────────┘

Guard Example

# start the server
$ cd examples/rangerguard/server
$ go run main.go

# start the client
$ cd examples/rangerguard/client
$ go run client.go 

FAQ

How can the client trust the server?

The current pattern only authenticates the client to the server but not the server to the client. Clients should use certificate pinning and verify that the https certificate of the server is valid.

Generate certificates

This based on How to Generate & Use Private Keys using OpenSSL's Command Line Tool. Ranger Guard recommends the use of elliptic curves:

# list available curves
openssl ecparam -list_curves

# generate a private key
openssl ecparam -name secp384r1 -genkey -noout -out private-key.pem

# convert to PKCS8 private key
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in private-key.pem -out private-key.p8 

# generate corresponding public key
openssl ec -in private-key.pem -pubout -out public-key.pem

# create a self-signed certificate
openssl req -new -x509 -key private-key.pem -out cert.pem -days 360

To generate rsa certs:

#!/bin/bash
openssl genpkey -algorithm RSA \
    -pkeyopt rsa_keygen_bits:3072 \
    -pkeyopt rsa_keygen_pubexp:65537 | \
    openssl pkcs8 -topk8 -nocrypt -outform pem > rsa/rsa-3072-private-key.p8

openssl pkey -pubout -inform pem -outform pem \
    -in rsa/rsa-3072-private-key.p8 \
    -out rsa/rsa-3072-public-key.pem

References

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	AUTHENTICATION_DENIED_ERROR = status.Error(codes.Unauthenticated, "request permission unauthenticated")
	PERMISSION_DENIED_ERROR     = status.Error(codes.PermissionDenied, "request permission denied")
)

Functions

func New

func New(opts Options, next http.Handler) *guardMux

func NewUserContext

func NewUserContext(ctx context.Context, u user.User) context.Context

func UserFromContext

func UserFromContext(ctx context.Context) (u user.User, ok bool)

Types

type Hook

type Hook interface {
	Name() string
	// Run is called a call has a validated identity
	// it can optionally return a new Context that will be attached to the incoming request
	Run(context.Context, user.User, *http.Request) (context.Context, error)
}

type Options

type Options struct {
	Authenticators []authentication.Authenticator
	Authorizors    []authorization.Authorizor
	Hooks          []Hook
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL