Skip to content

Commit

Permalink
Fly.io macaroon auth (#22)
Browse files Browse the repository at this point in the history
* use macaroon bundle API

* add support for fly.io macaroon authentication
  • Loading branch information
btoews authored Jul 26, 2024
1 parent 465e09d commit 9525286
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 24 deletions.
60 changes: 43 additions & 17 deletions authorizer.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package tokenizer

import (
"bytes"
"crypto/sha256"
"crypto/subtle"
"encoding/base64"
Expand All @@ -13,6 +12,9 @@ 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"
)

Expand Down Expand Up @@ -58,34 +60,22 @@ func (c *MacaroonAuthConfig) AuthRequest(req *http.Request) error {
var (
expectedKID = tkmac.KeyFingerprint(c.Key)
log = logrus.WithField("expected-kid", hex.EncodeToString(expectedKID))
ctx = req.Context()
)

for _, tok := range proxyAuthorizationTokens(req) {
permission, discharges, err := macaroon.ParsePermissionAndDischargeTokens(tok, tkmac.Location)
if err != nil {
log.WithError(err).Warn("bad macaroon encoding")
continue
}

m, err := macaroon.Decode(permission)
bun, err := bundle.ParseBundle(tkmac.Location, tok)
if err != nil {
log.WithError(err).Warn("bad macaroon format")
continue
}
log = log.WithFields(logrus.Fields{"uuid": m.Nonce.UUID()})

if !bytes.Equal(m.Nonce.KID, expectedKID) {
log.WithField("kid", hex.EncodeToString(m.Nonce.KID)).Warn("wrong macaroon key")
continue
}

cavs, err := m.Verify(c.Key, discharges, nil)
if err != nil {
if _, err = bun.Verify(ctx, bundle.WithKey(expectedKID, c.Key, nil)); err != nil {
log.WithError(err).Warn("bad macaroon signature")
continue
}

if err = cavs.Validate(&tkmac.Access{Request: req}); err != nil {
if err = bun.Validate(&tkmac.Access{Request: req}); err != nil {
log.WithError(err).Warn("bad macaroon authz")
continue
}
Expand Down Expand Up @@ -114,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 := flyio.ParseBundle(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) {
Expand Down
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@ module github.com/superfly/tokenizer
go 1.20

require (
github.com/alecthomas/assert/v2 v2.2.2
github.com/alecthomas/assert/v2 v2.3.0
github.com/elazarl/goproxy v0.0.0-20230731152917-f99041a5c027
github.com/sirupsen/logrus v1.9.3
github.com/superfly/macaroon v0.0.5
github.com/superfly/macaroon v0.2.14-0.20240718172852-139f90b76537
golang.org/x/crypto v0.12.0
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1
)

require (
github.com/alecthomas/repr v0.2.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/hexops/gotextdiff v1.0.3 // indirect
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
Expand Down
12 changes: 7 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
github.com/alecthomas/assert/v2 v2.2.2 h1:Z/iVC0xZfWTaFNE6bA3z07T86hd45Xe2eLt6WVy2bbk=
github.com/alecthomas/assert/v2 v2.2.2/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ=
github.com/alecthomas/assert/v2 v2.3.0 h1:mAsH2wmvjsuvyBvAmCtm7zFsBlb8mIHx5ySLVdDZXL0=
github.com/alecthomas/assert/v2 v2.3.0/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ=
github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk=
github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand All @@ -11,6 +11,8 @@ github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2 h1:dWB6v3RcOy0
github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand All @@ -22,8 +24,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/superfly/macaroon v0.0.5 h1:Rw48kdYc2k0PHccGnNWO0Byc5TQoJBjbQtzGZJPFKcU=
github.com/superfly/macaroon v0.0.5/go.mod h1:5DZuLe1e3EiEDs9R7snKQJVslVjgBhlJ9jbnOmKasRg=
github.com/superfly/macaroon v0.2.14-0.20240718172852-139f90b76537 h1:xL2tIkau3Dr3dd4WOLbGz14kRcF49x15bVIMdOkLTyI=
github.com/superfly/macaroon v0.2.14-0.20240718172852-139f90b76537/go.mod h1:Kt6/EdSYfFjR4GIe+erMwcJgU8iMu1noYVceQ5dNdKo=
github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU=
github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
Expand All @@ -36,5 +38,5 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
7 changes: 7 additions & 0 deletions secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
}
Expand All @@ -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")
}
Expand Down Expand Up @@ -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")
}
Expand Down

0 comments on commit 9525286

Please sign in to comment.