capi

package module
v0.0.0-...-2a10a93 Latest Latest
Warning

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

Go to latest
Published: Apr 7, 2020 License: MIT Imports: 18 Imported by: 0

README

capi - A S3 Gateway protected by OpenID Connect on top of Application Load Balancer

capi is a S3 gateway protected by OpenID Connect on top of AWS's Application Load Balancer.

Use-case

Problem: You want to host a static website on S3 but don't want to expose to everyone.

Solution: You can setup ALB with OpenID Connect and route requests to capi so that you can expose a static website on a private S3 bucket with the simple ACL by email address.

How it works

  • ALB authenticates you by OpenID Connect.
  • After the authentication succeeds, ALB routes a request to capi running on Lambda.
  • capi checks the JWT signed by ALB in x-amzn-oidc-data request header.
  • capi picks up a destination backend S3 by looking up host request header.
    • capi use AWS Parameter Store to store the configuration.
  • capi performs authorization before proxying a request to backend S3.
    • ACL (Access Control List; capiaccess.txt) is fetched from the destination S3 bucket so the owner can maintain it.
  • After the user is authorized to access the destination S3 bucket, capi proxyies requests to the S3 bucket.

Configuration

Let's say you want capi to route example.com to example-com S3 bucket in ap-northeast-1 region. You need to put the following JSON to the path on Parameter Store:

aws ssm put-parameter \
  --type String \
  --name '/capi/hosts/example.com' \
  --value '{"bucket": "example-com", "region": "ap-northeast-1"}'

then if you want give me@example.com and you@example.com access to your bucket, you can put ACL file (capiaccess.txt) to the root of the bucket (s3://example-com/capiaccess.txt):

me@example.com
you@example.com

or use the regular expression:

re/^(?:me|you)@example\.com$

Probably, you should have $ at the end.

ALB

Please read the ALB documentation to setup ALB and OpenID Connect. ALB needs to route requests to capi lambda function.

IAM

At least, you need to grant the lambda function to access S3 and SSM Parameter Store.

Deploy

make LAMBDA_FUNC_NAME=capi

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Authorize

func Authorize(target, pattern string) bool

func DebugHandler

func DebugHandler(dir func(*http.Request)) http.HandlerFunc

func NewProxy

func NewProxy(signer Signer) *httputil.ReverseProxy

Types

type ALBOIDCClaimSet

type ALBOIDCClaimSet struct {
	Iss   string `json:"iss"`
	Sub   string `json:"sub"`
	Email string `json:"email"`
	Exp   int64  `json:"exp"`
}

https://docs.aws.amazon.com/elasticloadbalancing/latest/application/listener-authenticate-users.html

func ALBOIDCClaimSetFromContext

func ALBOIDCClaimSetFromContext(ctx context.Context) ALBOIDCClaimSet

type AWSSigner

type AWSSigner struct {
	Signer *v4signer.Signer
}

func (*AWSSigner) Sign

func (s *AWSSigner) Sign(req *http.Request, signRegion string, signTime time.Time) error

type Authenticator

type Authenticator struct {
	JWKFetcher jwkset.Fetcher
}

func (*Authenticator) Handler

func (a *Authenticator) Handler(next http.Handler) http.Handler

type Authorizer

type Authorizer struct {
	Signer Signer

	Doer interface {
		Do(*http.Request) (*http.Response, error)
	}

	Cache *cache.Cache
}

Authorizer authorizes access to authenticated user based on policy document.

func (*Authorizer) Handler

func (a *Authorizer) Handler(next http.Handler) http.Handler

type Logger

type Logger struct {
	L zerolog.Logger
}

func (*Logger) Handler

func (l *Logger) Handler(next http.Handler) http.Handler

type S3Endpoint

type S3Endpoint struct {
	Bucket string `json:"bucket"`
	Region string `json:"region"`
}

func S3EndpointFromContext

func S3EndpointFromContext(ctx context.Context) S3Endpoint

func (S3Endpoint) URL

func (ep S3Endpoint) URL() *url.URL

func (S3Endpoint) Valid

func (ep S3Endpoint) Valid() bool

type S3EndpointResolver

type S3EndpointResolver struct {
	PSClient interface {
		GetParameter(string) (string, error)
	}

	Cache *cache.Cache
}

func (*S3EndpointResolver) Handler

func (r *S3EndpointResolver) Handler(next http.Handler) http.Handler

type Signer

type Signer interface {
	Sign(*http.Request, string, time.Time) error
}

Directories

Path Synopsis
cmd
capi command

Jump to

Keyboard shortcuts

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