AUTH4D-345 Sign-in method for every proof, and the token budget before the client lookup
Two fixes from the security review of the AUTH4D-333 (repository file docs/api-spec/auth4d-333.md) commit. No request or
response shape changes.
POST /oauth/authorize/continue: method for every proof
The sign-in method reported to Flows now comes from the redeemed proof’s purpose for every proof
the hosted login can redeem. Before this change, Google, Apple, Microsoft, Epic and SMS sign-ins
were reported as session. The method appears in the post_login trigger and the
user.signed_in event. The trigger’s context.provider names the same provider, except for
passkeys, which are not an identity provider.
proof_purpose |
Flows method |
context.provider |
|---|---|---|
email_verification |
email |
email |
discord_login |
discord |
discord |
steam_login |
steam |
steam |
google_login |
google |
google |
apple_login |
apple |
apple |
microsoft_login |
microsoft |
microsoft |
epic_login |
epic |
epic |
sms_verification |
phone |
phone |
sso_login |
sso |
sso |
passkey_login |
passkey |
(none) |
Without a proof (a reused hosted-login session) the method stays session. After a terms screen
(AUTH4D-160 (repository file docs/api-spec/auth4d-160.md)) the method of the original sign-in is kept. Email codes, magic links
and passwords all redeem email_verification proofs, so Flows sees email for all three; the
idp claim (AUTH4D-258 (repository file docs/api-spec/auth4d-258.md)) still tells them apart.
POST /oauth/token and POST /oauth/revoke: per-IP budget first
The per-IP budget (600 per minute, tokenRequestsPerIp) is now spent before the client is looked
up. A request whose client_id does not exist spends a unit too, so a burst of made-up client ids
from one address gets 429 slow_down instead of one database read each. A malformed client id is
refused before any budget is spent or any read is made.
The per-client budget and the client secret budget are still spent after the client is found and
before its secret is compared. Only their 429 carries CORS headers for the client’s registered
origin. The per-IP 429 has none, because no client is known yet.
Source: docs/api-spec/auth4d-345.md