diff --git a/api/auth/center.go b/api/auth/center.go index bc9107d0..4ea8d2c2 100644 --- a/api/auth/center.go +++ b/api/auth/center.go @@ -37,9 +37,10 @@ type ( } center struct { - reg *RegexpSubmatcher - postReg *RegexpSubmatcher - cli tokens.Credentials + reg *RegexpSubmatcher + postReg *RegexpSubmatcher + cli tokens.Credentials + allowedAccessKeyIDPrefixes []string // empty slice means all access key ids are allowed } prs int @@ -85,11 +86,12 @@ func (p prs) Seek(_ int64, _ int) (int64, error) { var _ io.ReadSeeker = prs(0) // New creates an instance of AuthCenter. -func New(neoFS tokens.NeoFS, key *keys.PrivateKey, config *cache.Config) Center { +func New(neoFS tokens.NeoFS, key *keys.PrivateKey, prefixes []string, config *cache.Config) Center { return ¢er{ - cli: tokens.New(neoFS, key, config), - reg: NewRegexpMatcher(authorizationFieldRegexp), - postReg: NewRegexpMatcher(postPolicyCredentialRegexp), + cli: tokens.New(neoFS, key, config), + reg: NewRegexpMatcher(authorizationFieldRegexp), + postReg: NewRegexpMatcher(postPolicyCredentialRegexp), + allowedAccessKeyIDPrefixes: prefixes, } } @@ -171,6 +173,10 @@ func (c *center) Authenticate(r *http.Request) (*accessbox.Box, error) { return nil, fmt.Errorf("failed to parse x-amz-date header field: %w", err) } + if err := c.checkAccessKeyID(authHdr.AccessKeyID); err != nil { + return nil, err + } + addr, err := authHdr.getAddress() if err != nil { return nil, err @@ -189,6 +195,20 @@ func (c *center) Authenticate(r *http.Request) (*accessbox.Box, error) { return box, nil } +func (c center) checkAccessKeyID(accessKeyID string) error { + if len(c.allowedAccessKeyIDPrefixes) == 0 { + return nil + } + + for _, prefix := range c.allowedAccessKeyIDPrefixes { + if strings.HasPrefix(accessKeyID, prefix) { + return nil + } + } + + return apiErrors.GetAPIError(apiErrors.ErrAccessDenied) +} + func (c *center) checkFormData(r *http.Request) (*accessbox.Box, error) { if err := r.ParseMultipartForm(maxFormSizeMemory); err != nil { return nil, apiErrors.GetAPIError(apiErrors.ErrInvalidArgument) diff --git a/cmd/s3-gw/app.go b/cmd/s3-gw/app.go index bce3f145..85bf8c88 100644 --- a/cmd/s3-gw/app.go +++ b/cmd/s3-gw/app.go @@ -188,7 +188,7 @@ func newApp(ctx context.Context, l *zap.Logger, v *viper.Viper) *App { } // prepare auth center - ctr = auth.New(neofs.NewAuthmateNeoFS(conns), key, getAccessBoxCacheConfig(v, l)) + ctr = auth.New(neofs.NewAuthmateNeoFS(conns), key, v.GetStringSlice(cfgAllowedAccessKeyIDPrefixes), getAccessBoxCacheConfig(v, l)) handlerOptions := getHandlerOptions(v, l) if caller, err = handler.New(l, obj, nc, handlerOptions); err != nil { diff --git a/cmd/s3-gw/app_settings.go b/cmd/s3-gw/app_settings.go index 3909e697..bedaa247 100644 --- a/cmd/s3-gw/app_settings.go +++ b/cmd/s3-gw/app_settings.go @@ -116,6 +116,9 @@ const ( // Settings. // Number of the object copies to consider PUT to NeoFS successful. cfgSetCopiesNumber = "neofs.set_copies_number" + // List of allowed AccessKeyID prefixes. + cfgAllowedAccessKeyIDPrefixes = "allowed_access_key_id_prefixes" + // envPrefix is an environment variables prefix used for configuration. envPrefix = "S3_GW" )