Skip to content

Instantly share code, notes, and snippets.

@reubenmiller
Last active March 6, 2026 13:45
Show Gist options
  • Select an option

  • Save reubenmiller/620c0f078edabebc3065069d206babf0 to your computer and use it in GitHub Desktop.

Select an option

Save reubenmiller/620c0f078edabebc3065069d206babf0 to your computer and use it in GitHub Desktop.
Cumulocity instructions on how to connect a device to the MQTT Service

Registering a device in Cumulocity

The following instructions detail how to connect to Cumulocity and the MQTT Service (i.e. port 9883) from a device.

Pre-requisites

The following pre-requisites are

On macOS (using brew)

You can install the required dependencies using homebrew

brew install bash openssl curl mosquitto

See the go-c8y-cli installation guide for installing go-c8y-cli.

Using a Cumulocity Device User with Basic Authentication

  1. Set a device id (this will be the c8y_Serial external id used to reference the device)

    DEVICE_ID=$(c8y template execute --template "'example_' + _.Char(10)")

    The above command just generates a randomized value for you, but you can change it to a fixed value if you want. Though we would recommend to sticking to the character set: [A-Za-z0-9_-].

  2. Register the device

    eval "$(c8y deviceregistration register-basic \
        --id "$DEVICE_ID" \
        --outputTemplate " 
            'export DEVICE_USER=%s\nexport DEVICE_PASSWORD=%s' % [
                std.escapeStringBash(output.username),
                std.escapeStringBash(output.password)
            ]
        "
    )"

    The command will use a randomized password and it will set the value (via the eval command) so that it can be referenced in following commands.

  3. Use an MQTT client to publish to a custom topic on the Cumulocity MQTT service

    mosquitto_pub \
        -h "$C8Y_DOMAIN" \
        -p 9883 \
        --debug \
        -i "$DEVICE_ID" \
        -u "$DEVICE_USER" \
        -P "$DEVICE_PASSWORD" \
        --cafile /opt/homebrew/etc/ca-certificates/cert.pem \
        -t foo \
        -m bar \
        -q 1

    Note: On macOS, the --cafile argument MUST be set otherwise the connection will fail (as the mosquitto_sub won't be able to establish trust with the Cumulocity endpoint). On other platforms, you might be able to leave out the --cafile, or direct it to the OS's ca file, e.g. on Linux this is typically, --cafile /etc/ssl/certs/ca-certificates.crt.

    Client example_UqCXbGBXHS sending CONNECT
    Client example_UqCXbGBXHS received CONNACK (0)
    Client example_UqCXbGBXHS sending PUBLISH (d0, q1, r0, m1, 'foo', ... (3 bytes))
    Client example_UqCXbGBXHS received PUBACK (Mid: 1, RC:0)
    Client example_UqCXbGBXHS sending DISCONNECT
    

Using a Cumulocity Device User with a Cumulocity CA Issued certificate

Using openssl and curl

  1. Set a device id (this will be the c8y_Serial external id used to reference the device)

    DEVICE_ID=$(c8y template execute --template "'example_' + _.Char(10)")

    The above command just generates a randomized value for you, but you can change it to a fixed value if you want. Though we would recommend to sticking to the character set: [A-Za-z0-9_-].

  2. Create a private key and CSR

    openssl req -new -newkey ec \
        -pkeyopt ec_paramgen_curve:prime256v1 \
        -nodes \
        -keyout "${DEVICE_ID}.key" \
        -out "${DEVICE_ID}.csr" \
        -subj "/C=US/ST=California/L=SanFrancisco/O=ExampleCorp/OU=IT/CN=$DEVICE_ID"

    Note: You can change the key algorithm and subject string as you with

  3. Register the device with Cumulocity

    eval "$(
        c8y deviceregistration register-ca \
            --id "$DEVICE_ID" \
            --outputTemplate "'export ONE_TIME_PASSWORD=%s' % std.escapeStringBash(output.password)"
    )"

    The command will use a randomized one-time password and it will set the value (via the eval command) so that it can be referenced in following commands.

    Alternatively, you can register the device in the Cumulocity Device Management Application, where you'll need to print out the following variables in order to input them into the registration form in the UI:

    • echo $DEVICE_ID - External ID
    • echo $ONE_TIME_PASSWORD - one-time password

    Note: A device managed object is created at this step, however the device user will not.

  4. Download the certificate using the device's one-time password

    curl \
        -f \
        -XPOST \
        --user "${DEVICE_ID}:${ONE_TIME_PASSWORD}" \
        -H "Content-Type: application/pkcs10" \
        -H "Content-Transfer-Encoding: base64" \
        -H "Accept: application/pkcs10" \
        --data-binary "@${DEVICE_ID}.csr" \
        "https://$C8Y_DOMAIN/.well-known/est/simpleenroll" > "${DEVICE_ID}.crt"

    You can inspect the contents of the certificate using:

    openssl x509 -in "${DEVICE_ID}.crt" -text -noout

    Example output

    Certificate:
        Data:
            Version: 3 (0x2)
            Serial Number: 1772700590664 (0x19cbd306248)
            Signature Algorithm: ecdsa-with-SHA256
            Issuer: C=United States, O=Cumulocity, CN=t123445
            Validity
                Not Before: Mar  5 08:49:50 2026 GMT
                Not After : Mar  5 08:49:50 2027 GMT
            Subject: C=US, ST=California, L=SanFrancisco, O=ExampleCorp, OU=IT, CN=example_abcdef
            Subject Public Key Info:
                Public Key Algorithm: id-ecPublicKey
                    Public-Key: (256 bit)
                    pub:
                        04:5b:c2:95:6c:45:50:1b:28:a2:9d:86:fa:ce:85:
                        d4:ea:70:ff:d5:1d:fe:25:8c:a3:7e:f9:8f:19:f1:
                        b6:39:96:80:18:f7:d0:0d:96:ea:67:8c:49:7e:48:
                        12:56:82:f0:e7:7b:63:e3:63:fc:23:46:f2:d5:0f:
                        87:82:7f:6c:da
                    ASN1 OID: prime256v1
                    NIST CURVE: P-256
        Signature Algorithm: ecdsa-with-SHA256
        Signature Value:
            30:45:02:21:00:e2:1b:3b:b3:4e:8e:e6:b4:82:97:a7:da:e3:
            84:42:22:b3:17:57:ce:03:3a:58:a3:e6:31:39:a8:8d:a4:3c:
            5e:02:20:1d:45:47:69:1d:67:ad:84:ce:26:97:a5:f7:e3:8f:
            32:cd:6b:ba:ec:54:56:bb:8c:5a:70:0d:43:5c:d1:9a:52
    
  5. Use an MQTT client to publish to a custom topic on the Cumulocity MQTT service

    mosquitto_pub \
        -h "$C8Y_DOMAIN" \
        -p 9883 \
        --debug \
        -i "$DEVICE_ID" \
        --key "${DEVICE_ID}.key" \
        --cert "${DEVICE_ID}.crt" \
        --cafile /opt/homebrew/etc/ca-certificates/cert.pem \
        -t foo \
        -m bar \
        -q 1

    Note: On macOS, the --cafile argument MUST be set otherwise the connection will fail (as the mosquitto_sub won't be able to establish trust with the Cumulocity endpoint). On other platforms, you might be able to leave out the --cafile, or direct it to the OS's ca file, e.g. on Linux this is typically, --cafile /etc/ssl/certs/ca-certificates.crt.

    Expected output

    Client example_UqCXbGBXHS sending CONNECT
    Client example_UqCXbGBXHS received CONNACK (0)
    Client example_UqCXbGBXHS sending PUBLISH (d0, q1, r0, m1, 'foo', ... (3 bytes))
    Client example_UqCXbGBXHS received PUBACK (Mid: 1, RC:0)
    Client example_UqCXbGBXHS sending DISCONNECT
    

Using go-c8y-cli

  1. Set a device id (this will be the c8y_Serial external id used to reference the device)

    DEVICE_ID=$(c8y template execute --template "'example_' + _.Char(10)")

    The above command just generates a randomized value for you, but you can change it to a fixed value if you want. Though we would recommend to sticking to the character set: [A-Za-z0-9_-].

  2. Enroll a device using the Cumulocity CA EST endpoint

    c8y devices enroll --id "$DEVICE_ID"

    Note: A device managed object is created at this step, however the device user will not.

  3. Use an MQTT client to publish to a custom topic on the Cumulocity MQTT service

    mosquitto_pub \
        -h "$C8Y_DOMAIN" \
        -p 9883 \
        --debug \
        -i "$DEVICE_ID" \
        --key "${DEVICE_ID}.key" \
        --cert "${DEVICE_ID}.crt" \
        --cafile /opt/homebrew/etc/ca-certificates/cert.pem \
        -t foo \
        -m bar \
        -q 1

    Note: On macOS, the --cafile argument MUST be set otherwise the connection will fail (as the mosquitto_sub won't be able to establish trust with the Cumulocity endpoint). On other platforms, you might be able to leave out the --cafile, or direct it to the OS's ca file, e.g. on Linux this is typically, --cafile /etc/ssl/certs/ca-certificates.crt.

    Expected output

    Client example_UqCXbGBXHS sending CONNECT
    Client example_UqCXbGBXHS received CONNACK (0)
    Client example_UqCXbGBXHS sending PUBLISH (d0, q1, r0, m1, 'foo', ... (3 bytes))
    Client example_UqCXbGBXHS received PUBACK (Mid: 1, RC:0)
    Client example_UqCXbGBXHS sending DISCONNECT
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment