From 7802e1b9a00cb15a8daa2b734d3a64f0b7652368 Mon Sep 17 00:00:00 2001 From: Jeremy Wharton Date: Tue, 19 Mar 2024 02:24:13 -0500 Subject: [PATCH] metainfo: use API key version when validating actions This change passes the API key version to the method responsible for checking whether a macaroon action is allowed. This lets us support version-specific API key behavior, such as Object Lock features. https://github.com/storj/edge/issues/399 Change-Id: Ibd069f296827053ea7d686c29a9954e38ac5aff9 --- go.mod | 2 +- go.sum | 4 ++-- satellite/console/apikeys.go | 21 +++++++++++---------- satellite/metainfo/validation.go | 6 +++--- satellite/satellitedb/apikeys.go | 5 +++-- satellite/satellitedb/dbx/project.dbx | 1 + testsuite/storjscan/go.mod | 2 +- testsuite/storjscan/go.sum | 4 ++-- 8 files changed, 24 insertions(+), 21 deletions(-) diff --git a/go.mod b/go.mod index c3e9e1538e76..082844e3f306 100644 --- a/go.mod +++ b/go.mod @@ -59,7 +59,7 @@ require ( golang.org/x/time v0.5.0 gopkg.in/segmentio/analytics-go.v3 v3.1.0 gopkg.in/yaml.v3 v3.0.1 - storj.io/common v0.0.0-20240312163747-de28b7045716 + storj.io/common v0.0.0-20240318212839-5a486c1a50e5 storj.io/drpc v0.0.34 storj.io/eventkit v0.0.0-20240306141230-6cb545e5f892 storj.io/monkit-jaeger v0.0.0-20240221095020-52b0792fa6cd diff --git a/go.sum b/go.sum index 623c2becf888..624533ff30a7 100644 --- a/go.sum +++ b/go.sum @@ -886,8 +886,8 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= storj.io/common v0.0.0-20220719163320-cd2ef8e1b9b0/go.mod h1:mCYV6Ud5+cdbuaxdPD5Zht/HYaIn0sffnnws9ErkrMQ= -storj.io/common v0.0.0-20240312163747-de28b7045716 h1:V3jSwIiO1O8KtihdhC4vNhtr0BYUKNkJKFI6fvdPKiA= -storj.io/common v0.0.0-20240312163747-de28b7045716/go.mod h1:MFl009RHY4tIqySVNy/6EmgRw2q60d26h9N/nb7JxGU= +storj.io/common v0.0.0-20240318212839-5a486c1a50e5 h1:H+xFzNEzx9K1oj3pKd3afyL6AasBLSzB2+sYz4If8UU= +storj.io/common v0.0.0-20240318212839-5a486c1a50e5/go.mod h1:MFl009RHY4tIqySVNy/6EmgRw2q60d26h9N/nb7JxGU= storj.io/drpc v0.0.32/go.mod h1:6rcOyR/QQkSTX/9L5ZGtlZaE2PtXTTZl8d+ulSeeYEg= storj.io/drpc v0.0.34 h1:q9zlQKfJ5A7x8NQNFk8x7eKUF78FMhmAbZLnFK+og7I= storj.io/drpc v0.0.34/go.mod h1:Y9LZaa8esL1PW2IDMqJE7CFSNq7d5bQ3RI7mGPtmKMg= diff --git a/satellite/console/apikeys.go b/satellite/console/apikeys.go index bb38613a6d26..8792023f1d69 100644 --- a/satellite/console/apikeys.go +++ b/satellite/console/apikeys.go @@ -7,6 +7,7 @@ import ( "context" "time" + "storj.io/common/macaroon" "storj.io/common/uuid" ) @@ -53,16 +54,16 @@ type CreateAPIKeyResponse struct { // APIKeyInfo describing api key model in the database. type APIKeyInfo struct { - ID uuid.UUID `json:"id"` - ProjectID uuid.UUID `json:"projectId"` - ProjectPublicID uuid.UUID `json:"projectPublicId"` - CreatedBy uuid.UUID `json:"createdBy"` - UserAgent []byte `json:"userAgent"` - Name string `json:"name"` - Head []byte `json:"-"` - Secret []byte `json:"-"` - CreatedAt time.Time `json:"createdAt"` - Version uint `json:"version"` + ID uuid.UUID `json:"id"` + ProjectID uuid.UUID `json:"projectId"` + ProjectPublicID uuid.UUID `json:"projectPublicId"` + CreatedBy uuid.UUID `json:"createdBy"` + UserAgent []byte `json:"userAgent"` + Name string `json:"name"` + Head []byte `json:"-"` + Secret []byte `json:"-"` + CreatedAt time.Time `json:"createdAt"` + Version macaroon.APIKeyVersion `json:"version"` // TODO move this closer to metainfo ProjectRateLimit *int `json:"-"` diff --git a/satellite/metainfo/validation.go b/satellite/metainfo/validation.go index a879aea2c97f..ed1c04280b13 100644 --- a/satellite/metainfo/validation.go +++ b/satellite/metainfo/validation.go @@ -63,7 +63,7 @@ func (endpoint *Endpoint) validateAuth(ctx context.Context, header *pb.RequestHe return nil, err } - err = key.Check(ctx, keyInfo.Secret, action, endpoint.revocations) + err = key.Check(ctx, keyInfo.Secret, keyInfo.Version, action, endpoint.revocations) if err != nil { endpoint.log.Debug("unauthorized request", zap.Error(err)) return nil, rpcstatus.Error(rpcstatus.PermissionDenied, "Unauthorized API credentials") @@ -105,7 +105,7 @@ func (endpoint *Endpoint) validateAuthN(ctx context.Context, header *pb.RequestH } for _, p := range permissions { - err = key.Check(ctx, keyInfo.Secret, p.action, endpoint.revocations) + err = key.Check(ctx, keyInfo.Secret, keyInfo.Version, p.action, endpoint.revocations) if p.actionPermitted != nil { *p.actionPermitted = err == nil } @@ -135,7 +135,7 @@ func (endpoint *Endpoint) validateAuthAny(ctx context.Context, header *pb.Reques var combinedErrs error for _, action := range actions { - err = key.Check(ctx, keyInfo.Secret, action, endpoint.revocations) + err = key.Check(ctx, keyInfo.Secret, keyInfo.Version, action, endpoint.revocations) if err == nil { return keyInfo, nil } diff --git a/satellite/satellitedb/apikeys.go b/satellite/satellitedb/apikeys.go index 383eaa390d03..8bb591f66459 100644 --- a/satellite/satellitedb/apikeys.go +++ b/satellite/satellitedb/apikeys.go @@ -10,6 +10,7 @@ import ( "github.com/zeebo/errs" "storj.io/common/lrucache" + "storj.io/common/macaroon" "storj.io/common/uuid" "storj.io/storj/satellite/console" "storj.io/storj/satellite/satellitedb/dbx" @@ -208,7 +209,7 @@ func (keys *apikeys) Create(ctx context.Context, head []byte, info console.APIKe } optional := dbx.ApiKey_Create_Fields{ - Version: dbx.ApiKey_Version(info.Version), + Version: dbx.ApiKey_Version(uint(info.Version)), } if info.UserAgent != nil { optional.UserAgent = dbx.ApiKey_UserAgent(info.UserAgent) @@ -281,7 +282,7 @@ func apiKeyToAPIKeyInfo(ctx context.Context, key *dbx.ApiKey) (_ *console.APIKey CreatedAt: key.CreatedAt, Head: key.Head, Secret: key.Secret, - Version: key.Version, + Version: macaroon.APIKeyVersion(key.Version), } if key.UserAgent != nil { diff --git a/satellite/satellitedb/dbx/project.dbx b/satellite/satellitedb/dbx/project.dbx index eb5e93d74ef3..eb68791b260e 100644 --- a/satellite/satellitedb/dbx/project.dbx +++ b/satellite/satellitedb/dbx/project.dbx @@ -235,6 +235,7 @@ model api_key ( // created_by is an UUID of the user who created this key. field created_by user.id restrict (nullable) // version specifies the version number of the api key. + // It refers to storj.io/common/macaroon.APIKeyVersion. field version uint (default 0) ) diff --git a/testsuite/storjscan/go.mod b/testsuite/storjscan/go.mod index 16dff4c293f8..1c871401e891 100644 --- a/testsuite/storjscan/go.mod +++ b/testsuite/storjscan/go.mod @@ -9,7 +9,7 @@ require ( github.com/zeebo/errs v1.3.0 go.uber.org/zap v1.27.0 golang.org/x/sync v0.6.0 - storj.io/common v0.0.0-20240312163747-de28b7045716 + storj.io/common v0.0.0-20240318212839-5a486c1a50e5 storj.io/storj v1.63.1 storj.io/storjscan v0.0.0-20220926140643-1623c3b391b0 storj.io/uplink v1.12.3-0.20240227083244-7974a2e1a6c2 diff --git a/testsuite/storjscan/go.sum b/testsuite/storjscan/go.sum index 21aa10871c96..2027f00b1757 100644 --- a/testsuite/storjscan/go.sum +++ b/testsuite/storjscan/go.sum @@ -1209,8 +1209,8 @@ rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= storj.io/common v0.0.0-20220719163320-cd2ef8e1b9b0/go.mod h1:mCYV6Ud5+cdbuaxdPD5Zht/HYaIn0sffnnws9ErkrMQ= -storj.io/common v0.0.0-20240312163747-de28b7045716 h1:V3jSwIiO1O8KtihdhC4vNhtr0BYUKNkJKFI6fvdPKiA= -storj.io/common v0.0.0-20240312163747-de28b7045716/go.mod h1:MFl009RHY4tIqySVNy/6EmgRw2q60d26h9N/nb7JxGU= +storj.io/common v0.0.0-20240318212839-5a486c1a50e5 h1:H+xFzNEzx9K1oj3pKd3afyL6AasBLSzB2+sYz4If8UU= +storj.io/common v0.0.0-20240318212839-5a486c1a50e5/go.mod h1:MFl009RHY4tIqySVNy/6EmgRw2q60d26h9N/nb7JxGU= storj.io/drpc v0.0.32/go.mod h1:6rcOyR/QQkSTX/9L5ZGtlZaE2PtXTTZl8d+ulSeeYEg= storj.io/drpc v0.0.34 h1:q9zlQKfJ5A7x8NQNFk8x7eKUF78FMhmAbZLnFK+og7I= storj.io/drpc v0.0.34/go.mod h1:Y9LZaa8esL1PW2IDMqJE7CFSNq7d5bQ3RI7mGPtmKMg=