From e32e140c901e41f95df1bcf7c597f975e4be7a3b Mon Sep 17 00:00:00 2001 From: btoews Date: Wed, 24 Jul 2024 15:48:24 -0600 Subject: [PATCH] add support for fly.io macaroon authentication --- authorizer.go | 38 ++++++++++++++++++++++++++++++++++++++ secret.go | 7 +++++++ 2 files changed, 45 insertions(+) diff --git a/authorizer.go b/authorizer.go index 33e4b5e..46cf533 100644 --- a/authorizer.go +++ b/authorizer.go @@ -13,6 +13,8 @@ import ( "github.com/sirupsen/logrus" "github.com/superfly/macaroon" "github.com/superfly/macaroon/bundle" + "github.com/superfly/macaroon/flyio" + "github.com/superfly/macaroon/flyio/machinesapi" tkmac "github.com/superfly/tokenizer/macaroon" ) @@ -102,6 +104,42 @@ func (c *MacaroonAuthConfig) Macaroon(caveats ...macaroon.Caveat) (string, error return macaroon.ToAuthorizationHeader(mb), nil } +type FlyioMacaroonAuthConfig struct { + Access flyio.Access `json:"access"` +} + +func NewFlyioMacaroonAuthConfig(access *flyio.Access) *FlyioMacaroonAuthConfig { + return &FlyioMacaroonAuthConfig{Access: *access} +} + +var _ AuthConfig = new(FlyioMacaroonAuthConfig) + +func (c *FlyioMacaroonAuthConfig) AuthRequest(req *http.Request) error { + var ctx = req.Context() + + for _, tok := range proxyAuthorizationTokens(req) { + bun, err := bundle.ParseBundle(tkmac.Location, tok) + if err != nil { + logrus.WithError(err).Warn("bad macaroon format") + continue + } + + if _, err := bun.Verify(ctx, machinesapi.DefaultClient); err != nil { + logrus.WithError(err).Warn("bad macaroon signature") + continue + } + + if err := bun.Validate(&c.Access); err != nil { + logrus.WithError(err).Warn("bad macaroon authz") + continue + } + + return nil + } + + return fmt.Errorf("%w: bad or missing proxy auth", ErrNotAuthorized) +} + func proxyAuthorizationTokens(req *http.Request) (ret []string) { hdrLoop: for _, hdr := range req.Header.Values(headerProxyAuthorization) { diff --git a/secret.go b/secret.go index 178c85f..c3eeb9a 100644 --- a/secret.go +++ b/secret.go @@ -55,6 +55,7 @@ type wireSecret struct { *OAuthProcessorConfig `json:"oauth2_processor,omitempty"` *BearerAuthConfig `json:"bearer_auth,omitempty"` *MacaroonAuthConfig `json:"macaroon_auth,omitempty"` + *FlyioMacaroonAuthConfig `json:"flyio_macaroon_auth,omitempty"` AllowHosts []string `json:"allowed_hosts,omitempty"` AllowHostPattern string `json:"allowed_host_pattern,omitempty"` } @@ -67,6 +68,8 @@ func (s *Secret) MarshalJSON() ([]byte, error) { ws.BearerAuthConfig = a case *MacaroonAuthConfig: ws.MacaroonAuthConfig = a + case *FlyioMacaroonAuthConfig: + ws.FlyioMacaroonAuthConfig = a default: return nil, errors.New("bad auth config") } @@ -131,6 +134,10 @@ func (s *Secret) UnmarshalJSON(b []byte) error { na += 1 s.AuthConfig = ws.MacaroonAuthConfig } + if ws.FlyioMacaroonAuthConfig != nil { + na += 1 + s.AuthConfig = ws.FlyioMacaroonAuthConfig + } if na != 1 { return errors.New("bad auth config") }