Rename docs to site (#1550)

Signed-off-by: Marinov Avgustin <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2024-01-18 15:31:20 +02:00
committed by GitHub
parent d15bcce8d2
commit f2a4f6f591
106 changed files with 5 additions and 25 deletions

View File

@@ -0,0 +1,268 @@
---
title: Authentication
parent: Concepts
weight: 51
---
A hawkBit update server can be accessed in four different ways:
- _Direct Device Integration (DDI) API_ by **targets**.
- _Management API_ by 3rd party **applications**.
- _Device Management Federation (DMF) API_ by 3rd party **applications** through AMQP.
- _Management UI_ by **users**.
<!--more-->
## DDI API Authentication Modes
### Security Token
hawkBit supports multiple ways to authenticate a target against the server. The different authentication modes can be individual enabled and disabled within hawkBit. Both on system level (with Spring Boot properties) as per individual tenant.
#### Target Security Token Authentication
There is a 32 alphanumeric character security-token for each created target within IoT hawkBit. This token can be used to authenticate the target at hawkBit through the HTTP-Authorization header with the custom scheme _TargetToken_.
```
GET /SPDEMO/controller/v1/0e945f95-9117-4500-9b0a-9c6d72fa6c07 HTTP/1.1
Host: your.hawkBit.server
Authorization: TargetToken bH7XXAprK1ChnLfKSdtlsp7NOlPnZAYY
```
The target security token is provided in [DMF API](../../apis/dmf_api/) as part of the update message in order to allow DMF clients to leverage the feature or can it be manually retrieved per target by [Management API](../../apis/management_api/) or in the [Management UI](../../ui) in the target details.
Note: needs to be enabled in your hawkBit installation **and** in the tenant configuration. That allows both the operator as well as the individual customer (if run in a multi-tenant setup) to enable this access method. See [DdiSecurityProperties](https://github.com/eclipse/hawkbit/blob/master/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/DdiSecurityProperties.java) for system wide enablement.
The additional activation for the individual tenant:
![Enable Target Token](../../images/security/targetToken.png)
#### Gateway Security Token Authentication
Often the targets are connected through a gateway which manages the targets directly and as a result are indirectly connected to the hawkBit update server.
To authenticate this gateway and allow it to manage all target instances under its tenant there is a _GatewayToken_ to authenticate this gateway through the HTTP-Authorization header with a custom scheme _GatewayToken_. This is of course also handy during development or for testing purposes. However, we generally recommend to use this token with care as it allows to act _in the name of_ any device.
```
GET /SPDEMO/controller/v1/0e945f95-9117-4500-9b0a-9c6d72fa6c07 HTTP/1.1
Host: your.hawkBit.server
Authorization: GatewayToken 3nkswAZhX81oDtktq0FF9Pn0Tc0UGXPW
```
Note: needs to be enabled in your hawkBit installation **and** in the tenant configuration. That allows both the operator as well as the individual customer (if run in a multi-tenant setup) to enable this access method. See [DdiSecurityProperties](https://github.com/eclipse/hawkbit/blob/master/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/DdiSecurityProperties.java) for system wide enablement.
The additional activation for the individual tenant:
![Enable Gateway Token](../../images/security/gatewayToken.png)
#### Anonymous access
Here we offer general anonymous access for all targets (see [DdiSecurityProperties](https://github.com/eclipse/hawkbit/blob/master/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/DdiSecurityProperties.java)) which we consider not really sufficient for a production system but it might come in handy to get a project started in the beginning.
However, anonymous download on the other side might be interesting even in production for scenarios where the artifact itself is already encrypted.
The activation for the individual tenant:
![Enable Anonymous Download](../../images/security/anonymousDownload.png)
### Certificate Authentication by Reverse Proxy
hawkBit offers a certificate-based authentication mechanism, also known as mutual TLS (mTLS), which eliminates the need to share a security token with the server. To implement this, you'll require a reverse proxy deployed in front of the hawkBit server to handle authentication. This process involves obtaining certificates (and keys) for both the client and the reverse proxy and configuring hawkBit accordingly.
Initially, you'll need to obtain certificates (and keys) for these components from the same or different Certificate Authorities (CAs). Once you have acquired certificates you have to set them up to both the client and the hawkBit server.
Then you shall enable *Allow targets to authenticate via a certificate authenticated by a reverse proxy* and set the fingerprint of the client certificate issuer(s) (as a comma separated list).
To authenticate the request to hawBit the following condition shall be met:
- the common name of the client certificate shall match the controller/client id
- the SSL Issuer(s) hash of the presented client certificate shall be set for the tenant. For that, in Hawkbit's UI section, under system configuration, you shall enable 'Allow targets to authenticate via a certificate by an reverse proxy' and set the hash of the client certificate issuer(s) (as a comma separated list).
![Example Reverse Proxy Settings](../../images/security/exampleReverseProxySettings.png)
You can use the following command to get the issuer hash:
```shell
openssl x509 -in client_certificate.crt -issuer_hash -noout`
```
Here is an example diagram that shows all the communication between the hawkBit, reverse proxy and client. For the sake of simplification we assume that there are not intermediate certificates and the certificate and key are as follows:
- client_ca.crt signs client.crt
- server_ca.crt signs server.crt
- client has the client.crt, client.key and server_ca.crt
- server (in this case reverse proxy) has the server.crt, server.key and client_ca.crt
![Example Reverse Proxy Architecture](../../images/security/exampleReverseProxyArchitecture.png)
#### Example - Nginx Reverse Proxy Configurations
Nginx doesn't support obtaining the issuer hash without addons. Therefore, in this example we bypass sending real SSL Issuer hash to hawhBit but do certificate issuer validation at Nginx and then supply shared (between Nginx and hawkBit) fixed hash "Hawkbit". You could use any value here as long as it is matched with the *Allow targets to authenticate via a certificate authenticated by a reverse proxy* setting in the hawkBit UI. Note that for multi-tenant scenarios with different trusted CAs this example won't work.
1. Hawkbit Configurations
There are also some configurations that you need update when you deployed your hawkbit service.
You need to add the given setting to your hawkBit configurations so that hawkBit can generate the URLs according to the https that the client will use to download. If you're deploying hawkBit as a Docker container, add these configurations as environmental values in the docker-compose.yml file.
```
server.forward-headers-strategy=NATIVE
```
2. In Hawkbit's UI section, under system configuration, make sure to select *Allow targets to authenticate via a certificate authenticated by a reverse proxy* and input the fixed issuer hash as "Hawkbit". This can be whetever you have configured in the nginx configuration in `proxy_set_header X-Ssl-Issuer-Hash-1` below.
3. After placing your certificates and keys, you need to deploy your proxy server and apply the provided configurations. You can apply mutual TLS specifically to the URL given below to implement the process only for devices using the Device Integration API:
`hawkbit.dev.example.com/default/controller/`
This ensures that other clients, like UI users, can connect to hawkBit without requiring client certificates. They can use Username and Password in the Management API, eliminating the need for authentication and making it more user-friendly.
```nginx
# Nginx Hawkbit Configurations
# Gets the Common Name of the certificate from the client certificate.
map $ssl_client_s_dn $ssl_client_s_dn_cn {
default "";
~CN=(?<CN>[^,]+) $CN;
}
server {
listen 80;
listen [::]:80;
server_name hawkbit.dev.example.com www.hawkbit.dev.example.com;
server_tokens off;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://hawkbit.dev.example.com$request_uri;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name hawkbit.dev.example.com;
ssl_certificate /etc/nginx/ssl/live/hawkbit.dev.example.com/server.crt;
ssl_certificate_key /etc/nginx/ssl/live/hawkbit.dev.example.com/server.key;
ssl_client_certificate /etc/nginx/client-cer/client_ca.crt;
ssl_verify_client optional;
ssl_verify_depth 3;
# For devices that is using device integration API,
# Mutual TLS is required.
location ~*/.*/controller/ {
if ($ssl_client_verify != SUCCESS) {
return 403;
}
proxy_pass http://hawkbit.dev.example.com:8080;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Client certificate Common Name and Issuer Hash is required
# for auth in hawkbit.
proxy_set_header X-Ssl-Client-Cn $ssl_client_s_dn_cn;
proxy_set_header X-Ssl-Issuer-Hash-1 Hawkbit;
# These are required for clients to upload and download software.
proxy_request_buffering off;
client_max_body_size 1000m;
}
# For clients that is using UI or Management API
location / {
proxy_pass http://hawkbit.dev.example.com:8080;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_request_buffering off;
client_max_body_size 1000m;
}
}
```
4. To deploy Nginx, you could use a `.yml` file. Here's an example `docker-compose.yml` file for Nginx Docker.
```yml
version: '3'
services:
webserver:
image: nginx:latest
ports:
- 80:80
- 443:443
restart: always
volumes:
- ./nginx/conf/:/etc/nginx/conf.d/:ro
- ./certbot/www:/var/www/certbot/:ro
- ./certbot/conf/:/etc/nginx/ssl/:ro
- ./client-cer/:/etc/nginx/client-cer/
- ./landing-page/:/etc/webserver/landing-page
certbot:
image: certbot/certbot:latest
volumes:
- ./certbot/www/:/var/www/certbot/:rw
- ./certbot/conf/:/etc/letsencrypt/:rw
```
`/client-cer/:/etc/nginx/client-cer/` is the designated location for the certificate authority that has signed the client certificate. The presented client certificate will be verified against this CA.
5. After successfully generating your certificates with the correct chain, deploying your Nginx and Hawkbit services with appropriate configurations, and updating the settings on the device side, you will be able to establish a certificate-based authentication mechanism. This will eliminate the necessity of sharing a security token with the server.
&nbsp;
##### Swupdate Suricatta Configurations
If the client is utilizing the SWUpdate Suricatta service, the configurations on the device or client side should also be adjusted as follows. Remember to change id, url and certificate names to your needs.
The location of the config file is `/etc/swupdate/swupdate.conf`
```yml
suricatta :
{
tenant = "default";
id = "device_id";
url = "https://hawkbit.dev.example.com";
nocheckcert = false;
cafile = "server_ca.crt";
sslkey = "/etc/ssl/certs/client.key";
sslcert = "/etc/ssl/certs/client.crt";
};
```
If your client service is a linux, you can use the command bellow to see the logs produced by the swupdate.
```shell
journalctl --follow -u swupdate
```
&nbsp;
##### Testing
You can test the communication by using the Curl command below to see if you successfully implemented mutual TLS:
```shell
curl -L -v --cert client.crt --key client.key --cacert server_ca.crt https://hawkbit.dev.example.com/default/controller/v1/{device-id}
```
In the UI, after uploading an SWU package and requesting a firmware update, you can use the link below to attempt to install the software package.
```
curl -L -v --cert client.crt --key client.key --cacert server_ca.crt https://hawkbit.dev.example.com/default/controller/v1/{device-id}/softwaremodules/{artifact-id}/artifacts/hawkbit_updated_5.swu --output outputfile
```
## DMF API
Authentication is provided by _RabbitMQ_ [vhost and user credentials](https://www.rabbitmq.com/access-control.html) that is used for the integration.
## Management API
- Basic Auth
## Management UI
- Login Dialog
- OpenID Connect

View File

@@ -0,0 +1,98 @@
---
title: Authorization
parent: Concepts
weight: 52
---
Authorization is handled separately for _Direct Device Integration (DDI) API_ and _Device Management Federation (DMF) API_ (where successful authentication includes full authorization) and _Management API_ and _UI_ which is based on Spring security [authorities](https://github.com/eclipse/hawkbit/blob/master/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java).
<!--more-->
However, keep in mind that hawkBit does not offer an off the shelf authentication provider to leverage these permissions and the underlying multi user/tenant capabilities of hawkBit but it supports authentication providers offering an OpenID Connect interface. Check out [Spring security documentation](http://projects.spring.io/spring-security/) for further information. In hawkBit [SecurityAutoConfiguration](https://github.com/eclipse/hawkbit/blob/master/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityAutoConfiguration.java) is a good starting point for integration.
The default implementation is single user/tenant with basic auth and the logged in user is provided with all permissions. Additionally, the application properties may be configured for multiple static users; see [Multiple Users](#multiple-users) for details.
## DDI API
An authenticated target is permitted to:
- retrieve commands from the server
- provide feedback to the the server
- download artifacts that are assigned to it
A target might be permitted to download artifacts without authentication (if enabled, see above). Only the download can be permitted to disable the authentication. This can be used in scenarios where the artifacts itself are e.g. signed and secured.
## Management API and UI
### Multiple Users
hawkBit optionally supports configuring multiple static users through the application properties. In this case, the user and password Spring security properties are ignored.
An example configuration is given below.
hawkbit.server.im.users[0].username=admin
hawkbit.server.im.users[0].password={noop}admin
hawkbit.server.im.users[0].firstname=Test
hawkbit.server.im.users[0].lastname=Admin
hawkbit.server.im.users[0].email=admin@test.de
hawkbit.server.im.users[0].permissions=ALL
hawkbit.server.im.users[1].username=test
hawkbit.server.im.users[1].password={noop}test
hawkbit.server.im.users[1].firstname=Test
hawkbit.server.im.users[1].lastname=Tester
hawkbit.server.im.users[1].email=test@tester.com
hawkbit.server.im.users[1].permissions=READ_TARGET,UPDATE_TARGET,CREATE_TARGET,DELETE_TARGET
A permissions value of `ALL` will provide that user with all possible permissions. Passwords need to be specified with the used password encoder in brackets. In this example, `noop` is used as the plaintext encoder. For production use, it is recommended to use a hash function designed for passwords such as *bcrypt*. See this [blog post](https://spring.io/blog/2017/11/01/spring-security-5-0-0-rc1-released#password-storage-format) for more information on password encoders in Spring Security.
### OpenID Connect
hawkbit supports authentication providers which use the OpenID Connect standard, an authentication layer built on top of the OAuth 2.0 protocol.
An example configuration is given below.
spring.security.oauth2.client.registration.oidc.client-id=clientID
spring.security.oauth2.client.provider.oidc.issuer-uri=https://oidc-provider/issuer-uri
spring.security.oauth2.client.provider.oidc.jwk-set-uri=https://oidc-provider/jwk-set-uri
Note: at the moment only DEFAULT tenant is supported. By default the resource_access/<client id>/roles claim is mapped to hawkBit permissions. However, by registering a Spring bean _org.eclipse.hawkbit.autoconfigure.security.OidcUserManagementAutoConfiguration.JwtAuthoritiesExtractor_ a custom extractor permission mapper could be registered.
### Delivered Permissions
- READ_/UPDATE_/CREATE_/DELETE_TARGET for:
- Target entities including metadata (that includes also the installed and assigned distribution sets)
- Target tags
- Target actions
- Target registration rules
- Bulk operations
- Target filters
- READ_/UPDATE_/CREATE_/DELETE_REPOSITORY for:
- Distribution sets
- Software Modules
- Artifacts
- DS tags
- READ_TARGET_SECURITY_TOKEN
- Permission to read the target security token. The security token is security concerned and should be protected.
- DOWNLOAD_REPOSITORY_ARTIFACT
- Permission to download artifacts of a software module (Note: READ_REPOSITORY allows only to read the metadata).
- TENANT_CONFIGURATION
- Permission to administrate the tenant settings.
- READ_/UPDATE_/CREATE_/DELETE_/HANDLE_/APPROVE_ROLLOUT for:
- Managing rollouts and provision targets through a rollout.
### Permission Matrix for example uses cases that need more than one permission
| Use Case | Needed permissions |
|----------------------------------------------------------------------------|----------------------------------------------------------------------------|
| Search _targets_ by installed or assigned _distribution set_ | READ_REPOSITORY, READ_TARGET |
| Assign _DS_ to a _target_ | READ_REPOSITORY, UPDATE_TARGET |
| Assign DS to target through a _Rollout_, i.e. _Rollout_ creation and start | READ_REPOSITORY, READ_TARGET, READ_ROLLOUT, CREATE_ROLLOUT, HANDLE_ROLLOUT |
| Read _Rollout_ status including its _deployment groups_ | READ_REPOSITORY, READ_ROLLOUT |
| Checks _targets_ inside _Rollout deployment group_ | READ_REPOSITORY, READ_TARGET, READ_ROLLOUT |
## Device Management Federation API
The provided _RabbitMQ_ [vhost and user](https://www.rabbitmq.com/access-control.html) should be provided with the necessary permissions to send messages to hawkBit through the exchange and receive messages from it through the specified queue.

View File

@@ -0,0 +1,50 @@
---
title: Data Model
parent: Concepts
weight: 53
---
The hawkBit data model was designed to have enough flexibility to define complex software structures (e.g. operating system, runtimes, apps, different kind of artifacts) on one side and simplicity compared to the capabilities of a full blown configuration management on the other.
<!--more-->
It does define a hierarchy of software that starts with a distribution, which can have (sub-)modules and these may have multiple artifacts. However, it does not consider any kind of dependency definitions between modules or artifacts. As a result, dependency checks - if necessary - have to be done outside hawkBit, i.e. on the device itself or before the entity creation in hawkBit by the origin.
## Provisioning Target Definition
A Provisioning Target is a neutral definition that may be an actual real device (e.g. gateway, embedded sensor) or a virtual device (e.g. vehicle, smart home).
The definition in hawkBit might reflect the transactional behavior if necessary on the device side. A vehicle might be updated device by device or as a whole. As a result one way of defining a vehicle in hawkBit could be to have one all inclusive Software Module or one module per (sub-) device.
A Target can have, next to its defined properties (e.g. controller ID, target type, name, description, security token), a generic set of attributes and meta data, both in key:value format. Target attributes are owned and managed by the device whereas target meta data are managed by the operator. If a target is defined to be of a certain target type, then during the assignment of a distribution set, a compatibility check will be performed between the target type and distribution set type.
## Software Structure Definition
The structure defines the model of the supported software by the provisioning target
- Distribution Set Type:defines a package structure that is supported by certain devices
- Consists of Software Module Types both for
- Firmware - device can have only one module of that type (e.g. the operating system)
- Software - device can have multiple modules of that type (e.g. "Apps")
Software Content Definition:
- Distribution Set: can be deployed to a provisioning target
- Software Module: is a sub element of the distribution, e.g. OS, application, firmware X, firmware Y
- Artifact: binaries for a software module. Note: the decision which artifacts have to be downloaded are done on the device side, e.g. Full package, signatures, binary deltas
## Entity Relationships
The public defined entities and their relation which are reflected by the Management API.
## Deleting and Archiving Software Modules
When a user deletes a Software Module, the update server cannot simply remove all the corresponding data. Because when the Software Module is already assigned to a Distribution Set or was assigned to a Target in the past, the hawkBit server has to make sure that remains a clean and full update history for every target. The history contains all information (e.g. name, version) of the software, which was assigned to a specific Target. Obviously storing the binary data of the artifacts is not necessary for the history purpose.
The delete process which is performed, when there are historical connections to targets is called SoftDelete. This process marks the Software Module as deleted and removes the artifact, but it won't delete the meta data, which describes the SoftwareModule and the associated Artifacts. SoftwareModules, which are marked as delete won't be visible for the user, when he is requesting all SoftwareModules.
Just in case there are no connections to Distribution Sets and targets the server will perform a HardDelete. This process deletes all stored data, including all meta information.
{{% note %}}
In case of of a SoftDelete the unique constraints are still in place, i.e. you cannot create an entity with the same name/key. This constraint might be removed in future versions because of the impact on the user experience (i.e. he does not see the soft deleted module but cannot create a new one).
{{% /note %}}

View File

@@ -0,0 +1,77 @@
---
title: Rollout Management
parent: Concepts
weight: 54
---
Software update operations in large scale IoT scenarios with hundreds of thousands of devices require special handling.
<!--more-->
That includes:
- _Technical Scalability_ by means of horizontal scale of the hawkBit server cluster in the cloud.
- _Global_ artifact _content delivery_ capacities.
- _Functional Scalability_ by means of:
- Secure handling of large volumes of devices at rollout creation time.
- Monitoring of the rollout progress.
- Emergency rollout shutdown in case of problems on to many devices.
- Reporting capabilities for a complete understanding of the rollout progress at each point in time.
Eclipse hawkBit sees these capabilities under the term Rollout Management.
The following capabilities are currently supported by the _Rollout Management_:
- Create, update and start of rollouts.
- Selection of targets as input for the rollout based on _target filter_ functionality.
- Selection of a _DistributionSet_.
- Auto-splitting of the input target list into a defined number deployment groups.
- Approval workflow
- Has to be enabled explicitly in configuration.
- Enables a workflow that requires a user with adequate permissions to review any new or updated rollout before it
can be started.
- Allows integration with 3rd party workflow engines.
- Cascading start of the deployment groups based on installation status of the previous group.
- Emergency shutdown of the rollout in case a group exceeds the defined error threshold.
- Rollout progress monitoring for the entire rollout and the individual groups.
## Cascading Deployment Group Execution
The cascading execution of the deployment groups is based on two thresholds that can be defined by the rollout creator.
- success condition by means of percentage of successfully installed targets in the current groups triggers.
- error condition by means of absolute or percentage of failed installations which triggers an emergency shutdown of the entire rollout.
## Rollout state machine
### State Machine on Rollout
![](../../images/rolloutstatediagram.png)
### State Machine on Rollout Deployment Group
![](../../images/rolloutgroupstatediagram.png)
## Multi-Assignments (beta)
One of the main paradigms of Eclipse hawkBit is, that a Distribution Set represents the currently installed software of a device. Hence, a device can have only one Distribution Set assigned/installed at a time. With _Multi-Assignments_ enabled, this paradigm shifts. Multi-Assignments allows to assign multiple Distribution Sets to a device simultaneously, without cancelling each other. As a consequence, an operator can trigger multiple campaigns addressing the same devices in parallel.
### Action weight
To differentiate between important and less important updates a property called _weight_ is used. When multi-assignments is enabled every action has a weight value between (and including) 0 and 1000. The higher the weight the more important is the assignment represented by the action. Also when defining a _rollout_ or an _auto-assignment_ and multi-assignments is enabled a weight value has to be provided. This value is passed to the actions created during the execution of these _rollouts_ and _auto-assignments_. If no weight was provided the highest value of 1000 is used instead.
### Consequences
While this feature provides more flexibility to the user and enables new use-cases, there are also some consequences one should be aware of:
**Critical**
* This feature is in beta and may change unannounced.
* For now, this feature is **opt-in only**. Once activated, it cannot be deactivated.
**Minor**
* While on DMF-API a MULTI_ACTION request is sent, DDI-API only exposes the next action which has the highest priority in the list of open actions(according to their weight property).
* All information regarding the currently assigned or installed Distribution Set does only respect the last assignment, as well as the last successfully installed Distribution set. This also affects:
* Pinning a target or Distribution Set in Deployment View.
* Statistics about installed or assigned Distribution Sets.
* Auto close running actions, when a new Distribution Set is assigned (`repository.actions.autoclose.enabled`) is deactivated.
* Marking a Distribution Set to be a *Required Migration Step* is deactivated.

View File

@@ -0,0 +1,21 @@
---
title: Target State Machine
parent: Concepts
weight: 55
---
A target has a current state which reflects the provisioning status of the device at this point in time. State changes are driven either by the update server by means of starting an update or by the controller on the provisioning target that gives feedback to the update server, e.g. "I am here", "I am working on a provisioning", "I have finished a provisioning".
<!--more-->
## Defined states
| State | Description |
|------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| UNKNOWN | Set by default for a pre-commissioned target until first status update received from the target. Is the initial starting point for targets created by UI or management API. |
| IN_SYNC | Assigned _Distribution Set_ is installed. |
| PENDING | Installation of assigned _Distribution Set_ is not yet confirmed. |
| ERROR | Installation of assigned _Distribution Set_ has failed. |
| REGISTERED | Target registered at the update server but no _Distribution Set_ assigned. Is the initial starting point for plug-and-play devices. |
## Transitions
![](../../images/architecture/targetStatusStates.png)