Needed to run two commands to set up IAM roles because passing `--role` twice only uses the second value passed.
8.3 KiB
Certificate Management Services
This document describes how to use a certificate management service or CAS to sign X.509 certificates requests.
A CAS is a system that implements an API to sign certificate requests, the difference between CAS and KMS is that the latter can sign any data, while CAS is intended to sign only X.509 certificates.
step-ca
defines an interface that can be implemented to support other
services, currently only CloudCAS and the default SoftCAS are implemented.
The CertificateAuthorityService
is defined in the package
github.com/smallstep/certificates/cas/apiv1
and it is:
type CertificateAuthorityService interface {
CreateCertificate(req *CreateCertificateRequest) (*CreateCertificateResponse, error)
RenewCertificate(req *RenewCertificateRequest) (*RenewCertificateResponse, error)
RevokeCertificate(req *RevokeCertificateRequest) (*RevokeCertificateResponse, error)
}
The same package defines another interface that is used to get the root certificates from the CAS:
type CertificateAuthorityGetter interface {
GetCertificateAuthority(req *GetCertificateAuthorityRequest) (*GetCertificateAuthorityResponse, error)
}
SoftCAS
SoftCAS is the default implementation supported by step-ca
. No special
configurations are required to enable it.
SoftCAS generally uses certificates and keys in the filesystem, but a KMS can also be used instead of a key file for signing certificates. See KMS for more information.
CloudCAS
CloudCAS is the implementation of the CertificateAuthorityService
and
CertificateAuthorityGetter
interfaces using Google's Certificate Authority
Service.
Before enabling CloudCAS in step-ca
you do some steps in Google Cloud Console
or using gcloud
CLI:
-
Create or define a project to use. Let's say the name is
smallstep-cas-test
. -
Create the KMS keyring and keys for root and intermediate certificates:
# Create key ring gcloud kms keyrings create kr1 --location us-west1 # Create key for Root certificate gcloud kms keys create k1 \ --location us-west1 \ --keyring kr1 \ --purpose asymmetric-signing \ --default-algorithm ec-sign-p256-sha256 \ --protection-level software # Create key for Intermediate certicate gcloud kms keys create k2 \ --location us-west1 \ --keyring kr1 \ --purpose asymmetric-signing \ --default-algorithm ec-sign-p256-sha256 \ --protection-level software # Put the resource name for version 1 of the new KMS keys into a shell variable. # This will be used in the other instructions below. KMS_ROOT_KEY_VERSION=$(gcloud kms keys versions describe 1 --key k1 --keyring kr1 --location us-west1 --format "value(name)") KMS_INTERMEDIATE_KEY_VERSION=$(gcloud kms keys versions describe 1 --key k2 --keyring kr1 --location us-west1 --format "value(name)")
-
Enable the CA service API. You can do it on the console or running:
gcloud services enable privateca.googleapis.com
-
Configure IAM. Create a service account using Google Console or running:
# Create service account gcloud iam service-accounts create step-ca-sa \ --project smallstep-cas-test \ --description "Step-CA Service Account" \ --display-name "Step-CA Service Account" # Add permissions to use the privateca API gcloud projects add-iam-policy-binding smallstep-cas-test \ --member=serviceAccount:step-ca-sa@smallstep-cas-test.iam.gserviceaccount.com \ --role=roles/privateca.caManager gcloud projects add-iam-policy-binding smallstep-cas-test \ --member=serviceAccount:step-ca-sa@smallstep-cas-test.iam.gserviceaccount.com \ --role=roles/privateca.certificateRequester # Download the credentials.file gcloud iam service-accounts keys create credentials.json \ --iam-account step-ca-sa@smallstep-cas-test.iam.gserviceaccount.com
-
Create a Root CA. You can do this on the console or running:
gcloud beta privateca roots create prod-root-ca \ --location us-west1 \ --kms-key-version "$KMS_ROOT_KEY_VERSION" \ --subject "CN=Example Root CA, O=Example LLC" \ --max-chain-length 2
-
Create an Intermediate CA. You can do this on the console or running:
gcloud beta privateca subordinates create prod-intermediate-ca \ --location us-west1 \ --issuer prod-root-ca \ --issuer-location us-west1 \ --kms-key-version "$KMS_INTERMEDIATE_KEY_VERSION" \ --subject "CN=Example Intermediate CA, O=Example LLC" \ --reusable-config "subordinate-server-tls-pathlen-0"
Not it's time to enable it in step-ca
adding the new property "cas"
must be added
to the ca.json
.
{
"cas": {
"type": "cloudCAS",
"credentialsFile": "/path/to/credentials.json",
"certificateAuthority": "projects/<name>/locations/<loc>/certificateAuthorities/<ca-name>"
}
}
- type defines the name of the CAS to use, cloudCAS must be used to enable it.
- credentialsFile defines the path to a Google Cloud credential file with
access to Google's Certificate AuthorityService. We created this file before
in step 4. Instead of setting this property, the environment variable
GOOGLE_APPLICATION_CREDENTIALS
can be pointed to the file to use. Or if thestep-ca
is running in Google Cloud, the default service account in the machine can also be used. - certificateAuthority defines the Google Cloud resource to the intermediate (or subordinated) certificate to use. We created this resource in step 6.
As we said before, the CloudCAS implementation in step-ca
also defines the
interface CertificateAuthorityGetter
, this allows step-ca
to automatically
download the root certificate from Cloud CAS. In the ca.json
now you don't
need to configure "root"
, and because the intermediate is in Google Cloud,
"crt"
and "key"
are no needed. A full ca.json
can look like:
{
"address": ":443",
"dnsNames": ["ca.example.com"],
"logger": {"format": "text"},
"db": {
"type": "badger",
"dataSource": "/home/jane/.step/db",
},
"cas": {
"type": "cloudCAS",
"credentialsFile": "/home/jane/.step/credentials.json",
"certificateAuthority": "projects/smallstep-cas-test/locations/us-west1/certificateAuthorities/prod-intermediate-ca"
},
"authority": {
"provisioners": [
{
"type": "JWK",
"name": "jane@example.com",
"key": {
"use": "sig",
"kty": "EC",
"kid": "ehFT9BkVOY5k_eIiMax0ZxVZCe2hlDVkMwZ2Y78av4s",
"crv": "P-256",
"alg": "ES256",
"x": "GtEftN0_ED1lNc2SEUJDXV9EMi7JY-kqINPIEQJIkjM",
"y": "8HYFdNe1MbWcbclF-hU1L80SCmMcZQI6vZfTOXfPOjg"
},
"encryptedKey": "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJjdHkiOiJqd2sranNvbiIsImVuYyI6IkEyNTZHQ00iLCJwMmMiOjEwMDAwMCwicDJzIjoiSjBSWnY5UFZrM3JKRUJkem5RbExzZyJ9.Fiwvo-RIKU5G6v5udeCT1nlX87ElxrocP2FcgNs3AqEz5OH9H4suew.NmzUJR_9xv8ynQC8.dqOveA_G5kn5lxjxnEZoJCystnJMVYLkZ_8CVzfJQhYchbZfNk_-FKdIuQxeWWBzvmomsILFNtLOIUoqSt30qk83lFyGQWN8Ke2bK5DhuwojF7RI_UqkMyiKP0F28Z4ZFhfQP5D2ZT_stoFaMlU8eak0-T8MOiBIfdAJTWM9x2DN-68mtUBuL5z5eU8bqsxELnjGauD_GHTdnduOosmYsw8vp_PmffTTwqUzDFH1RhkeSmRFRZntAizZMGYkxLamquHI3Jvuqiv4eeJ3yLqh3Ppyo_mVQKnxM7P9TyTxcvLkb2dB3K-cItl1fpsz92cy8euKsKG8n5-hKFRyPfY.j7jBN7nUwatoSsIZuNIwHA"
}
]
},
"tls": {
"cipherSuites": [
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
],
"minVersion": 1.2,
"maxVersion": 1.3,
"renegotiation": false
}
}
The we only need to run step-ca
as usual, but this time, the CA will print the
root fingerprint too:
$ step-ca /home/jane/.step/config/ca.json
2020/09/22 13:17:15 Using root fingerprint '3ef16343cf0952eedbe2b843066bb798fa7a7bceb16aa285e8b0399f661b28b7'
2020/09/22 13:17:15 Serving HTTPS on :9000 ...
We will need to bootstrap once our environment using the printed fingerprint:
step ca bootstrap --ca-url https://ca.example.com --fingerprint 3ef16343cf0952eedbe2b843066bb798fa7a7bceb16aa285e8b0399f661b28b7
And now we can sign sign a certificate as always:
step ca certificate test.example.com test.crt test.key