diff --git a/docs/connectivity/2-credentials/1-pki.md b/docs/connectivity/2-credentials/1-pki.md deleted file mode 100644 index f3d39f43..00000000 --- a/docs/connectivity/2-credentials/1-pki.md +++ /dev/null @@ -1,212 +0,0 @@ ---- -title: Public Key Infrastructure ---- - -A robust [Public Key Infrastructure -(PKI)](https://en.wikipedia.org/wiki/Public_key_infrastructure) is imperative -for ensuring secure cloud communication throughout the lifecycle of devices in a -fleet. PKI includes the creation, management, and distribution of keys and -certificates used in public-key cryptography. - -A central tenet of public-key cryptography is the protection of private key -material. Establishing PKI allows for private keys to be generated in and never -leave secure storage on a device. This dramatically reduces the potential of -private key material being compromised. - -## Establishing PKI - -In order to start leveraging PKI for device certificates, it is necessary to -provision infrastructure and establish at least one certiciate authority (CA). - -### Setting Up Infrastructure - -Customers are in full control of their PKI when using Golioth. While it is -possible to establish your own infrastructure, doing so requires extreme care -and domain expertise. For most organizations, leveraging a PKI vendor is -recommended. - -For demonstration purposes, local PKI can be established using tools such as -[`openssl`](https://github.com/openssl/openssl) or -[`cfssl`](https://github.com/cloudflare/cfssl). - -### Establishing a Certificate Authority - -Device certificates are issued by a certificate authority (CA). A CA is -typically comprised of a _root CA certificate_, and one or more _intermediate CA -certificates_, which are signed by the root and used to sign device -certificates. - -To generate a root CA certificate using `openssl`, a private key must first be -generated. - -``` -openssl ecparam -name prime256v1 -genkey -noout -out "ca.key.pem" -``` - -Because the root CA certificate serves as the anchor in a chain of trust, it is -self-signed with the previously generated key. - -``` -openssl req -x509 -new -nodes \ - -key "ca.key.pem" \ - -sha256 -subj "/CN=Root CA" \ - -days 10 -out "ca.crt.pem" -``` - -In this example, the root CA certificate is being generated with a common name -of `Root CA` and an expiration in `10` days. In a production scenario, root CA -certificates typically have an expiration many years in the future in order to -minimize the churn of establishing a new chain of trust. - -### Integrating with Golioth - -In order for Golioth to establish a chain of trust with certificates presented -by devices connecting to the platform, the root CA certificate and any -intermediate CA certificates must be uploaded in the relevant Golioth project. -This allows Golioth to verify that the certificate presented by a devices was -signed using the configured CA. If the device is then able to prove possession -of the private key associated with their certificate, then you can be certain -that it is a valid device and should be allowed to communicate. - -CA certificates can be uploaded in a Golioth project by navigating to the -`Certificates` section under `Credentials`. - -## Generating Device Certificates - -In a production provisioning flow, a private key should never leave the secure -region on the device where it is generated and stored. Instead, a _certificate -signing request (CSR)_ should be generated and exported. Some devices -incorporate a dedicated secure element IC for this purpose, while others -leverage integrated secure storage. - -The CSR is signed by the device's private key and can be presented to a CA, -which can then issue a signed certificate that can then be returned to the -device. The signed certificate is only useful for a device that can prove -possession of the associated private key. If the private key never leaves the -secure region of the device, and the device has not been otherwise compromised, -then only it should be able to use the certificate to authenticate and establish -a secure communication channel with Golioth. - -:::note Device Certificate Requirements -Device certificates used with the Golioth platform must set the subject -organization (`O`) to the slug for the appropriate project, which can be found -under [`Project Settings`](https://console.golioth.io/project-settings). The -common name (`CN`) must be set to a unique identifier for the device within the -project. The unique value used in the common name is referred to as the device's -_certificate ID_. See the [Certificate IDs](#certificate-ids) section below for -more information. -::: - -For demonstration purposes, the previously created local CA can be used to -issue device certificates with `openssl`. The first step is generating a private -key for the device. - -``` -openssl ecparam -name prime256v1 -genkey -noout -out "device.key.pem" -``` - -The device private key can then be used to create a CSR. - -:::tip -Make sure to replace `PROJECT_SLUG` and `CERTIFICATE_ID` with appropriate -values for your Golioth project. -::: - -``` -openssl req -new \ - -key "device.key.pem" \ - -subj "/O=PROJECT_SLUG/CN=CERTIFICATE_ID" \ - -out "device.csr.pem" -``` - -Finally, the local CA can be used to issue a device certificate by signing the -certificate in the CSR. - -``` -openssl x509 -req \ - -in "device.csr.pem" \ - -CA "ca.crt.pem" \ - -CAkey "ca.key.pem" \ - -CAcreateserial \ - -out "device.crt.pem" \ - -days 7 -sha256 -``` - -The resulting device certificate (`device.crt.pem`) will have parameters that -match the supplied CSR, and an expiration of `7` days. Similarly to the root CA -certificate, device certificates should be created with an expiration that is -appropriate for the lifecycle of the device. - -:::tip -Keys and certificates may be encoded in different formats for distribution. The -`openssl` commands above produce text-based PEM (`.pem`) encoded files. Devices -will frequently use the more compact binary DER (`.der`) encoding. The following -commands can be used to convert PEM encoded keys and certificates to DER. -``` -openssl ec -in device.key.pem -outform DER -out device.key.der -``` -``` -openssl x509 -in device.crt.pem -outform DER -out device.crt.der -``` -::: - - -### Certificate IDs - -When issuing a device certificate, the certificate ID used in the common name -(`CN`) is a unique identifier within the Golioth project specified in the -organization (`O`) that is used to distinguish the physical device when using -the certificate. The sole purpose of this identifier is to associate the -physical device with a device on the Golioth platform. While a device's -certificate ID may match other device attributes, such as the device name, it -does not specifically connotate any other meaning. Using a dedicated identifier -for this purpose enables [zero-touch provisioning](#zero-touch-provisioning) and -other flexible provisioning workflows. - -When a physical device presents a valid certificate to Golioth and proves -possession of the associated private key, the physical device is associated with -a device on Golioth according to the following logic. - -1. If a Golioth device already exists with the given certificate ID, the - physical device is associated with it. -2. If a Golioth device exists with a name that matches the certificate ID, and - it has no certificate ID set, then the certificate ID is set and the physical - device is associated with it. -3. If no devices exist with either a matching certificate ID, or a matching name - and no certificate ID, then a new device is created on Golioth with the - certificate ID set, and the physical device is associated with it. - -After a certificate ID is set on a Golioth device it is immutable. However, the -name of the device remains mutable. In the third case above, this can lead to a -scenario where a Golioth device exists with a name and certificate ID, and the -name matches the certificate ID presented by the physical device, but the -certificate IDs do not match. If this occurs, a new Golioth device is created -with certificate ID set to match the physical device's certificate ID, and with -name set to the same value of the certificate ID with a random suffix appended. -Otherwise, the name of the newly created Golioth device will be set to the same -value of the certificate ID. - -## Verification of Golioth Server Certificate - -Similarly to how Golioth must be able to establish a chain of trust rooted in -the CA certificates uploaded in a project, a device must also be able to verify -that it is communicating with Golioth. To accomplish this, one or more root CA -certificates must be stored on the device. Golioth will present a server -certificate, or a chain of certificates, that allow the device to establish a -chain of trust rooted in the stored CA certificates. - -Firmware SDKs and libraries distributed by Golioth typically will include the -necessary root CA certificates to verify certificates presented by the platform. -For example, the [Golioth Firmware -SDK](https://github.com/golioth/golioth-firmware-sdk) embeds the ISRG Root X1 -and Golioth Root X1 root CA certificates, whereas the -[`pouch`](https://github.com/golioth/pouch) only embeds the latter. - -## Zero-Touch Provisioning - -The use of certificates enables devices to be created on the Golioth platform -without a user needing to interact with the console or [management -API](/reference/management-api). This workflow is referred to as _zero-touch -provisioning_ and can alleviate operational overhead, particularly when -deploying large fleets of devices. However, customers are still welcome to -manually provision devices prior to their first connection. diff --git a/docs/connectivity/2-credentials/1-pki/1-aws.md b/docs/connectivity/2-credentials/1-pki/1-aws.md new file mode 100644 index 00000000..a4e8b128 --- /dev/null +++ b/docs/connectivity/2-credentials/1-pki/1-aws.md @@ -0,0 +1,93 @@ +--- +title: "AWS Private CA" +--- + +To allow Golioth to use your AWS Private Certificate Authority service as a PKI +provider for your project, you need to go through a few steps in the AWS Console +before you can configure a connection from Golioth. + +For information about how you can establish a CA in AWS Private CA and issue +end-entity certificates, please refer to [the official AWS +documentation](https://docs.aws.amazon.com/privateca/latest/userguide/PcaWelcome.html). + +## Configuring AWS + +To allow Golioth to securely connect directly to your AWS Private CA service, +you'll need to create an IAM user with the required permissions. + +### 1. Create an IAM user + +Golioth connects to your AWS Private CA service as an IAM user. Although it's +possible for Golioth to authenticate as an existing user, we strongly recommend +establishing a dedicated user with a narrow set of permissions. + +As an admin or an IAM user with the required permissions, navigate to the [IAM +User Management Dashboard](https://console.aws.amazon.com/iamv2/home#/users) in +the AWS Console, and click **Create User**. + +![Create a user](./assets/aws-user.png) + +Pick a recognizable user name, and click **Next** to go to the permissions +screen. + +### 2. Set Permissions + +The Golioth user requires read access to the Private CA service to be able to +authenticate device certificates. This can be enabled by attaching the +**AWSPrivateCAReadOnly** policy to the user. + +To enable certificate rotation for your devices, you additionally need write +permission for the AWS Private CA service. This can be enabled by attaching the +**AWSPrivateCAUser** policy to the user. + +![Attaching Policies](./assets/aws-policies.png) + +:::note +Other, more permissive policies, such as **AWSPrivateCAFullAccess** and +**AWSPrivateCAPrivilegedUser** also grant the required permissions to verify and +issue device certificates, but these policies additionally grant the user the +ability to manage the CA certificates themselves, which is not necessary, and +thus not recommended. +::: + +Policies can either be attached to the user directly when you create it, or by +assigning the user to a user group with the required permissions. + +#### Required permissions: + +Golioth requires the following permissions to verify device certificates: + +- `acm-pca:ListCertificateAuthorities` +- `acm-pca:GetCertificateAuthorityCertificate` + +To enable certificate rotation, Golioth additionally requires the following +permissions: + +- `acm-pca:IssueCertificate` +- `acm-pca:GetCertificate` + +### 3. Create an access key + +Once the user is created with the required permissions, you'll need to create an +access key that Golioth can use to authenticate as that user. + +Follow [the AWS +documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/access-keys-admin-managed.html) +for instructions on how to create an access key for an IAM user. Note that the +secret access key is only available during the creation process, and must be +saved before leaving the page. + +## Connecting to AWS from the Golioth Console + +Once you have an AWS IAM user with the required permissions, you can configure +Golioth's connection to the AWS Private CA from the Golioth Console. Navigate to +the PKI Providers section in the sidebar, and click **Add Provider**. In the +modal window, select _AWS Private Certificate Authority_, and the correct region +for your AWS instance. Add the Access Key ID and Secret Access Key that you +created in the AWS Console, and click **Connect**. The provider will be added to +the list of known providers, and a provider status check will run. + +If everything is configured correctly, the provider status should change to +"Connected", and list the number of available certificate authorities. + +![Configured Provider](./assets/configured-provider.png) diff --git a/docs/connectivity/2-credentials/1-pki/2-local-pki.md b/docs/connectivity/2-credentials/1-pki/2-local-pki.md new file mode 100644 index 00000000..ec95dfa8 --- /dev/null +++ b/docs/connectivity/2-credentials/1-pki/2-local-pki.md @@ -0,0 +1,131 @@ +--- +title: "Setting up a local PKI" +--- + +For demonstration and testing purposes, local PKI can be established using tools +such as [`openssl`](https://github.com/openssl/openssl) or +[`cfssl`](https://github.com/cloudflare/cfssl). + +This approach is not recommended for production environments, but can be an easy +way to get started with using certificates. + +## Establishing a Certificate Authority + +Device certificates are issued by a certificate authority (CA). A CA is +typically comprised of a _root CA certificate_, and one or more _intermediate CA +certificates_, which are signed by the root and used to sign device +certificates. + +To generate a root CA certificate using `openssl`, a private key must first be +generated. + +``` +openssl ecparam -name prime256v1 -genkey -noout -out "ca.key.pem" +``` + +Because the root CA certificate serves as the anchor in a chain of trust, it is +self-signed with the previously generated key. + +``` +openssl req -x509 -new -nodes \ + -key "ca.key.pem" \ + -sha256 -subj "/CN=Root CA" \ + -days 10 -out "ca.crt.pem" +``` + +In this example, the root CA certificate is being generated with a common name +of `Root CA` and an expiration in `10` days. In a production scenario, root CA +certificates typically have an expiration many years in the future in order to +minimize the churn of establishing a new chain of trust. + +## Integrating with Golioth + +In order for Golioth to establish a chain of trust with certificates presented +by devices connecting to the platform, the root CA certificate and any +intermediate CA certificates must be uploaded in the relevant Golioth project. +This allows Golioth to verify that the certificate presented by a devices was +signed using the configured CA. If the device is then able to prove possession +of the private key associated with their certificate, then you can be certain +that it is a valid device and should be allowed to communicate. + +CA certificates can be uploaded in a Golioth project by navigating to the +`Certificates` section under `Credentials`. + +## Generating Device Certificates + +In a production provisioning flow, a private key should never leave the secure +region on the device where it is generated and stored. Instead, a _certificate +signing request (CSR)_ should be generated and exported. Some devices +incorporate a dedicated secure element IC for this purpose, while others +leverage integrated secure storage. + +The CSR is signed by the device's private key and can be presented to a CA, +which can then issue a signed certificate that can then be returned to the +device. The signed certificate is only useful for a device that can prove +possession of the associated private key. If the private key never leaves the +secure region of the device, and the device has not been otherwise compromised, +then only it should be able to use the certificate to authenticate and establish +a secure communication channel with Golioth. + +:::note Device Certificate Requirements +Device certificates used with the Golioth platform must set the subject +organization (`O`) to the slug for the appropriate project, which can be found +under [`Project Settings`](https://console.golioth.io/project-settings). The +common name (`CN`) must be set to a unique identifier for the device within the +project. The unique value used in the common name is referred to as the device's +_certificate ID_. See the [Certificate IDs](#certificate-ids) section below for +more information. +::: + +For demonstration purposes, the previously created local CA can be used to +issue device certificates with `openssl`. The first step is generating a private +key for the device. + +``` +openssl ecparam -name prime256v1 -genkey -noout -out "device.key.pem" +``` + +The device private key can then be used to create a CSR. + +:::tip +Make sure to replace `PROJECT_SLUG` and `CERTIFICATE_ID` with appropriate +values for your Golioth project. +::: + +``` +openssl req -new \ + -key "device.key.pem" \ + -subj "/O=PROJECT_SLUG/CN=CERTIFICATE_ID" \ + -out "device.csr.pem" +``` + +Finally, the local CA can be used to issue a device certificate by signing the +certificate in the CSR. + +``` +openssl x509 -req \ + -in "device.csr.pem" \ + -CA "ca.crt.pem" \ + -CAkey "ca.key.pem" \ + -CAcreateserial \ + -out "device.crt.pem" \ + -days 7 -sha256 +``` + +The resulting device certificate (`device.crt.pem`) will have parameters that +match the supplied CSR, and an expiration of `7` days. Similarly to the root CA +certificate, device certificates should be created with an expiration that is +appropriate for the lifecycle of the device. + +:::tip +Keys and certificates may be encoded in different formats for distribution. The +`openssl` commands above produce text-based PEM (`.pem`) encoded files. Devices +will frequently use the more compact binary DER (`.der`) encoding. The following +commands can be used to convert PEM encoded keys and certificates to DER. +``` +openssl ec -in device.key.pem -outform DER -out device.key.der +``` +``` +openssl x509 -in device.crt.pem -outform DER -out device.crt.der +``` +::: diff --git a/docs/connectivity/2-credentials/1-pki/README.md b/docs/connectivity/2-credentials/1-pki/README.md new file mode 100644 index 00000000..8e63be48 --- /dev/null +++ b/docs/connectivity/2-credentials/1-pki/README.md @@ -0,0 +1,111 @@ +--- +title: Public Key Infrastructure +--- + +A robust [Public Key Infrastructure +(PKI)](https://en.wikipedia.org/wiki/Public_key_infrastructure) is imperative +for ensuring secure cloud communication throughout the lifecycle of devices in a +fleet. PKI includes the creation, management, and distribution of keys and +certificates used in public-key cryptography. + +A central tenet of public-key cryptography is the protection of private key +material. Establishing PKI allows for private keys to be generated in and never +leave secure storage on a device. This dramatically reduces the potential of +private key material being compromised. + +## Establishing PKI + +When one of your devices connects to Golioth, it'll prove its identity by +presenting a signed certificate. The device certificate contains the device's +public key, as well as its project and device ID. Device certificates are issued +by a _certificate authority_ (CA), which validated the information in the +certificate and signed it. + +To verify the certificate the device presented, Golioth goes through a list of +known CAs for your project. If the device's certificate was signed by one of the +known CAs, Golioth can trust the information within it, and the device can +start sending and receiving data. + +In order to start leveraging PKI for device certificates, it is necessary to +establish at least one CA, and register it with Golioth. + +### PKI Providers + +Golioth supports two mechanisms for registering CAs: Direct connections to +external PKI providers, and manually uploading CA certificates. By establishing a +direct connection to an external PKI provider, Golioth automatically keeps an up +to date list of CAs, and is able to forward certificate signing requests on +behalf of your devices, allowing devices to perform certificate rotation through +Golioth's infrastructure. + +For now, the only supported external PKI provider type is [AWS Private +Certificate Authority](https://aws.amazon.com/private-ca/). If you're using a +different service for your Public Key Infrastructure, you need to register your +CAs manually, and certificate rotation will not be supported. + +Read [how to set up AWS Private CA as a PKI provider](./1-aws.md) for detailed +instructions on how to set this up. + +If you do not have a PKI provider service set up, but still want to leverage +certificate authentication in your development process, you can also [establish +local PKI](./2-local-pki.md) with [`openssl`](https://github.com/openssl/openssl). + +## Certificate IDs + +When issuing a device certificate, the certificate ID used in the common name +(`CN`) is a unique identifier within the Golioth project specified in the +organization (`O`) that is used to distinguish the physical device when using +the certificate. The sole purpose of this identifier is to associate the +physical device with a device on the Golioth platform. While a device's +certificate ID may match other device attributes, such as the device name, it +does not specifically connotate any other meaning. Using a dedicated identifier +for this purpose enables [zero-touch provisioning](#zero-touch-provisioning) and +other flexible provisioning workflows. + +When a physical device presents a valid certificate to Golioth and proves +possession of the associated private key, the physical device is associated with +a device on Golioth according to the following logic. + +1. If a Golioth device already exists with the given certificate ID, the + physical device is associated with it. +2. If a Golioth device exists with a name that matches the certificate ID, and + it has no certificate ID set, then the certificate ID is set and the physical + device is associated with it. +3. If no devices exist with either a matching certificate ID, or a matching name + and no certificate ID, then a new device is created on Golioth with the + certificate ID set, and the physical device is associated with it. + +After a certificate ID is set on a Golioth device it is immutable. However, the +name of the device remains mutable. In the third case above, this can lead to a +scenario where a Golioth device exists with a name and certificate ID, and the +name matches the certificate ID presented by the physical device, but the +certificate IDs do not match. If this occurs, a new Golioth device is created +with certificate ID set to match the physical device's certificate ID, and with +name set to the same value of the certificate ID with a random suffix appended. +Otherwise, the name of the newly created Golioth device will be set to the same +value of the certificate ID. + +## Verification of Golioth Server Certificate + +Similarly to how Golioth must be able to establish a chain of trust rooted in +the CA certificates uploaded in a project, a device must also be able to verify +that it is communicating with Golioth. To accomplish this, one or more root CA +certificates must be stored on the device. Golioth will present a server +certificate, or a chain of certificates, that allow the device to establish a +chain of trust rooted in the stored CA certificates. + +Firmware SDKs and libraries distributed by Golioth typically will include the +necessary root CA certificates to verify certificates presented by the platform. +For example, the [Golioth Firmware +SDK](https://github.com/golioth/golioth-firmware-sdk) embeds the ISRG Root X1 +and Golioth Root X1 root CA certificates, whereas the +[`pouch`](https://github.com/golioth/pouch) only embeds the latter. + +## Zero-Touch Provisioning + +The use of certificates enables devices to be created on the Golioth platform +without a user needing to interact with the console or [management +API](/reference/management-api). This workflow is referred to as _zero-touch +provisioning_ and can alleviate operational overhead, particularly when +deploying large fleets of devices. However, customers are still welcome to +manually provision devices prior to their first connection. diff --git a/docs/connectivity/2-credentials/1-pki/_category_.yml b/docs/connectivity/2-credentials/1-pki/_category_.yml new file mode 100644 index 00000000..88dbaaed --- /dev/null +++ b/docs/connectivity/2-credentials/1-pki/_category_.yml @@ -0,0 +1,4 @@ +label: 'Public Key Infrastructure' +position: 1 # float position is supported +collapsible: true # make the category collapsible +collapsed: false # keep the category open by default diff --git a/docs/connectivity/2-credentials/1-pki/assets/aws-policies.png b/docs/connectivity/2-credentials/1-pki/assets/aws-policies.png new file mode 100644 index 00000000..b9f0354e Binary files /dev/null and b/docs/connectivity/2-credentials/1-pki/assets/aws-policies.png differ diff --git a/docs/connectivity/2-credentials/1-pki/assets/aws-user.png b/docs/connectivity/2-credentials/1-pki/assets/aws-user.png new file mode 100644 index 00000000..cef04706 Binary files /dev/null and b/docs/connectivity/2-credentials/1-pki/assets/aws-user.png differ diff --git a/docs/connectivity/2-credentials/1-pki/assets/configured-provider.png b/docs/connectivity/2-credentials/1-pki/assets/configured-provider.png new file mode 100644 index 00000000..56e9b7b1 Binary files /dev/null and b/docs/connectivity/2-credentials/1-pki/assets/configured-provider.png differ