# Device Secrets
Device Secrets is a security concept that is designed to send, store, manage information such as keys within the cloud for various application needs. These secrets are secured in transit and at rest as per the minimum cybersecurity recommendations.
Your devices might have a requirement to operate on some "secret" values (connection strings, passwords, etc.). There might be cases where your device would create such secrets or receive them from the cloud. In the first case, it could be useful to store a secret (securely) in the cloud - to have a way of retrieving it back if the local version of the secret gets lost due to some unexpected conditions. In the second case, there might be a need for configuring the device with secret information from outside - i.e., via a configuration update.
Secure storage of keys, connection strings, passwords, and other secrets is provided by the Ability Platform's Information Model service (IM). IM takes the responsibility of keeping and protecting data securely, which is encrypted at rest and transit, with appropriate access control. Keys and secrets are only accessible by authorized users and applications.
An authenticated and authorized device can access only its own secrets.
The feature supports all CRUD operations for secrets:
- Create a secret
- Read a secret
- Update a secret
- Delete a secret
# Defining Secret
Secrets are defined as properties in the object models. They differ from other
properties by the addition of an attribute called secretType
. SecretType
is an
array of strings from enum = [ "persistent", "end-to-end" ]
TIP
For more information about Information Modeling, see Information Model Overview
An example of a type definition that defines a secret:
{
"model": "abb.ability.configuration",
"typeId": "abb.ability.opcuaConnectorModule.configuration",
"version": "1.0.0",
"properties": {
...
"properties": {
"dataDownloadFrequency": {
"value": "PT15M"
},
"opcuaServerConnectionString": {
"dataType": "string",
"secretType": ["end-to-end", "persistent"],
},
"factoryServer" : {
"serverIP": {
"dataType": "string"
},
"factoryServerPassword" : {
"secretType": ["persistent"],
"dataType": "string"
}
}
}
}
TIP
While defining a secret property in a type definition, you may restrict this
property's secretType
to be only end-to-end or persistent. You may also
allow both of these types. Then, it's up to a specific object which type it's
going to use for its secret.
Following are the ways to add secrets in the object model:
- Add a secret from the device side by using Device API. For example, model.create
- Add a secret from the cloud side by using Instance API's object model endpoints (i.e., POST /objects).
The following notation will be used in the diagrams/descriptions:
- Pk[d] - Device/Module Private Key
- Pu[d] - Device/Module Public Key
- Pu[IM] - Information Model Public Key (Used for device communication only)
- Pk[IM] - Information Model Private Key
- Sk[d] - Device/Module Symmetric Key (Recommended AES -128 bit)
- Sk[Dev->IM] - Symmetric Key (Generated by Device and used for transfer of secret to IM)
- Sk[IM->Dev] - Symmetric Key (Generated by IM and used for transfer of secret to Device)
- Sk[IM] - Symmetric key (Generated by IM and used only within IM to encrypt the secret while storing the object model)
The secrets can be of two types under secretType
system attribute:
- persistent
- end-to-end
# Persistent secrets
The secret is encrypted using keys managed by the Ability cloud.
When the module needs to save persistent secrets in Information Model, it performs the following steps:
- Module encrypts the secret using Information Model public key.
- Module sends the secret in the object model to Information Model and indicates
that the secretType is
persistent
along with the Information Model public key that is used to encrypt the secret. - Public keys belonging to devices/modules are stored in Principal Manager as a part of the identity of the device/module and can be read via an API call.
- Information Model receives the object model, decrypts the secret using Information Model private key, and re-encrypts the secret using IM's internal public key before storing the secret in the database.
When the module needs to receive the same secret back:
Information Model retrieves the object model from its database.
Information Model decrypts the secret using IM's internal private key.
Information Model re-encrypts the secret using Device/Module public key.
The device receives the object model and the secret decrypted by Device/Module private key.
# Using Persistent secretType
This section describes the working principle of Persistent secretType
:
# Bootstrap
- IM generates two pairs of asymmetric keys:
- The first pair of keys are internal to IM. IM uses those keys to encrypt and decrypt secrets while storing in the database
- The second pair of keys (Information Model public key and Information Model private key) are exclusively used for securing the transfer of secrets between devices and IM.
- A new message (
encryptionKey.get
) is introduced in Device API to allow connected devices to retrieve the IM's public key. - When a new module is started, it receives its public key and private key via docker secrets and reads the IM's public key from the Broker via the MQTT topic. Thus, the module has access to the device's public key, device's private key, and IM public key.
# Encryption of secrets at rest in Edge/Device
The broker cache in the device holds a copy of the object models (including secrets). However, the secrets in the object models are encrypted using the public key of the modules and hence are encrypted at rest.
The keys belonging to various modules are stored in Docker secrets. Docker
secrets are persisted at rest in raft
logs. To ensure that the raft
logs are
protected by a hardware-based root of trust (HW ROT) (for MCSR compliance), the
raft
logs are protected at rest using the auto-lock feature of Docker Swarm.
For more details on the auto-lock feature of Docker Swarm, please refer to
Docker Swarm
In Ability Edge, all the interactions to TPM are managed by SecStore service, so
to comply with MCSR for protection of swarm unlock key with HW ROT, SecStore
service provides an interface to Ability Edge Manager to invoke the SecStore
service for enabling the docker swarm auto-lock feature upon swarm
initialization and node unlock after restart of docker daemon. Enabling
auto-lock and unlocking is requested by abb-IoT-edge-unlock-swarm.service
.
# Pros and Cons using Persistent secretType
Pros:
- Secrets are end-to-end encrypted.
- Secrets are encrypted at rest in the edge.
- Secrets can be recovered in case of local edge disruptions.
- Additional hardware is not required from the device/edge side.
Cons:
- One additional encryption/decryption of secrets is required.
# End-To-End secrets
The keys used to encrypt the secret originate from the source module/device, and
the secret is end-to-end
encrypted.
- Secrets are encrypted with the public key of the module/device and stored in Information Model.
- Encrypted secrets are sent to the Information Model.
- Secrets can be retrieved at any time and decrypted using the device's private key.
- Asymmetric cryptography is used to encrypt/decrypt the secrets at rest and in transit.
- Public keys belonging to devices/modules are stored in Principal Manager as a part of the identity of the device/module and can be read via an API call.
- IM-owned keys are protected by Azure key vault. The private key stays in Azure Key Vault and thus confirms to MCSR. For more details, refer to Azure Key Vault documentation.
# Using end-to-end secretType
Secrets are encrypted with the Device/Module public key of the module/device and stored in IM. Encrypted secrets are sent to Information Model, secrets can be retrieved any time, and decrypted using the Device/Module private key.
The following requisites must be fulfilled to satisfy the end-to-end
conditions:
- Ensure that each module is authenticated that needs to store/retrieve the secrets
- Ensure that secrets are configured either from the cloud or from edge/device
- Ensure that secrets are protected at rest and during transit
- Ensure that secrets are restored to recover from hard disk failures.
# Configuration of Secrets from Cloud and/or from Edge/Device
Configuration of secrets from the cloud are as follows:
- The public keys associated with modules are sent to the cloud via
identity.update/identity.create
messages - The application retrieves the public keys and encrypts the secrets before sending them to the edge/device
- The secrets can be sent via
- Object models
- Method invocation (using an agreed method signature for secret provisioning that is implemented by modules).
# Pros and Cons using end-2-end secretType
Pros:
- The secret can be decrypted only by the device.
- Secrets are
end-to-end
encrypted and protected at rest.
Cons:
- Backup and restoration of secrets require an outside trusted party.
- Authorization for backup and restoration is not trivial.
- When the device gets corrupted/broken/whatever, the secret might be lost forever.
# Encryption algorithms and Key sizes
The RSA encryption and decryption algorithms are assumed to be used for secret encryption and decryption.
Note: As per the key length defined in the parameter of PKI_KEY_LENGTH
=
2048 in dpcm.config
file, TPM generates the key pair and stores it in
edgedevice-key.pem
. The key size of 2048 (PKI_KEY_LENGTH
) applies to keys
generated by devices. IM can choose to generate keys that are longer than 2048
bits for persistent secrets as they are re-encrypted en-route to the devices.
# Authorization for Read/Write of secrets
The following design is to ensure that the correct entities have access to read/write to the secrets. From the cloud end, once a secret is configured, it is impossible to retrieve a secret, only to be able to overwrite the secrets with a new one. It is assumed that applications or users do not need to read the secret information once configured, and such retrieval of the secret value from the cloud end is not supported. Only metadata of a secret can be retrieved from the cloud APIs.
# Configuration of the Secret from the cloud
Any principal that has object_model_write
permission is allowed to add/modify
secrets. Reading object models from cloud API will return the secret metadata
without the actual values of the secrets.
# Secret Read permissions for Devices (and modules)
An explicit declaration of modules/devices that can read the secrets is necessary. The entity that configures the secret also configures the entity that is allowed to read a secret as follows:
{
"objectId": "0027e126-869d-4174-bcd4-5bb3a2e6c8e1",
"model": "abb.ability.configuration",
"type": "abb.ability.opcuaConnectorModule.configuration@1",
"secretReaders" : ["<principal ID of the entity that can read the secret>"],
"properties": {
"dataDownloadFrequency": {
"value": "PT15M"
},
"opcSecret": {
"secretType": "end-to-end",
"value": "<encrypted string of the secret>"
},
"factoryServer" : {
"serverIP": {
"value": "10.140.150.160"
},
"factorySecret" : {
"secretType": "persistent",
"value": "<encrypted password for connection to imaginary factory server>"
}
}
}
}
# Subscriptions and Events behavior
The secret value is shown in the payload if the requestor's identity matches the
secretReader
property in the requested object model.The module doesn't receive the
secret
value in default subscription,ObjectModelUpdated
, andObjectModelCreated
issued via the cloud.The module can execute the action
ObjectModelQuery
, and in response, the payload includes thesecret
value.
TIP
A device API user can perform additional steps if the platform event from IM indicates the presence of secrets in the object model.
IM sends a platform event for object model subscriptions from devices when the object model changes (without secret value). In such case, Device API user should:
- Request the object model from IM on behalf of a device that is subscribed for this object model (i.e. an owner of a device object model for the current implicit subscription).
- Receive the object model with the secrets encrypted with the device's public key.
- Send the object model along with encrypted secrets to the device.