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

Add initial ACME API documentation #20752

Merged
merged 5 commits into from
May 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelog/20752.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:feature
**Vault PKI ACME Server**: Support for the ACME certificate lifecycle management protocol has been added to the Vault PKI Plugin. This allows standard ACME clients, such as the EFF's certbot and the CNCF's k8s cert-manager, to request certificates from a Vault server with no knowledge of Vault APIs or authentication mechanisms. For public-facing Vault instances, we recommend requiring External Account Bindings (EAB) to limit the ability to request certificates to only authenticated clients.
```
342 changes: 342 additions & 0 deletions website/content/api-docs/secret/pki.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ update your API calls accordingly.
## Table of Contents

- [Notice About New Multi-Issuer Functionality](#notice-about-new-multi-issuer-functionality)
- [ACME Certificate Issuance](#acme-certificate-issuance)
- [ACME Directories](#acme-directories)
- [Get ACME EAB Binding Token](#get-acme-eab-binding-token)
- [List Unused ACME EAB Binding Tokens](#list-unused-acme-eab-binding-tokens)
- [Delete Unused ACME EAB Binding Tokens](#delete-unused-acme-eab-binding-tokens)
- [Get ACME Configuration](#get-acme-configuration)
- [Set ACME Configuration](#set-acme-configuration)
- [Issuing Certificates](#issuing-certificates)
- [List Roles](#list-roles)
- [Read Role](#read-role)
Expand Down Expand Up @@ -106,6 +113,324 @@ to mix different types of CAs (roots and intermediates).
current issuing certificate on migration from an older Vault version
(Vault < 1.11.0).

## ACME Certificate Issuance

Starting with Vault 1.14, Vault supports the [ACME certificate lifecycle
management protocol](https://datatracker.ietf.org/doc/html/rfc8555) for issuing
and renewing leaf server certificates.

In order to use ACME, a [cluster path](#set-cluster-configuration) must be
set and ACME must be [enabled in its configuration](#set-acme-configuration)
with the [required headers](#acme-required-headers) enabled on the mount
tuning.

Using ACME with a role requires `no_store=false` to be set on the role; this
allows the certificate to be stored and later fetched through the ACME
protocol.

### ACME Directories

Vault PKI supports the following ACME directories, providing different
restrictions around usage (defaults, a specific issuer and/or a specific
role). To interact with these directories, specify the directory URL in
an ACME client. For example, with the EFF's [CertBot](https://certbot.eff.org/):

```
$ certbot certonly --server https://localhost:8200/v1/pki/acme/directory ...
```

These endpoints are unauthenticated from a Vault authentication model, but
internally authenticated via the ACME protocol.

| Method | Path | Issuer | Role |
| :----- | :--------------------------------------------------- | :-------------------- | :----------------------------------- |
| `ACME` | `/pki/acme/directory` | `default` | Sign-Verbatim or Specified in Config |
| `ACME` | `/pki/issuer/:issuer_ref/acme/directory` | `:issuer_ref` | Sign-Verbatim or Specified in Config |
| `ACME` | `/pki/roles/:role/acme/directory` | Specified by the role | `:role` |
| `ACME` | `/pki/issuer/:issuer_ref/roles/:role/acme/directory` | `:issuer_ref` | `:role` |

When a role is not specified (for the first two directory URLs), and no
`default_role` is specified in the [ACME configuration](#set-acme-configuration),
then _any_ identifier for which the client can prove ownership of will be
issued for. This is similar to using the [Sign Verbatim](#sign-verbatim)
endpoint, but with additional verification that the client has proven
ownership (within the ACME protocol) of the requested certificate
identifiers.

cipherboy marked this conversation as resolved.
Show resolved Hide resolved
#### ACME Challenge Types

Vault supports the following ACME challenge types presently:

- `http-01`, supporting both `dns` and `ip` identifiers,
- `dns-01`, supporting `dns` identifiers including wildcards.

A custom DNS resolver used by the server for looking up DNS names for use
with both mechanisms can be added via the [ACME configuration](#set-acme-configuration).

#### ACME External Account Bindings

ACME External Account Binding (EAB) Policy can enforce that clients need to
have a valid external account binding to Vault. Before registering a new account,
an authenticated Vault client will need to [fetch a new EAB
token](#get-acme-eab-binding-token). This returns two values: a key identifier
and an HMAC key used by the ACME client to authenticate with EAB. For example:

```
$ vault write -f /pki/acme/new-eab
$ certbot certonly --server https://localhost:8200/v1/pki/acme/directory \
--eab-kid <id> --eab-hmac-key <hmac-key>
```

With or without EAB, requests from the ACME client are not authenticated using
traditional Vault authentication, but are instead authenticated through the
ACME protocol. With EAB however, a Vault authenticated client will have to
fetch an EAB token and pass it to the ACME client for use on the initial
registration: this binds the ACME client's registration to an authenticated
Vault endpoint, but not further to the client's entity or other information.

~> Note: Enabling EAB is strongly recommended for public-facing Vault
deployments. Use of the `VAULT_DISABLE_PUBLIC_ACME` environment variable
can be used to enforce all ACME instances have EAB enabled.

#### ACME Accounts

ACME Accounts are created specific to a particular directory and are not
portable across Performance Secondary clusters.

#### ACME Required Headers

ACME requires the following response headers (`allowed_response_headers`)
to be specified by [mount tuning](/vault/api-docs/system/mounts#tune-mount-configuration):

- `Replay-Nonce`
- `Link`
- `Location`

On an existing mount, these can be specified by running the following command:

```
$ vault secrets tune -allowed-response-headers=Location -allowed-response-headers=Replay-Nonce \
-allowed-response-headers=Link \
pki/
```

### Get ACME EAB Binding Token

This endpoint returns a new ACME binding token. The `id` response field can
be used as the key identifier and the `key` response field be used as the
EAB HMAC key in the ACME Client.

Each call to this endpoint will generate and return a new EAB binding token.

| Method | Path |
| :----- | :------------------ |
| `POST` | `/pki/acme/new-eab` |

#### Parameters

No parameters.

#### Sample Request

```
$ curl \
--header "X-Vault-Token: ..." \
--request POST \
http://127.0.0.1:8200/v1/pki/acme/new-eab
```

#### Sample Response

```
{
"data": {
"created_on": "2023-05-24T14:33:00-04:00",
"id": "bc8088d9-3816-5177-ae8e-d8393265f7dd",
"key_bits": "256",
"key_type": "hs",
"key": "MHcCAQE... additional data elided ...",
}
}
```

### List Unused ACME EAB Binding Tokens

This endpoint returns a list of all unused ACME binding tokens; once used,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is authed, right? (maybe say, "this authenticated endpoint")

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We usually only list unauthenticated endpoints; its assumed endpoints are authed by default. I've added a missing note to the Directories that it is unauthed from a Vault auth perspective though. :-) thanks!

they will be removed from this list.

| Method | Path |
| :----- | :--------- |
| `LIST` | `/pki/eab` |

#### Sample Request

```
$ curl \
--header "X-Vault-Token: ..." \
--request LIST \
http://127.0.0.1:8200/v1/pki/eab
```

#### Sample Response

```
{
"data": {
"key_info": {
"bc8088d9-3816-5177-ae8e-d8393265f7dd": {
"created_on": "2023-05-24T14:33:00-04:00",
"key_bits": "256",
"key_type": "hs"
}
},
"keys": [
"bc8088d9-3816-5177-ae8e-d8393265f7dd"
]
}
}
```

### Delete Unused ACME EAB Binding Tokens

This endpoint allows the deletion of an unused ACME binding token.

| Method | Path |
| :------- | :----------------- |
| `DELETE` | `/pki/eab/:key_id` |

#### Parameters

- `key_id` `(string: <required>)` - The id of the EAB binding token to
delete. This is part of the request URL.

#### Sample Request

```
$ curl \
--header "X-Vault-Token: ..." \
--request DELETE \
http://127.0.0.1:8200/v1/pki/eab/bc8088d9-3816-5177-ae8e-d8393265f7dd
```

### Get ACME Configuration

This endpoint allows reading of the current ACME server configuration used by
this mount.

| Method | Path |
| :----- | :----------------- |
| `GET` | `/pki/config/acme` |

#### Sample Request

```
$ curl \
--header "X-Vault-Token: ..." \
http://127.0.0.1:8200/v1/pki/config/acme
```

#### Sample Response

```
{
"data": {
"allowed_issuers": [
"*"
],
"allowed_roles": [
"*"
],
"default_role": "",
"dns_resolver": "",
"eab_policy": "not-required",
"enabled": true
},
}
```

### Set ACME Configuration

This endpoint allows setting the ACME server configuration used by this
mount.

| Method | Path |
| :----- | :----------------- |
| `POST` | `/pki/config/acme` |

#### Parameters

- `allowed_issuers` `(list: ["*"])` - Specifies a list issuers allowed to
issue certificates via explicit ACME paths. If an allowed role specifies
an issuer outside this list, it will be allowed. The default value `*`
allows every issuer within the mount.

- `allowed_roles` `(list: ["*"])` - Specifies a list of roles to allow to
issue certificates via explicit ACME paths. If no `default_role` is
specified, sign-verbatim-like issuance on the default ACME directory
will still occur.

- `default_role` `(string: "")` - Optionally specifies a role to enforce
on the default ACME directory. Must be present in `allowed_roles` if
set.

- `dns_resolver` `(string: "")` - An optional overriding DNS resolver to
use for challenge verification lookups. When not specified, the default
system resolver will be used. This allows domains on peered networks with
an accessible DNS resolver to be validated.

- `eab_policy` `(string: "not-required")` - Specified policy to enforce
around [External Account Bindings (EABs)](#acme-external-account-bindings).
The allowed values are:

- `not-required`, where EABs are not enforced but are validated if
specified.

- `new-account-required`, where new accounts are required to have EAB
but existing accounts can still be used.

- `always-required`, where all accounts regardless of age are required
to have EABs set.

- `enabled` `(bool: false)` - Whether ACME is enabled on this mount. When
ACME is disabled, all requests to ACME directory URLs will return 404.

#### Sample Payload

```
{
"enabled": true
}
```

#### Sample Request

```
$ curl \
--header "X-Vault-Token: ..." \
--request POST \
--data @payload.json \
http://127.0.0.1:8200/v1/pki/config/acme
```

#### Sample Response

```
{
"data": {
"allowed_issuers": [
"*"
],
"allowed_roles": [
"*"
],
"default_role": "",
"dns_resolver": "",
"eab_policy": "not-required",
"enabled": true
}
}
```

## Issuing Certificates

The following API endpoints allow users or operators to request certificates
Expand Down Expand Up @@ -3867,6 +4192,23 @@ expiration time.
still be there, but not too long as to fill up storage with too many invalid
requests. Defaults to `48h`.

- `tidy_acme` `(bool: false)` - Set to true to tidy stale ACME accounts,
orders, authorizations, EABs, and challenges. ACME orders are tidied (deleted)
`safety_buffer` after the certificate associated with them expires, or after
the order and relevant authorizations have expired if no certificate was
produced. Authorizations are tidied with the corresponding order.

When a valid ACME Account is at least `acme_account_safety_buffer`
old, and has no remaining orders associated with it, the account is
marked as revoked. After another `acme_account_safety_buffer` has
passed from the revocation or deactivation date, a revoked or
deactivated ACME account is deleted.

- `acme_account_safety_buffer` `(string: "720h")` - The amount of time that
must pass after creation that an account with no orders is marked revoked,
and the amount of time after being marked revoked or deactivated. The
default is 30 days as hours.

#### Sample Payload

```json
Expand Down