Enforce new orders per acct per window rate limit.#3501
Conversation
Previously we introduced the concept of a "pending orders per account ID" rate limit. After struggling with making an implementation of this rate limit perform well we reevaluated the problem and decided a "new orders per account per time window" rate limit would be a better fit for ACMEv2 overall. This commit introduces the new `newOrdersPerAccount` rate limit. The RA now checks this before creating new pending orders in `ra.NewOrder`. It does so _after_ order reuse takes place ensuring the rate limit is only applied in cases when a distinct new pending order row would be created. For deployability the deprecated `pendingOrdersPerAccount` code & SA gRPC bits are left around. A follow-up PR will be needed to remove those.
jsha
left a comment
There was a problem hiding this comment.
Overall looks great, thanks for the quick turnaround on this! On nit: I think the SA method should be called CountOrders rather than CountNewOrders.
rolandshoemaker
left a comment
There was a problem hiding this comment.
Two small questions. Also currently there are no checks for order.Created in the various gRPC wrapper files, which is necessary for deployability but could we add a comment/open a issue that we will need to add those checks once the code has been deployed.
|
|
||
| // Check that the registration ID in question has rate limit space for another | ||
| // pending order | ||
| if err := ra.checkPendingOrderLimit(ctx, *req.RegistrationID); err != nil { |
There was a problem hiding this comment.
Should we not also kill off the checkPendingOrderLimit code?
There was a problem hiding this comment.
Sure, that makes sense. I think I was overly generous in what I left around for the deployability guidelines.
| // order | ||
|
|
||
| // Check if there is rate limit space for a new order within the current window | ||
| if err := ra.checkNewOrdersPerAccountLimit(ctx, *order.RegistrationID); err != nil { |
There was a problem hiding this comment.
I know this is for an API that isn't yet prod but given if this doesn't work how we want (or has negative side effects) I kind of think this should be gated behind a feature... I could probably be convinced that isn't needed though.
There was a problem hiding this comment.
I think this feedback and your feedback about killing off ra.checkPendingOrderLimit are hard to achieve together.
If I delete the ra.checkPendingOrderLimit impl in the RA (and the call from ra.NewOrder that is already deleted stays deleted), then the feature flag would make NewOrder limitless (minus the authz limits ofc) if disabled which seems more harmful overall.
I'm slightly inclined to not introduce the feature flag here.
There was a problem hiding this comment.
I think it could be done (i.e. if featureEnabled { limitA } else { limitB }) but your right it would require keeping the old code around. I'm fine going forward without it to be honest, I'm just hesitant that if we ever need to back it out we'll need to essentially revert and re-deploy, which is a pain.
That said... this code looks right enough to me, so I'm happy to just dive in head first 😄.
There was a problem hiding this comment.
I'm just hesitant that if we ever need to back it out we'll need to essentially revert and re-deploy, which is a pain.
That's true, but the pain of doing so only in staging is relatively minor compared to a prod revert.
There was a problem hiding this comment.
For rate limits, the limit.Enabled() flag acts as a good feature flag, since Enabled() will return false if there is not entry for that limit.
|
@jsha @rolandshoemaker Ready for more 🔍's |
|
Ping on
Otherwise looks fine. |
Missed that feedback, thanks! Resolved in 5fa5f33 |
#3501 made this code deprecated. We've deployed 3501 to the staging environment and can now pull out the old cruft.
Previously we introduced the concept of a "pending orders per account
ID" rate limit. After struggling with making an implementation of this
rate limit perform well we reevaluated the problem and decided a "new
orders per account per time window" rate limit would be a better fit for
ACMEv2 overall.
This commit introduces the new
newOrdersPerAccountrate limit. The RAnow checks this before creating new pending orders in
ra.NewOrder. Itdoes so after order reuse takes place ensuring the rate limit is only
applied in cases when a distinct new pending order row would be created.
To accomplish this a migration for a new
ordersfield (created) and anindex over
createdandregistrationIDis added. It would be possible touse the existing
expiresfield for this like we've done in the past, but thatwas primarily to avoid running a migration on a large table in prod. Since
we don't have that problem yet for V2 tables we can Do The Right Thing
and add a column.
For deployability the deprecated
pendingOrdersPerAccountcode & SAgRPC bits are left around. A follow-up PR will be needed to remove
those (#3502).
Resolves #3410