Skip to content

Commit

Permalink
Add client-side rate limiting for rekor ops (#54)
Browse files Browse the repository at this point in the history
We are hitting 429s with rekor, which only allows 500 requests per
minute.

Signed-off-by: Jon Johnson <jon.johnson@chainguard.dev>
  • Loading branch information
jonjohnsonjr authored Jul 31, 2023
1 parent 60d23a0 commit 8b84c16
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 0 deletions.
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ require (
github.com/sigstore/rekor v1.2.2
github.com/sigstore/sigstore v1.7.1
github.com/transparency-dev/merkle v0.0.2
go.uber.org/ratelimit v0.3.0
golang.org/x/oauth2 v0.10.0
)

Expand Down Expand Up @@ -92,6 +93,7 @@ require (
github.com/aws/aws-sdk-go-v2/service/sts v1.19.2 // indirect
github.com/aws/smithy-go v1.13.5 // indirect
github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20221027043306-dc425bc05c64 // indirect
github.com/benbjohnson/clock v1.3.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bgentry/speakeasy v0.1.0 // indirect
github.com/blang/semver v3.5.1+incompatible // indirect
Expand Down
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J
github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20221027043306-dc425bc05c64 h1:J+6PUCOmCU9A2iZDGsTGxdycxybJMp+fbFEMWWsQUgg=
github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20221027043306-dc425bc05c64/go.mod h1:oqbjAk8VeItfKctyahGuAyU61z4d0Fi1gHmlWjHWsMM=
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
Expand Down Expand Up @@ -1040,6 +1041,8 @@ go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/ratelimit v0.3.0 h1:IdZd9wqvFXnvLvSEBo0KPcGfkoBGNkpTHlrE3Rcjkjw=
go.uber.org/ratelimit v0.3.0/go.mod h1:So5LG7CV1zWpY1sHe+DXTJqQvOx+FFPFaAs2SnoyBaI=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
Expand Down
7 changes: 7 additions & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"net/url"
"sync"
"time"

"github.com/chainguard-dev/terraform-provider-cosign/internal/secant/fulcio"
"github.com/google/go-containerregistry/pkg/authn"
Expand All @@ -16,6 +17,7 @@ import (
"github.com/sigstore/fulcio/pkg/api"
rclient "github.com/sigstore/rekor/pkg/client"
"github.com/sigstore/rekor/pkg/generated/client"
"go.uber.org/ratelimit"
)

// Ensure Provider satisfies various provider interfaces.
Expand All @@ -42,6 +44,9 @@ type ProviderOpts struct {

// Keyed off rekor URL.
rekorClients map[string]*client.Rekor

// Client-side rate limiting to avoid rekor 429s.
limiter ratelimit.Limiter
}

func (p *ProviderOpts) rekorClient(rekorUrl string) (*client.Rekor, error) {
Expand Down Expand Up @@ -129,6 +134,8 @@ func (p *Provider) Configure(ctx context.Context, req provider.ConfigureRequest,
oidc: &oidcProvider{},
signers: map[string]*fulcio.SignerVerifier{},
rekorClients: map[string]*client.Rekor{},
// A little bird told me that rekor allows 500 requests per minute.
limiter: ratelimit.New(500, ratelimit.Per(time.Minute), ratelimit.WithoutSlack),
}

// Make provider opts available to resources and data sources.
Expand Down
3 changes: 3 additions & 0 deletions internal/provider/resource_attest.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,9 @@ func (r *AttestResource) doAttest(ctx context.Context, data *AttestResourceModel
return "", nil, fmt.Errorf("creating rekor client: %w", err)
}

// Avoid hitting rekor rate limits.
r.popts.limiter.Take()

ctx, cancel := context.WithTimeout(ctx, options.DefaultTimeout)
defer cancel()

Expand Down
3 changes: 3 additions & 0 deletions internal/provider/resource_sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ func (r *SignResource) doSign(ctx context.Context, data *SignResourceModel) (str
return "", nil, fmt.Errorf("creating rekor client: %w", err)
}

// Avoid hitting rekor rate limits.
r.popts.limiter.Take()

ctx, cancel := context.WithTimeout(ctx, options.DefaultTimeout)
defer cancel()

Expand Down

0 comments on commit 8b84c16

Please sign in to comment.