rfc9444v3.txt   rfc9444.txt 
Internet Engineering Task Force (IETF) O. Friel Internet Engineering Task Force (IETF) O. Friel
Request for Comments: 9444 R. Barnes Request for Comments: 9444 R. Barnes
Category: Standards Track Cisco Category: Standards Track Cisco
ISSN: 2070-1721 T. Hollebeek ISSN: 2070-1721 T. Hollebeek
DigiCert DigiCert
M. Richardson M. Richardson
Sandelman Software Works Sandelman Software Works
July 2023 August 2023
Automated Certificate Management Environment (ACME) for Subdomains Automated Certificate Management Environment (ACME) for Subdomains
Abstract Abstract
This document specifies how Automated Certificate Management This document specifies how Automated Certificate Management
Environment (ACME) can be used by a client to obtain a certificate Environment (ACME) can be used by a client to obtain a certificate
for a subdomain identifier from a certification authority. for a subdomain identifier from a certification authority.
Additionally, this document specifies how a client can fulfill a Additionally, this document specifies how a client can fulfill a
challenge against an ancestor domain but may not need to fulfill a challenge against an ancestor domain but may not need to fulfill a
skipping to change at line 291 skipping to change at line 291
specified domain, as opposed to just requesting authorization for an specified domain, as opposed to just requesting authorization for an
explicit domain identifier. Clients need a mechanism to do this in explicit domain identifier. Clients need a mechanism to do this in
both newAuthz and newOrder requests. ACME servers need a mechanism both newAuthz and newOrder requests. ACME servers need a mechanism
to indicate to clients that authorization objects are valid for all to indicate to clients that authorization objects are valid for all
subdomains under the specified domain. These are described in this subdomains under the specified domain. These are described in this
section. section.
4.1. Authorization Object 4.1. Authorization Object
ACME ([RFC8555], Section 7.1.4) defines the authorization object. ACME ([RFC8555], Section 7.1.4) defines the authorization object.
This document defines a new "subdomainAuthAllowed" field for the This document defines a new subdomainAuthAllowed field for the
authorization object. When ACME server policy allows authorization authorization object. When ACME server policy allows authorization
for subdomains subordinate to a domain, the server indicates this by for subdomains subordinate to a domain, the server indicates this by
including the new "subdomainAuthAllowed" field in the authorization including the new subdomainAuthAllowed field in the authorization
object for that domain identifier: object for that domain identifier:
subdomainAuthAllowed (optional, boolean): If present, this field subdomainAuthAllowed (optional, boolean): If present, this field
MUST be true for authorizations where ACME server policy allows MUST be true for authorizations where ACME server policy allows
certificates to be issued for any subdomain subordinate to the certificates to be issued for any subdomain subordinate to the
domain specified in the identifier field of the authorization domain specified in the identifier field of the authorization
object. object.
The following example shows an authorization object for the domain The following example shows an authorization object for the domain
example.org, where the authorization covers the subdomains example.org, where the authorization covers the subdomains
skipping to change at line 329 skipping to change at line 329
"type": "http-01", "type": "http-01",
"status": "valid", "status": "valid",
"token": "DGyRejmCefe7v4NfDGDKfA", "token": "DGyRejmCefe7v4NfDGDKfA",
"validated": "2014-12-01T12:05:58.16Z" "validated": "2014-12-01T12:05:58.16Z"
} }
], ],
"subdomainAuthAllowed": true "subdomainAuthAllowed": true
} }
If the "subdomainAuthAllowed" field is not included, then the assumed If the subdomainAuthAllowed field is not included, then the assumed
default value is false. default value is false.
If ACME server policy allows issuance of certificates containing If ACME server policy allows issuance of certificates containing
wildcard identifiers under that authorization object, then the server wildcard identifiers under that authorization object, then the server
SHOULD include the "wildcard" field with a value of true, as per SHOULD include the wildcard field with a value of true, as per
[RFC8555], Section 7.1.4. [RFC8555], Section 7.1.4.
4.2. Pre-authorization 4.2. Pre-authorization
The basic ACME workflow has authorization objects created reactively The basic ACME workflow has authorization objects created reactively
in response to a certificate order. ACME also allows for pre- in response to a certificate order. ACME also allows for pre-
authorization, where clients obtain authorization for an identifier authorization, where clients obtain authorization for an identifier
proactively, outside of the context of a specific issuance. With the proactively, outside of the context of a specific issuance. With the
ACME pre-authorization flow, a client can pre-authorize for a domain ACME pre-authorization flow, a client can pre-authorize for a domain
once and then issue multiple newOrder requests for certificates with once and then issue multiple newOrder requests for certificates with
identifiers in the subdomains subordinate to that domain. identifiers in the subdomains subordinate to that domain.
ACME ([RFC8555], Section 7.4.1) defines the identifier object for ACME ([RFC8555], Section 7.4.1) defines the identifier object for
newAuthz requests. This document defines a new newAuthz requests. This document defines a new subdomainAuthAllowed
"subdomainAuthAllowed" field for the identifier object: field for the identifier object:
subdomainAuthAllowed (optional, boolean): An ACME client sets this subdomainAuthAllowed (optional, boolean): An ACME client sets this
flag to indicate to the server that it is requesting an flag to indicate to the server that it is requesting an
authorization for the subdomains subordinate to the specified authorization for the subdomains subordinate to the specified
domain identifier value. domain identifier value.
Clients include the new "subdomainAuthAllowed" field in the Clients include the new subdomainAuthAllowed field in the identifier
identifier object of newAuthz requests to indicate that they are object of newAuthz requests to indicate that they are requesting a
requesting a subdomain authorization. In the following example of a subdomain authorization. In the following example of a newAuthz
newAuthz payload, the client is requesting pre-authorization for the payload, the client is requesting pre-authorization for the
subdomains subordinate to example.org. subdomains subordinate to example.org.
"payload": base64url({ "payload": base64url({
"identifier": { "identifier": {
"type": "dns", "type": "dns",
"value": "example.org", "value": "example.org",
"subdomainAuthAllowed": true "subdomainAuthAllowed": true
} }
}) })
If the server is willing to allow a single authorization for the If the server is willing to allow a single authorization for the
subdomains and there is not an existing authorization object for the subdomains and there is not an existing authorization object for the
identifier, then it will create an authorization object and include identifier, then it will create an authorization object and include
the "subdomainAuthAllowed" flag with a value of true. the subdomainAuthAllowed flag with a value of true.
If the server policy does not allow creation of subdomain If the server policy does not allow creation of subdomain
authorizations subordinate to that domain, the server can create an authorizations subordinate to that domain, the server can create an
authorization object for the indicated identifier and MAY include the authorization object for the indicated identifier and MAY include the
"subdomainAuthAllowed" flag with a value of false. If the server subdomainAuthAllowed flag with a value of false. If the server
creates an authorization object and does not include the creates an authorization object and does not include the
"subdomainAuthAllowed" flag, then the assumed value is false. subdomainAuthAllowed flag, then the assumed value is false.
In both scenarios, handling of the pre-authorization follows the In both scenarios, handling of the pre-authorization follows the
process documented in ACME [RFC8555], Section 7.4.1. process documented in ACME [RFC8555], Section 7.4.1.
4.3. New Orders 4.3. New Orders
Clients need a mechanism to optionally indicate to servers whether or Clients need a mechanism to optionally indicate to servers whether or
not they are authorized to fulfill challenges against an ancestor not they are authorized to fulfill challenges against an ancestor
domain for a given identifier. For example, if a client places an domain for a given identifier. For example, if a client places an
order for an identifier foo.bar.example.org and is authorized to order for an identifier foo.bar.example.org and is authorized to
fulfill a challenge against the ancestor domains bar.example.org or fulfill a challenge against the ancestor domains bar.example.org or
example.org, then the client needs a mechanism to indicate control example.org, then the client needs a mechanism to indicate control
over the ancestor domains to the ACME server. over the ancestor domains to the ACME server.
In order to accomplish this, this document defines a new In order to accomplish this, this document defines a new
"ancestorDomain" field for the identifier that is included in order ancestorDomain field for the identifier that is included in order
objects. objects.
ancestorDomain (optional, string): This is an ancestor domain of the ancestorDomain (optional, string): This is an ancestor domain of the
requested identifier. The client MUST be able to fulfill a requested identifier. The client MUST be able to fulfill a
challenge against the ancestor domain. challenge against the ancestor domain.
This field specifies an ancestor domain of the identifier that the This field specifies an ancestor domain of the identifier that the
client has DNS control over and is capable of fulfilling challenges client has DNS control over and is capable of fulfilling challenges
against. Based on server policy, the server can choose to issue a against. Based on server policy, the server can choose to issue a
challenge against any ancestor domain of the identifier up to and challenge against any ancestor domain of the identifier up to and
including the specified "ancestorDomain" and create a corresponding including the specified ancestorDomain and create a corresponding
authorization object against the chosen identifier. authorization object against the chosen identifier.
In the following example of a newOrder payload, the client requests a In the following example of a newOrder payload, the client requests a
certificate for identifier foo.bar.example.org and indicates that it certificate for identifier foo.bar.example.org and indicates that it
can fulfill a challenge against the ancestor domain bar.example.org. can fulfill a challenge against the ancestor domain bar.example.org.
The server can then choose to issue a challenge against either The server can then choose to issue a challenge against either
foo.bar.example.org or bar.example.org identifiers. foo.bar.example.org or bar.example.org identifiers.
"payload": base64url({ "payload": base64url({
"identifiers": [ "identifiers": [
skipping to change at line 443 skipping to change at line 443
"identifiers": [ "identifiers": [
{ "type": "dns", { "type": "dns",
"value": "foo.bar.example.org", "value": "foo.bar.example.org",
"ancestorDomain": "example.org" } "ancestorDomain": "example.org" }
], ],
"notBefore": "2023-09-01T00:04:00+04:00", "notBefore": "2023-09-01T00:04:00+04:00",
"notAfter": "2023-09-08T00:04:00+04:00" "notAfter": "2023-09-08T00:04:00+04:00"
}) })
If the client is unable to fulfill authorizations against an ancestor If the client is unable to fulfill authorizations against an ancestor
domain, the client should not include the "ancestorDomain" field. domain, the client should not include the ancestorDomain field.
Server newOrder handling generally follows the process documented in Server newOrder handling generally follows the process documented in
ACME (Section 7.4 of [RFC8555]). If the server is willing to allow ACME (Section 7.4 of [RFC8555]). If the server is willing to allow
subdomain authorizations for the domain specified in subdomain authorizations for the domain specified in ancestorDomain,
"ancestorDomain", then it creates an authorization object against then it creates an authorization object against that ancestor domain
that ancestor domain and includes the "subdomainAuthAllowed" flag and includes the subdomainAuthAllowed flag with a value of true.
with a value of true.
If the server policy does not allow creation of subdomain If the server policy does not allow creation of subdomain
authorizations against that ancestor domain, then it can create an authorizations against that ancestor domain, then it can create an
authorization object for the indicated identifier value and SHOULD authorization object for the indicated identifier value and SHOULD
NOT include the "subdomainAuthAllowed" flag. As the client requested NOT include the subdomainAuthAllowed flag. As the client requested a
a subdomain authorization for the ancestor domain and not for the subdomain authorization for the ancestor domain and not for the
indicated identifier, there is no need for the server to include the indicated identifier, there is no need for the server to include the
"subdomainAuthAllowed" flag in the authorization object for the subdomainAuthAllowed flag in the authorization object for the
indicated identifier. indicated identifier.
4.4. Directory Object Metadata 4.4. Directory Object Metadata
This document defines a new "subdomainAuthAllowed" ACME directory This document defines a new subdomainAuthAllowed ACME directory
metadata field. An ACME server can advertise support for metadata field. An ACME server can advertise support for
authorization of subdomains by including the "subdomainAuthAllowed" authorization of subdomains by including the subdomainAuthAllowed
boolean flag in its "ACME Directory Metadata Fields" registry: boolean flag in its "ACME Directory Metadata Fields" registry:
subdomainAuthAllowed (optional, bool): Indicates if an ACME server subdomainAuthAllowed (optional, bool): Indicates if an ACME server
supports authorization of subdomains. supports authorization of subdomains.
If not specified, then the assumed default value is false. If an If not specified, then the assumed default value is false. If an
ACME server supports authorization of subdomains, it can indicate ACME server supports authorization of subdomains, it can indicate
this by including this field with a value of "true". this by including this field with a value of "true".
5. Illustrative Call Flow 5. Illustrative Call Flow
skipping to change at line 557 skipping to change at line 556
| POST /certificate | | | POST /certificate | |
|--------------------------->| | |--------------------------->| |
| | | | | |
| 200 OK | | | 200 OK | |
| PEM SAN "sub2.example.org" | | | PEM SAN "sub2.example.org" | |
|<---------------------------| | |<---------------------------| |
* Step 1: Pre-authorization of ancestor domain. * Step 1: Pre-authorization of ancestor domain.
The client sends a newAuthz request for the ancestor domain and The client sends a newAuthz request for the ancestor domain and
includes the "subdomainAuthAllowed" flag in the identifier object. includes the subdomainAuthAllowed flag in the identifier object.
POST /acme/new-authz HTTP/1.1 POST /acme/new-authz HTTP/1.1
Host: example.com Host: example.com
Content-Type: application/jose+json Content-Type: application/jose+json
{ {
"protected": base64url({ "protected": base64url({
"alg": "ES256", "alg": "ES256",
"kid": "https://example.com/acme/acct/evOfKhNU60wg", "kid": "https://example.com/acme/acct/evOfKhNU60wg",
"nonce": "uQpSjlRb4vQVCjVYAyyUWg", "nonce": "uQpSjlRb4vQVCjVYAyyUWg",
skipping to change at line 581 skipping to change at line 580
"identifier": { "identifier": {
"type": "dns", "type": "dns",
"value": "example.org", "value": "example.org",
"subdomainAuthAllowed": true "subdomainAuthAllowed": true
} }
}), }),
"signature": "nuSDISbWG8mMgE7H...QyVUL68yzf3Zawps" "signature": "nuSDISbWG8mMgE7H...QyVUL68yzf3Zawps"
} }
The server creates and returns an authorization object for the The server creates and returns an authorization object for the
identifier that includes the "subdomainAuthAllowed" flag. The identifier that includes the subdomainAuthAllowed flag. The
object is initially in "pending" state. object is initially in "pending" state.
{ {
"status": "pending", "status": "pending",
"expires": "2023-09-01T14:09:07.99Z", "expires": "2023-09-01T14:09:07.99Z",
"identifier": { "identifier": {
"type": "dns", "type": "dns",
"value": "example.org" "value": "example.org"
}, },
skipping to change at line 629 skipping to change at line 628
the client's challenge immediately with a status of "processing" the client's challenge immediately with a status of "processing"
and the client will then need to poll the authorization resource and the client will then need to poll the authorization resource
to see when it is finalized. Refer to Section 7.5.1 of [RFC8555] to see when it is finalized. Refer to Section 7.5.1 of [RFC8555]
for more details. for more details.
* Step 2: The client places a newOrder for sub1.example.org. * Step 2: The client places a newOrder for sub1.example.org.
The client sends a newOrder request to the server and includes the The client sends a newOrder request to the server and includes the
subdomain identifier. Note that the identifier is a subdomain of subdomain identifier. Note that the identifier is a subdomain of
the ancestor domain that has been pre-authorized in Step 1. The the ancestor domain that has been pre-authorized in Step 1. The
client does not need to include the "subdomainAuthAllowed" field client does not need to include the subdomainAuthAllowed field in
in the identifier object, as it has already pre-authorized the the identifier object, as it has already pre-authorized the
ancestor domain. ancestor domain.
POST /acme/new-order HTTP/1.1 POST /acme/new-order HTTP/1.1
Host: example.com Host: example.com
Content-Type: application/jose+json Content-Type: application/jose+json
{ {
"protected": base64url({ "protected": base64url({
"alg": "ES256", "alg": "ES256",
"kid": "https://example.com/acme/acct/evOfKhNU60wg", "kid": "https://example.com/acme/acct/evOfKhNU60wg",
skipping to change at line 690 skipping to change at line 689
The client can proceed to finalize the order by posting a CSR to The client can proceed to finalize the order by posting a CSR to
the finalize resource. The client can then download the the finalize resource. The client can then download the
certificate for sub1.example.org. certificate for sub1.example.org.
* Step 3: The client places a newOrder for sub2.example.org. * Step 3: The client places a newOrder for sub2.example.org.
The client sends a newOrder request to the server and includes the The client sends a newOrder request to the server and includes the
subdomain identifier. Note that the identifier is a subdomain of subdomain identifier. Note that the identifier is a subdomain of
the ancestor domain that has been pre-authorized in Step 1. The the ancestor domain that has been pre-authorized in Step 1. The
client does not need to include the "subdomainAuthAllowed" field client does not need to include the subdomainAuthAllowed field in
in the identifier object, as it has already pre-authorized the the identifier object, as it has already pre-authorized the
ancestor domain. ancestor domain.
POST /acme/new-order HTTP/1.1 POST /acme/new-order HTTP/1.1
Host: example.com Host: example.com
Content-Type: application/jose+json Content-Type: application/jose+json
{ {
"protected": base64url({ "protected": base64url({
"alg": "ES256", "alg": "ES256",
"kid": "https://example.com/acme/acct/evOfKhNU60wg", "kid": "https://example.com/acme/acct/evOfKhNU60wg",
 End of changes. 22 change blocks. 
32 lines changed or deleted 31 lines changed or added

This html diff was produced by rfcdiff 1.48.