2019-05-10 01:45:57 +00:00
|
|
|
# Provisioners
|
|
|
|
|
2020-11-16 17:30:41 +00:00
|
|
|
> Note: The canonical documentation for `step-ca` provisioners now lives at
|
2021-07-20 15:32:18 +00:00
|
|
|
> https://smallstep.com/docs/step-ca/provisioners. Documentation
|
2020-11-16 17:30:41 +00:00
|
|
|
> found on this page may be out of date.
|
|
|
|
|
2019-05-10 01:45:57 +00:00
|
|
|
Provisioners are people or code that are registered with the CA and authorized
|
|
|
|
to issue "provisioning tokens". Provisioning tokens are single-use tokens that
|
|
|
|
can be used to authenticate with the CA and get a certificate.
|
|
|
|
|
2020-06-26 00:27:17 +00:00
|
|
|
See `step ca provisioner add --help` for documentation and examples on adding
|
|
|
|
provisioners.
|
|
|
|
|
|
|
|
> Attn: We strongly recommend using the `step ca provisioner add ...`
|
|
|
|
> utility to generate provisioners in your `ca.json` configuration. We often
|
|
|
|
> encode fields differently in the JSON than you might expect. And you can
|
|
|
|
> always come in and modify the configuration manually after using the utility.
|
|
|
|
|
2020-06-24 21:12:21 +00:00
|
|
|
## Claims
|
|
|
|
|
2020-05-01 21:47:29 +00:00
|
|
|
Each provisioner can define an optional `claims` attribute. The settings in this
|
|
|
|
attribute override any settings in the global `claims` attribute in the authority
|
|
|
|
configuration.
|
|
|
|
|
|
|
|
Example `claims`:
|
|
|
|
|
|
|
|
```
|
|
|
|
...
|
|
|
|
"claims": {
|
|
|
|
"minTLSCertDuration": "5m",
|
|
|
|
"maxTLSCertDuration": "24h",
|
|
|
|
"defaultTLSCertDuration": "24h",
|
2020-06-24 21:12:21 +00:00
|
|
|
"disableRenewal": false,
|
2020-05-01 21:47:29 +00:00
|
|
|
"minHostSSHCertDuration": "5m",
|
|
|
|
"maxHostSSHCertDuration": "1680h",
|
2020-11-16 17:30:41 +00:00
|
|
|
"defaultHostSSHCertDuration": "720h",
|
2020-05-01 21:47:29 +00:00
|
|
|
"minUserSSHCertDuration": "5m",
|
|
|
|
"maxUserSSHCertDuration": "24h",
|
2020-11-16 17:30:41 +00:00
|
|
|
"defaultUserSSHCertDuration": "16h",
|
2020-06-24 21:12:21 +00:00
|
|
|
"enableSSHCA": true
|
|
|
|
},
|
2020-05-01 21:47:29 +00:00
|
|
|
...
|
|
|
|
```
|
|
|
|
|
|
|
|
* `claims` (optional): overwrites the default claims set in the authority.
|
|
|
|
You can set one or more of the following claims:
|
|
|
|
|
|
|
|
* `minTLSCertDuration`: do not allow certificates with a duration less than
|
|
|
|
this value.
|
|
|
|
|
|
|
|
* `maxTLSCertDuration`: do not allow certificates with a duration greater than
|
|
|
|
this value.
|
|
|
|
|
|
|
|
* `defaultTLSCertDuration`: if no certificate validity period is specified,
|
|
|
|
use this value.
|
|
|
|
|
|
|
|
* `disableIssuedAtCheck`: disable a check verifying that provisioning tokens
|
|
|
|
must be issued after the CA has booted. This claim is one prevention against
|
|
|
|
token reuse. The default value is `false`. Do not change this unless you
|
|
|
|
know what you are doing.
|
|
|
|
|
|
|
|
SSH CA properties
|
|
|
|
|
2020-06-16 17:58:58 +00:00
|
|
|
* `minUserSSHCertDuration`: do not allow certificates with a duration less
|
2020-05-01 21:47:29 +00:00
|
|
|
than this value.
|
|
|
|
|
2020-06-16 17:58:58 +00:00
|
|
|
* `maxUserSSHCertDuration`: do not allow certificates with a duration
|
2020-05-01 21:47:29 +00:00
|
|
|
greater than this value.
|
|
|
|
|
2020-06-16 17:58:58 +00:00
|
|
|
* `defaultUserSSHCertDuration`: if no certificate validity period is specified,
|
2020-05-01 21:47:29 +00:00
|
|
|
use this value.
|
|
|
|
|
2020-06-16 17:58:58 +00:00
|
|
|
* `minHostSSHCertDuration`: do not allow certificates with a duration less
|
2020-05-01 21:47:29 +00:00
|
|
|
than this value.
|
|
|
|
|
2020-06-16 17:58:58 +00:00
|
|
|
* `maxHostSSHCertDuration`: do not allow certificates with a duration
|
2020-05-01 21:47:29 +00:00
|
|
|
greater than this value.
|
|
|
|
|
2020-06-16 17:58:58 +00:00
|
|
|
* `defaultHostSSHCertDuration`: if no certificate validity period is specified,
|
2020-05-01 21:47:29 +00:00
|
|
|
use this value.
|
|
|
|
|
|
|
|
* `enableSSHCA`: enable all provisioners to generate SSH Certificates.
|
2021-04-05 22:19:27 +00:00
|
|
|
The default value is `false`. You can enable this option per provisioner
|
2020-05-01 21:47:29 +00:00
|
|
|
by setting it to `true` in the provisioner claims.
|
|
|
|
|
2020-06-24 21:12:21 +00:00
|
|
|
## Provisioner Types
|
|
|
|
|
|
|
|
Each provisioner has a different method of authentication with the CA.
|
|
|
|
|
|
|
|
- A JWK provisioner uses a JWT signed by a JWK.
|
|
|
|
- An OIDC provisioner uses a OIDC token signed by an Identity Provider e.g. Google, Okta, Azure.
|
|
|
|
- An AWS provisioner uses an Instance Identity Document signed by AWS.
|
|
|
|
- etc.
|
|
|
|
|
|
|
|
### Capabilities by Type
|
|
|
|
|
|
|
|
Provisioners are used to authenticate certificate signing requests, and every
|
|
|
|
provisioner has a slightly different scope of authorization. Below is a table
|
|
|
|
detailing the authorization capabilities of each provisioner.
|
|
|
|
|
2020-06-26 00:27:17 +00:00
|
|
|
Provisioner Capabilities| x509-sign | x509-renew | x509-revoke | ssh-user-cert-sign | ssh-host-cert-sign | ssh-user-cert-renew | ssh-host-cert-renew | ssh-revoke | ssh-rekey
|
|
|
|
----------- | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-:
|
|
|
|
JWK | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | 𝗫 | 𝗫 | ✔️ | 𝗫
|
|
|
|
OIDC | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ <sup id="a1">[1](#f1)</sup> | 𝗫 | 𝗫 | ✔️ | 𝗫
|
|
|
|
X5C | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | 𝗫 | 𝗫 | 𝗫 | 𝗫
|
|
|
|
K8sSA | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | 𝗫 | 𝗫 | 𝗫 | 𝗫
|
|
|
|
ACME | ✔️ | ✔️ | 𝗫 | 𝗫 | 𝗫 | 𝗫 | 𝗫 | 𝗫 | 𝗫
|
|
|
|
SSHPOP | 𝗫 | 𝗫 | 𝗫 | 𝗫 | 𝗫 | 𝗫 | ✔️ | ✔️ | ✔️
|
|
|
|
AWS | ✔️ | ✔️ | 𝗫 | 𝗫 | ✔️ | 𝗫 | 𝗫 | 𝗫 | 𝗫
|
|
|
|
Azure | ✔️ | ✔️ | 𝗫 | 𝗫 | ✔️ | 𝗫 | 𝗫 | 𝗫 | 𝗫
|
|
|
|
GCP | ✔️ | ✔️ | 𝗫 | 𝗫 | ✔️ | 𝗫 | 𝗫 | 𝗫 | 𝗫
|
|
|
|
|
|
|
|
<b id="f1">1</b> Admin OIDC users can generate Host SSH Certificates. Admins can be configured in the OIDC provisioner. [↩](#a1)
|
2020-06-24 21:12:21 +00:00
|
|
|
|
|
|
|
### JWK
|
2019-05-10 01:45:57 +00:00
|
|
|
|
2019-06-11 15:28:43 +00:00
|
|
|
JWK is the default provisioner type. It uses public-key cryptography to sign and
|
2019-05-10 01:45:57 +00:00
|
|
|
validate a JSON Web Token (JWT).
|
|
|
|
|
|
|
|
The [step](https://github.com/smallstep/cli) CLI tool will create a JWK
|
|
|
|
provisioner when `step ca init` is used, and it also contains commands to add
|
|
|
|
(`step ca provisioner add`) and remove (`step ca provisioner remove`) JWK
|
|
|
|
provisioners.
|
|
|
|
|
|
|
|
In the ca.json configuration file, a complete JWK provisioner example looks like:
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
|
|
|
"type": "JWK",
|
|
|
|
"name": "you@smallstep.com",
|
|
|
|
"key": {
|
|
|
|
"use": "sig",
|
|
|
|
"kty": "EC",
|
|
|
|
"kid": "NPM_9Gz_omTqchS6Xx9Yfvs-EuxkYo6VAk4sL7gyyM4",
|
|
|
|
"crv": "P-256",
|
|
|
|
"alg": "ES256",
|
|
|
|
"x": "bBI5AkO9lwvDuWGfOr0F6ttXC-ZRzJo8kKn5wTzRJXI",
|
|
|
|
"y": "rcfaqE-EEZgs34Q9SSH3f9Ua5a8dKopXNfEzDD8KRlU"
|
|
|
|
},
|
|
|
|
"encryptedKey": "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJjdHkiOiJqd2sranNvbiIsImVuYyI6IkEyNTZHQ00iLCJwMmMiOjEwMDAwMCwicDJzIjoiTlV6MjlEb3hKMVdOaFI3dUNjaGdYZyJ9.YN7xhz6RAbz_9bcuXoymBOj8bOg23ETAdmSCRyHpxGekkV0q3STYYg.vo1oBnZsZjgRu5Ln.Xop8AvZ74h_im2jxeaq-hYYWnaK_eF7MGr4xcZGodMUxp-hGPqS85oWkyprkQLYt1-jXTURfpejtmPeB4-sxgj7OFxMYYus84BdkG9BZgSBmMN9SqZItOv4pqg_NwQA0bv9g9A_e-N6QUFanxuYQsEPX_-IwWBDbNKyN9bXbpEQa0FKNVsTvFahGzOxQngXipi265VADkh8MJLjYerplKIbNeOJJbLd9CbS9fceLvQUNr3ACGgAejSaWmeNUVqbho1lY4882iS8QVx1VzjluTXlAMdSUUDHArHEihz008kCyF0YfvNdGebyEDLvTmF6KkhqMpsWn3zASYBidc9k._ch9BtvRRhcLD838itIQlw",
|
|
|
|
"claims": {
|
|
|
|
"minTLSCertDuration": "5m",
|
|
|
|
"maxTLSCertDuration": "24h",
|
|
|
|
"defaultTLSCertDuration": "24h",
|
2020-06-26 00:27:17 +00:00
|
|
|
"disableRenewal": false,
|
2020-05-01 21:47:29 +00:00
|
|
|
"minHostSSHCertDuration": "5m",
|
|
|
|
"maxHostSSHCertDuration": "1680h",
|
|
|
|
"minUserSSHCertDuration": "5m",
|
|
|
|
"maxUserSSHCertDuration": "24h",
|
2020-06-26 00:27:17 +00:00
|
|
|
"enableSSHCA": true
|
2019-05-10 01:45:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
* `type` (mandatory): for a JWK provisioner it must be `JWK`, this field is case
|
|
|
|
insensitive.
|
|
|
|
|
|
|
|
* `name` (mandatory): identifies the provisioner, a good practice is to
|
|
|
|
use an email address or a descriptive string that allows the identification of
|
|
|
|
the owner, but it can be any non-empty string.
|
|
|
|
|
|
|
|
* `key` (mandatory): is the JWK (JSON Web Key) representation of a public key
|
|
|
|
used to validate a signed token.
|
|
|
|
|
|
|
|
* `encryptedKey` (recommended): is the encrypted private key used to sign a
|
|
|
|
token. It's a JWE compact string containing the JWK representation of the
|
|
|
|
private key.
|
|
|
|
|
|
|
|
We can use [step](https://github.com/smallstep/cli) to see the private key
|
|
|
|
encrypted with the password `asdf`:
|
2019-06-11 15:28:43 +00:00
|
|
|
|
2019-05-10 01:45:57 +00:00
|
|
|
```sh
|
|
|
|
$ echo ey...lw | step crypto jwe decrypt | jq
|
|
|
|
Please enter the password to decrypt the content encryption key:
|
|
|
|
{
|
|
|
|
"use": "sig",
|
|
|
|
"kty": "EC",
|
|
|
|
"kid": "NPM_9Gz_omTqchS6Xx9Yfvs-EuxkYo6VAk4sL7gyyM4",
|
|
|
|
"crv": "P-256",
|
|
|
|
"alg": "ES256",
|
|
|
|
"x": "bBI5AkO9lwvDuWGfOr0F6ttXC-ZRzJo8kKn5wTzRJXI",
|
|
|
|
"y": "rcfaqE-EEZgs34Q9SSH3f9Ua5a8dKopXNfEzDD8KRlU",
|
|
|
|
"d": "rsjCCM_2FQ-uk7nywBEQHl84oaPo4mTpYDgXAu63igE"
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
If the ca.json does not contain the encryptedKey, the private key must be
|
|
|
|
provided using the `--key` flag of the `step ca token` to be able to sign the
|
|
|
|
token.
|
|
|
|
|
2020-06-24 21:12:21 +00:00
|
|
|
### OIDC
|
2019-05-10 01:45:57 +00:00
|
|
|
|
|
|
|
An OIDC provisioner allows a user to get a certificate after authenticating
|
2021-04-19 19:08:42 +00:00
|
|
|
with an OAuth OpenID Connect identity provider. The ID token provided
|
2019-05-10 01:45:57 +00:00
|
|
|
will be used on the CA authentication, and by default, the certificate will only
|
|
|
|
have the user's email as a Subject Alternative Name (SAN) Extension.
|
|
|
|
|
|
|
|
One of the most common providers and the one we'll use in the following example
|
|
|
|
is G-Suite.
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
|
|
|
"type": "OIDC",
|
|
|
|
"name": "Google",
|
|
|
|
"clientID": "1087160488420-8qt7bavg3qesdhs6it824mhnfgcfe8il.apps.googleusercontent.com",
|
|
|
|
"clientSecret": "udTrOT3gzrO7W9fDPgZQLfYJ",
|
|
|
|
"configurationEndpoint": "https://accounts.google.com/.well-known/openid-configuration",
|
|
|
|
"admins": ["you@smallstep.com"],
|
|
|
|
"domains": ["smallstep.com"],
|
2019-09-19 17:20:41 +00:00
|
|
|
"listenAddress": ":10000",
|
2019-05-10 01:45:57 +00:00
|
|
|
"claims": {
|
|
|
|
"maxTLSCertDuration": "8h",
|
|
|
|
"defaultTLSCertDuration": "2h",
|
|
|
|
"disableRenewal": true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
* `type` (mandatory): indicates the provisioner type and must be `OIDC`.
|
|
|
|
|
|
|
|
* `name` (mandatory): a string used to identify the provider when the CLI is
|
|
|
|
used.
|
|
|
|
|
|
|
|
* `clientID` (mandatory): the client id provided by the identity provider used
|
|
|
|
to initialize the authentication flow.
|
|
|
|
|
|
|
|
* `clientSecret` (mandatory): the client secret provided by the identity
|
|
|
|
provider used to get the id token. Some identity providers might use an empty
|
|
|
|
string as a secret.
|
|
|
|
|
2019-10-01 09:20:03 +00:00
|
|
|
* `configurationEndpoint` (mandatory): is the HTTP address used by the CA to get
|
2019-05-10 01:45:57 +00:00
|
|
|
the OpenID Connect configuration and public keys used to validate the tokens.
|
|
|
|
|
|
|
|
* `admins` (optional): is the list of emails that will be able to get
|
|
|
|
certificates with custom SANs. If a user is not an admin, it will only be able
|
|
|
|
to get a certificate with its email in it.
|
|
|
|
|
|
|
|
* `domains` (optional): is the list of domains valid. If provided only the
|
|
|
|
emails with the provided domains will be able to authenticate.
|
|
|
|
|
2019-09-19 17:20:41 +00:00
|
|
|
* `listenAddress` (optional): is the loopback address (`:port` or `host:port`)
|
|
|
|
where the authorization server will redirect to complete the authorization
|
|
|
|
flow. If it's not defined `step` will use `127.0.0.1` with a random port. This
|
|
|
|
configuration is only required if the authorization server doesn't allow any
|
|
|
|
port to be specified at the time of the request for loopback IP redirect URIs.
|
|
|
|
|
2019-05-10 01:45:57 +00:00
|
|
|
* `claims` (optional): overwrites the default claims set in the authority, see
|
2020-05-01 21:47:29 +00:00
|
|
|
the [top](#provisioners) section for all the options.
|
2019-05-10 01:45:57 +00:00
|
|
|
|
2020-06-26 00:27:17 +00:00
|
|
|
### X5C
|
|
|
|
|
|
|
|
An X5C provisioner allows a client to get an x509 or SSH certificate using
|
|
|
|
an existing x509 certificate that is trusted by the X5C provisioner.
|
|
|
|
|
|
|
|
An X5C provisioner is configured with a root certificate, supplied by the user,
|
|
|
|
at the time the provisioner is created. The X5C provisioner can authenticate
|
|
|
|
X5C tokens.
|
|
|
|
|
|
|
|
An X5C token is a JWT, signed by the certificate private key, with an `x5c`
|
|
|
|
header that contains the chain.
|
|
|
|
|
|
|
|
If you would like any certificate signed by `step-ca` to become a provisioner,
|
|
|
|
you can configure the X5C provisioner using the root certificate used by
|
|
|
|
`step-ca`, like so:
|
|
|
|
|
|
|
|
```
|
|
|
|
step ca provisioner add x5c-smallstep --type X5C --x5c-root $(step path)/certs/root_ca.crt
|
|
|
|
```
|
|
|
|
|
|
|
|
Or you can configure the X5C provisioner with an outside root, giving provisioner
|
|
|
|
capabilities to a completely separate PKI.
|
|
|
|
|
|
|
|
Below is an example of an X5C provisioner in the `ca.json`:
|
|
|
|
|
|
|
|
```json
|
|
|
|
...
|
|
|
|
{
|
|
|
|
"type": "X5C",
|
|
|
|
"name": "x5c",
|
|
|
|
"roots": "LS0tLS1 ... Q0FURS0tLS0tCg==",
|
|
|
|
"claims": {
|
|
|
|
"maxTLSCertDuration": "8h",
|
|
|
|
"defaultTLSCertDuration": "2h",
|
|
|
|
"disableRenewal": true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2020-06-29 19:32:42 +00:00
|
|
|
* `type` (mandatory): indicates the provisioner type and must be `X5C`.
|
2020-06-26 00:27:17 +00:00
|
|
|
|
|
|
|
* `name` (mandatory): a string used to identify the provider when the CLI is
|
|
|
|
used.
|
|
|
|
|
|
|
|
* `roots` (mandatory): a base64 encoded list of root certificates used for
|
|
|
|
validating X5C tokens.
|
|
|
|
|
|
|
|
* `claims` (optional): overwrites the default claims set in the authority, see
|
|
|
|
the [top](#provisioners) section for all the options.
|
|
|
|
|
|
|
|
### SSHPOP
|
|
|
|
|
|
|
|
An SSHPOP provisioner allows a client to renew, revoke, or rekey an SSH
|
|
|
|
certificate using that certificate for authentication with the CA.
|
|
|
|
The renew and rekey methods can only be used on SSH host certificates.
|
|
|
|
|
|
|
|
An SSHPOP provisioner is configured with the user and host root ssh certificates
|
|
|
|
from the `ca.json`. The SSHPOP provisioner can only authenticate SSHPOP tokens
|
|
|
|
generated using SSH certificates created by `step-ca`.
|
|
|
|
|
|
|
|
An SSHPOP token is a JWT, signed by the certificate private key, with an `sshpop`
|
|
|
|
header that contains the SSH certificate.
|
|
|
|
|
|
|
|
Below is an example of an SSHPOP provisioner in the `ca.json`:
|
|
|
|
|
|
|
|
```json
|
|
|
|
...
|
|
|
|
{
|
|
|
|
"type": "SSHPOP",
|
|
|
|
"name": "sshpop-smallstep",
|
|
|
|
"claims": {
|
|
|
|
"enableSSHCA": true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2020-06-29 19:32:42 +00:00
|
|
|
* `type` (mandatory): indicates the provisioner type and must be `SSHPOP`.
|
2020-06-26 00:27:17 +00:00
|
|
|
|
|
|
|
* `name` (mandatory): a string used to identify the provider when the CLI is
|
|
|
|
used.
|
|
|
|
|
|
|
|
* `claims` (optional): overwrites the default claims set in the authority, see
|
|
|
|
the [top](#provisioners) section for all the options.
|
|
|
|
|
|
|
|
### ACME
|
|
|
|
|
|
|
|
An ACME provisioner allows a client to request a certificate from the server
|
2020-10-25 09:52:23 +00:00
|
|
|
using the [ACME Protocol](https://tools.ietf.org/html/rfc8555). The ACME
|
2020-06-26 00:27:17 +00:00
|
|
|
provisioner can only request X509 certificates. All authentication of the CSR
|
|
|
|
is managed by the ACME protocol.
|
|
|
|
|
|
|
|
Below is an example of an ACME provisioner in the `ca.json`:
|
|
|
|
|
|
|
|
```json
|
|
|
|
...
|
|
|
|
{
|
|
|
|
"type": "ACME",
|
|
|
|
"name": "my-acme-provisioner",
|
2020-06-26 17:42:13 +00:00
|
|
|
"forceCN": true,
|
2021-08-06 23:33:08 +00:00
|
|
|
"requireEAB": false,
|
2020-06-26 00:27:17 +00:00
|
|
|
"claims": {
|
|
|
|
"maxTLSCertDuration": "8h",
|
|
|
|
"defaultTLSCertDuration": "2h",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2020-06-29 19:32:42 +00:00
|
|
|
* `type` (mandatory): indicates the provisioner type and must be `ACME`.
|
2020-06-26 00:27:17 +00:00
|
|
|
|
|
|
|
* `name` (mandatory): a string used to identify the provider when the CLI is
|
|
|
|
used.
|
|
|
|
|
2020-06-26 17:42:13 +00:00
|
|
|
* `forceCN` (optional): force one of the SANs to become the Common Name, if a
|
|
|
|
common name is not provided.
|
|
|
|
|
2021-08-06 23:33:08 +00:00
|
|
|
* `requireEAB` (optional): require clients to provide External Account Binding
|
|
|
|
credentials when creating an ACME Account.
|
|
|
|
|
2020-06-26 00:27:17 +00:00
|
|
|
* `claims` (optional): overwrites the default claims set in the authority, see
|
|
|
|
the [top](#provisioners) section for all the options.
|
|
|
|
|
|
|
|
See our [`step-ca` ACME tutorial](https://app.smallstep.com/docs/[product]/tutorials/acme-provisioners)
|
|
|
|
for more guidance on configuring and using the ACME protocol with `step-ca`.
|
|
|
|
|
|
|
|
### K8sSA - Kubernetes Service Account
|
|
|
|
|
|
|
|
A K8sSA provisioner allows a client to request a certificate from the server
|
|
|
|
using a Kubernetes Service Account Token.
|
|
|
|
|
|
|
|
As of the time when this provisioner was coded, the Kubernetes Service Account
|
|
|
|
API for retrieving the token from a running instance was still in beta. Therefore,
|
|
|
|
our K8sSA provisioner must be configured with the public key that will be used
|
|
|
|
to validate K8sSA tokens.
|
|
|
|
|
|
|
|
K8sSA tokens are very minimal. There is no place for SANs, or other details that
|
|
|
|
a user may want validated in a CSR. It is essentially a bearer token. Therefore,
|
|
|
|
at this time a K8sSA token can be used to sign a CSR with any SANs. Said
|
|
|
|
differently, the **K8sSA provisioner does little to no validation on the CSR
|
|
|
|
before signing it**. You should only configure and use this provisioner if you
|
|
|
|
know what you are doing. If a malicious user obtains the private key they will
|
|
|
|
be able to create certificates with any SANs and Subject.
|
|
|
|
|
|
|
|
Below is an example of a K8sSA provisioner in the `ca.json`:
|
|
|
|
|
|
|
|
```json
|
|
|
|
...
|
|
|
|
{
|
|
|
|
"type": "K8sSA",
|
|
|
|
"name": "my-kube-provisioner",
|
|
|
|
"publicKeys": "LS0tLS1...LS0tCg==",
|
|
|
|
"claims": {
|
|
|
|
"maxTLSCertDuration": "8h",
|
|
|
|
"defaultTLSCertDuration": "2h",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2020-06-29 19:32:42 +00:00
|
|
|
* `type` (mandatory): indicates the provisioner type and must be `K8sSA`.
|
2020-06-26 00:27:17 +00:00
|
|
|
|
|
|
|
* `name` (mandatory): a string used to identify the provider when the CLI is
|
|
|
|
used.
|
|
|
|
|
|
|
|
* `publicKeys` (mandatory): a base64 encoded list of public keys used to validate
|
|
|
|
K8sSA tokens.
|
|
|
|
|
|
|
|
* `claims` (optional): overwrites the default claims set in the authority, see
|
|
|
|
the [top](#provisioners) section for all the options.
|
|
|
|
|
2020-06-24 21:12:21 +00:00
|
|
|
### Provisioners for Cloud Identities
|
2019-05-10 01:45:57 +00:00
|
|
|
|
|
|
|
[Step certificates](https://github.com/smallstep/certificates) can grant
|
|
|
|
certificates to code running in a machine without any other authentication than
|
|
|
|
the one provided by the cloud. Usually, this is implemented with some kind of
|
|
|
|
signed document, but the information contained on them might not be enough to
|
|
|
|
generate a certificate. Due to this limitation, the cloud identities use by
|
|
|
|
default a trust model called Trust On First Use (TOFU).
|
|
|
|
|
|
|
|
The Trust On First Use model allows the use of more permissive CSRs that can
|
|
|
|
have custom SANs that cannot be validated. But it comes with the limitation that
|
|
|
|
you can only grant a certificate once. After this first grant, the same machine
|
|
|
|
will need to renew the certificate using mTLS, and the CA will block any other
|
|
|
|
attempt to grant a certificate to that instance.
|
|
|
|
|
2020-06-24 21:12:21 +00:00
|
|
|
#### AWS
|
2019-05-10 01:45:57 +00:00
|
|
|
|
|
|
|
The AWS provisioner allows granting a certificate to an Amazon EC2 instance
|
|
|
|
using the [Instance Identity Documents](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-identity-documents.html)
|
|
|
|
|
|
|
|
The [step](https://github.com/smallstep/cli) CLI will generate a custom JWT
|
|
|
|
token containing the instance identity document and its signature and the CA
|
|
|
|
will grant a certificate after validating it.
|
|
|
|
|
|
|
|
In the ca.json, an AWS provisioner looks like:
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
|
|
|
"type": "AWS",
|
|
|
|
"name": "Amazon Web Services",
|
|
|
|
"accounts": ["1234567890"],
|
|
|
|
"disableCustomSANs": false,
|
|
|
|
"disableTrustOnFirstUse": false,
|
2019-06-05 17:50:08 +00:00
|
|
|
"instanceAge": "1h",
|
2020-10-14 00:51:24 +00:00
|
|
|
"iidRoots": "/path/to/aws.crt",
|
2019-05-10 01:45:57 +00:00
|
|
|
"claims": {
|
|
|
|
"maxTLSCertDuration": "2160h",
|
|
|
|
"defaultTLSCertDuration": "2160h"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
* `type` (mandatory): indicates the provisioner type and must be `AWS`.
|
|
|
|
|
|
|
|
* `name` (mandatory): a string used to identify the provider when the CLI is
|
|
|
|
used.
|
|
|
|
|
|
|
|
* `accounts` (optional): the list of AWS account numbers that are allowed to use
|
|
|
|
this provisioner. If none is specified, all AWS accounts will be valid.
|
|
|
|
|
|
|
|
* `disableCustomSANs` (optional): by default custom SANs are valid, but if this
|
|
|
|
option is set to true only the SANs available in the instance identity
|
|
|
|
document will be valid, these are the private IP and the DNS
|
|
|
|
`ip-<private-ip>.<region>.compute.internal`.
|
|
|
|
|
|
|
|
* `disableTrustOnFirstUse` (optional): by default only one certificate will be
|
|
|
|
granted per instance, but if the option is set to true this limit is not set
|
|
|
|
and different tokens can be used to get different certificates.
|
|
|
|
|
2019-06-05 17:50:08 +00:00
|
|
|
* `instanceAge` (optional): the maximum age of an instance to grant a
|
|
|
|
certificate. The instance age is a string using the duration format.
|
|
|
|
|
2020-10-14 00:51:24 +00:00
|
|
|
* `iidRoots` (optional): the path to one or more public certificates in PEM
|
|
|
|
format used to validate the signature of the instance identity document.
|
|
|
|
|
2019-05-10 01:45:57 +00:00
|
|
|
* `claims` (optional): overwrites the default claims set in the authority, see
|
2020-05-01 21:47:29 +00:00
|
|
|
the [top](#provisioners) section for all the options.
|
2019-05-10 01:45:57 +00:00
|
|
|
|
2020-06-24 21:12:21 +00:00
|
|
|
#### GCP
|
2019-05-10 01:45:57 +00:00
|
|
|
|
|
|
|
The GCP provisioner grants certificates to Google Compute Engine instance using
|
|
|
|
its [identity](https://cloud.google.com/compute/docs/instances/verifying-instance-identity)
|
|
|
|
token. The CA will validate the JWT and grant a certificate.
|
|
|
|
|
|
|
|
In the ca.json, a GCP provisioner looks like:
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
|
|
|
"type": "GCP",
|
|
|
|
"name": "Google Cloud",
|
|
|
|
"serviceAccounts": ["1234567890"],
|
2019-06-05 17:50:08 +00:00
|
|
|
"projectIDs": ["project-id"],
|
2019-05-10 01:45:57 +00:00
|
|
|
"disableCustomSANs": false,
|
|
|
|
"disableTrustOnFirstUse": false,
|
2019-06-05 17:50:08 +00:00
|
|
|
"instanceAge": "1h",
|
2019-05-10 01:45:57 +00:00
|
|
|
"claims": {
|
|
|
|
"maxTLSCertDuration": "2160h",
|
|
|
|
"defaultTLSCertDuration": "2160h"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
* `type` (mandatory): indicates the provisioner type and must be `GCP`.
|
|
|
|
|
|
|
|
* `name` (mandatory): a string used to identify the provider when the CLI is
|
|
|
|
used.
|
|
|
|
|
|
|
|
* `serviceAccounts` (optional): the list of service account numbers that are
|
|
|
|
allowed to use this provisioner. If none is specified, all service accounts
|
|
|
|
will be valid.
|
|
|
|
|
2019-06-05 17:50:08 +00:00
|
|
|
* `projectIDs` (optional): the list of project identifiers that are allowed to
|
|
|
|
use this provisioner. If non is specified all project will be valid.
|
|
|
|
|
2019-05-10 01:45:57 +00:00
|
|
|
* `disableCustomSANs` (optional): by default custom SANs are valid, but if this
|
|
|
|
option is set to true only the SANs available in the instance identity
|
|
|
|
document will be valid, these are the DNS
|
|
|
|
`<instance-name>.c.<project-id>.internal` and
|
|
|
|
`<instance-name>.<zone>.c.<project-id>.internal`
|
|
|
|
|
|
|
|
* `disableTrustOnFirstUse` (optional): by default only one certificate will be
|
|
|
|
granted per instance, but if the option is set to true this limit is not set
|
|
|
|
and different tokens can be used to get different certificates.
|
|
|
|
|
2019-06-05 17:50:08 +00:00
|
|
|
* `instanceAge` (optional): the maximum age of an instance to grant a
|
|
|
|
certificate. The instance age is a string using the duration format.
|
|
|
|
|
2019-05-10 01:45:57 +00:00
|
|
|
* `claims` (optional): overwrites the default claims set in the authority, see
|
2020-05-01 21:47:29 +00:00
|
|
|
the [top](#provisioners) section for all the options.
|
2019-05-10 01:45:57 +00:00
|
|
|
|
2020-06-24 21:12:21 +00:00
|
|
|
#### Azure
|
2019-05-10 01:45:57 +00:00
|
|
|
|
|
|
|
The Azure provisioner grants certificates to Microsoft Azure instances using
|
|
|
|
the [managed identities tokens](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/how-to-use-vm-token).
|
|
|
|
The CA will validate the JWT and grant a certificate.
|
|
|
|
|
|
|
|
In the ca.json, an Azure provisioner looks like:
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
|
|
|
"type": "Azure",
|
|
|
|
"name": "Microsoft Azure",
|
|
|
|
"tenantId": "b17c217c-84db-43f0-babd-e06a71083cda",
|
|
|
|
"resourceGroups": ["backend", "accounting"],
|
|
|
|
"audience": "https://management.azure.com/",
|
|
|
|
"disableCustomSANs": false,
|
|
|
|
"disableTrustOnFirstUse": false,
|
|
|
|
"claims": {
|
|
|
|
"maxTLSCertDuration": "2160h",
|
|
|
|
"defaultTLSCertDuration": "2160h"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
* `type` (mandatory): indicates the provisioner type and must be `Azure`.
|
|
|
|
|
|
|
|
* `name` (mandatory): a string used to identify the provider when the CLI is
|
|
|
|
used.
|
|
|
|
|
|
|
|
* `tenantId` (mandatory): the Azure account tenant id for this provisioner. This
|
|
|
|
id is the Directory ID available in the Azure Active Directory properties.
|
|
|
|
|
|
|
|
* `audience` (optional): defaults to `https://management.azure.com/` but it can
|
|
|
|
be changed if necessary.
|
|
|
|
|
|
|
|
* `resourceGroups` (optional): the list of resource group names that are allowed
|
|
|
|
to use this provisioner. If none is specified, all resource groups will be
|
|
|
|
valid.
|
|
|
|
|
|
|
|
* `disableCustomSANs` (optional): by default custom SANs are valid, but if this
|
|
|
|
option is set to true only the SANs available in the token will be valid, in
|
|
|
|
Azure only the virtual machine name is available.
|
|
|
|
|
|
|
|
* `disableTrustOnFirstUse` (optional): by default only one certificate will be
|
|
|
|
granted per instance, but if the option is set to true this limit is not set
|
|
|
|
and different tokens can be used to get different certificates.
|
|
|
|
|
|
|
|
* `claims` (optional): overwrites the default claims set in the authority, see
|
2020-05-01 21:47:29 +00:00
|
|
|
the [top](#provisioners) section for all the options.
|