Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Let's Encrypt specific API for resource GET w/o POST-as-GET #4577

Closed
cpu opened this issue Nov 25, 2019 · 0 comments · Fixed by #4645
Closed

Let's Encrypt specific API for resource GET w/o POST-as-GET #4577

cpu opened this issue Nov 25, 2019 · 0 comments · Fixed by #4645

Comments

@cpu
Copy link
Contributor

cpu commented Nov 25, 2019

RFC 8555 imposed access restrictions for polling ACME resources. Instead of GET requests to resource URLs the RFC specifies using POST-as-GET requests authenticated by the owning ACME account.

Historically Let's Encrypt has always made ACME resources (except Accounts) accessible by GET to anyone that knew the URL. In practice this enabled greater transparency and aided debugging, especially in the community forum context where aid often comes from community members without access to server side logs or the owning ACME account keypair.

We intend to require POST-as-GET to do our part in maintaining RFC 8555 compatibility but would like to continue to make resources available by URL without requiring authentication. One potential compromise is to make resources accessible outside of the RFC 8555 API namespace via a separate GETable API.

We do not want client developers to side-step full RFC 8555 compliance by over-fitting Let's Encrypt and using the special "GET resource" API to poll resources during the issuance flow. One approach to preventing this could be to only allow GET requests via the non-ACME API for (cert|order|authz|challenge) resources that are older than a specific threshold (say 5-10 minutes). For the purposes of transparency/archiving/debugging the time delay won't be significant. For real-time issuance it will be awkward and slow and encourage using POST-as-GET.

@cpu cpu changed the title Make order/authz/challenge/cert resources accessible without POST-as-GET Let' accessible without POST-as-GET Nov 25, 2019
@cpu cpu changed the title Let' accessible without POST-as-GET Let's Encrypt specific API for resource GET w/o POST-as-GET Nov 25, 2019
@jsha jsha assigned cpu Jan 14, 2020
@jsha jsha added this to the Sprint 2019-01-14 milestone Jan 14, 2020
@cpu cpu closed this as completed in #4645 Jan 15, 2020
cpu pushed a commit that referenced this issue Jan 15, 2020
This builds on the work @sh7dm started in #4600. I primarily did some
refactoring, added enforcement of the stale check for authorizations and
challenges, and completed the unit test coverage.

A new Boulder-specific (e.g. not specified by ACME / RFC 8555) API is added for
fetching order, authorization, challenge, and certificate resources by URL
without using POST-as-GET. Since we intend this API to only be used by humans
for debugging and we want to ensure ACME client devs use the standards compliant
method we restrict the GET API to only allowing access to "stale" resources
where the required staleness is defined by the WFE2 "staleTimeout"
configuration value (set to 5m in dev/CI).

Since authorizations don't have a creation date tracked we add
a `authorizationLifetimeDays` and `pendingAuthorizationLifetimeDays`
configuration parameter to the WFE2 that matches the RA's configuration. These
values are subtracted from the authorization expiry to find the creation date to
enforce the staleness check for authz/challenge GETs.

One other note: Resources accessed via the GET API will have Link relation URLs
pointing to the standard ACME API URL. E.g. a GET to a stale challenge will have
a response header with a link "up" relation URL pointing at the POST-as-GET URL
for the associated authorization. I wanted to avoid complicating
`prepAuthorizationForDisplay` and `prepChallengeForDisplay` to be aware of the
GET API and update or exclude the Link relations. This seems like a fine
trade-off since we don't expect machine consumption of the GET API results
(these are for human debugging).

Replaces #4600
Resolves #4577
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment