The Thing SDK enables a thing, which can be either a physical device or a software service, to register and authenticate without human interaction. Once registered, the thing will be represented by a digital identity in the ForgeRock Identity Platform and can authenticate itself in order to interact with the platform tier. The Thing SDK can communicate directly with the platform using HTTP(S) or via the Thing Gateway using CoAP(S).
The Thing Gateway is an application that enables more constrained devices to interact with the ForgeRock Identity Platform by acting as a proxy between a thing and the Platform.
This section covers the tasks you need to quickly get a test or demo environment running. It will guide you through configuring ForgeRock Access Management (AM) and running the Thing SDK and Gateway examples.
The Thing SDK and Gateway has been developed in the Go programming language and to run the examples you require Go 1.13 or later.
You also require Git for downloading the source code and running the examples.
Clone this repository:
git clone git@github.com:ForgeRock/iot-edge.git
This will create a directory named iot-edge
. The instructions for running the examples will assume this as your
current directory:
cd iot-edge
The examples require AM to be installed with a fully qualified domain name of am.localtest.me
, using port 8080
.
Follow the AM Evaluation Guide to quickly set up an instance.
Log in to AM and go to Services:
- Add the IoT Service
- Select Create OAuth 2.0 Client and Create OAuth 2.0 JWT Issuer
- Save Changes
- Add the OAuth2 Provider service
Go to the IoT OAuth 2.0 Client:
- Add
publish
to Scope(s) - Save Changes
Create an authentication tree called auth-tree
:
Create a second authentication tree called reg-tree
and enable Create Identity for the Register Thing node:
Go to the default keystore mappings
and add the mapping: Secret ID: am.services.iot.cert.verification
, Alias: es256test
. The CA certificate used in
this example is one of the test certificates (es256test) that AM includes by default. This mapping tells the
Register Thing node what key to use when verifying the registration certificate.
This example will authenticate and request an access token for the thing. It requires the thing to be in possession of an asymmetric key pair for signing.
Before running the example, register the thing manually using manual-thing
as
the thing's ID.
Run the example:
./run.sh example "thing/simple" \
-name "manual-thing" \
-url "http://am.localtest.me:8080/am" \
-audience "/" \
-realm "/" \
-tree "auth-tree" \
-keyfile "./examples/resources/eckey1.key.pem"
This example will create a new identity, authenticate and request an access token for the thing. It requires the thing to be in possession of an asymmetric key pair for signing, and a CA signed X.509 certificate containing the key pair's public key.
Run the example:
./run.sh example "thing/cert-registration" \
-name "dynamic-thing" \
-url "http://am.localtest.me:8080/am" \
-audience "/" \
-realm "/" \
-tree "reg-tree" \
-keyfile "./examples/resources/eckey1.key.pem" \
-certfile "./examples/resources/dynamic-thing.cert.pem"
The Thing Gateway has its own identity in AM, which similar to a Thing, can be manually or dynamically registered. When manually registered, the gateway requires an asymmetric key pair for signing. When dynamically registered, the gateway requires an asymmetric key pair for signing, and a CA signed X.509 certificate containing the key pair's public key.
This example will start the gateway and authenticate it.
Before running the example, register the gateway manually using manual-gateway
as the gateway's ID.
Run the gateway:
./run.sh gateway \
--name "manual-gateway" \
--url "http://am.localtest.me:8080/am" \
--audience "/" \
--realm "/" \
--tree "auth-tree" \
--kid "pop.cnf" \
--key "./examples/resources/eckey1.key.pem" \
--address ":5683" \
-d
The message Thing Gateway server started
will appear if the manual-gateway
has started up and authenticated itself
successfully.
In a different terminal window, connect a thing to the gateway.
To stop the gateway process, press Ctrl+C
in the window where the process is running.
This example will start the gateway, register and authenticate it.
Run the gateway:
./run.sh gateway \
--name "dynamic-gateway" \
--url "http://am.localtest.me:8080/am" \
--audience "/" \
--realm "/" \
--tree "reg-tree" \
--key "./examples/resources/eckey1.key.pem" \
--cert "./examples/resources/dynamic-gateway.cert.pem" \
--address ":5683" \
-d
The message Thing Gateway server started
will appear if the gateway has started up, registered and authenticated
itself successfully.
In a different terminal window, connect a thing to the gateway.
To stop the gateway process, press Ctrl+C
in the window where the process is running.
This example will connect a thing to the Thing Gateway. Once the thing has connected it will authenticate and request an access token.
Before running the example, register the thing manually using gateway-thing
as the thing's ID.
Run the SDK example to connect the thing to the gateway:
./run.sh example "thing/simple" \
-name "gateway-thing" \
-url "coap://:5683" \
-keyfile "./examples/resources/eckey1.key.pem"
Use curl and AM's REST endpoints to manually register an identity for a thing or the gateway.
Get an admin SSO token:
curl --request POST 'http://am.localtest.me:8080/am/json/authenticate' \
--header 'Content-Type: application/json' \
--header 'X-OpenAM-Username: amAdmin' \
--header 'X-OpenAM-Password: changeit' \
--header 'Accept-API-Version: resource=2.0, protocol=1.0'
Save the tokenId
received from this request to a variable:
tokenId="5oXAB6....lMxAAA.*"
Set the ID of the identity to register. Change the value as specified in the example's instructions:
ID=thing-or-gateway
Register an identity for a thing:
curl -v --request PUT "http://am.localtest.me:8080/am/json/realms/root/users/${ID}" \
--header 'Content-Type: application/json' \
--header 'Accept-Api-Version: resource=4.0, protocol=2.1' \
--cookie "iPlanetDirectoryPro=${tokenId}" \
--data '{
"userPassword": "5tr0ngG3n3r@ted",
"thingType": "device",
"thingKeys": "{\"keys\":[{\"use\":\"sig\",\"kty\":\"EC\",\"kid\":\"pop.cnf\",\"crv\":\"P-256\",\"alg\":\"ES256\",\"x\":\"wjC9kMzwIeXNn6lsjdqplcq9aCWpAOZ0af1_yruCcJ4\",\"y\":\"ihIziCymBnU8W8m5zx69DsQr0sWDiXsDMq04lBmfEHw\"}]}"
}'
Register an identity for the gateway:
curl -v --request PUT "http://am.localtest.me:8080/am/json/realms/root/users/${ID}" \
--header 'Content-Type: application/json' \
--header 'Accept-Api-Version: resource=4.0, protocol=2.1' \
--cookie "iPlanetDirectoryPro=${tokenId}" \
--data '{
"userPassword": "5tr0ngG3n3r@ted",
"thingType": "gateway",
"thingKeys": "{\"keys\":[{\"use\":\"sig\",\"kty\":\"EC\",\"kid\":\"pop.cnf\",\"crv\":\"P-256\",\"alg\":\"ES256\",\"x\":\"wjC9kMzwIeXNn6lsjdqplcq9aCWpAOZ0af1_yruCcJ4\",\"y\":\"ihIziCymBnU8W8m5zx69DsQr0sWDiXsDMq04lBmfEHw\"}]}"
}'