RAUC usage example¶
This example shows how to create a product which enables RAUC signing. Also example signing operation is performed and the result is also verified.
This example uses the reference python client and the UI to perform different actions.
The example is divided to following stages:
- How to get authentication token
- Adding certificate profiles
- Creating product
- Signing RAUC bundles
- Verifying RAUC bundle
Authentication¶
In order to use the reference python client a valid JWT token is needed. How to obtain one is explained in more detail in the authentication chapter. New token must be requested if the current token expires. ( roughly 1 hour of validity)
(venv) $ az login --allow-no-subscriptions --only-show-error
A web browser has been opened at https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize. Please continue the login in the web browser. If no web browser is available or if the web browser fails to open, use device code flow with `az login --use-device-code`.
[1] N/A(tenant level account) <redacted> <redacted>
The default is marked with an *; the default tenant is '<redacted>' and subscription is 'N/A(tenant level account)' (<redacted>).
Select a subscription and tenant (Type a number or Enter for no changes): 1
Tenant: <redacted>
Subscription: N/A(tenant level account) (<redacted>)
(venv) $ az account get-access-token --resource api://<redacted>
{
"accessToken": "<redacted>",
"expiresOn": "2025-06-04 15:18:10.000000",
"expires_on": 1749039490,
"subscription": "<redacted>",
"tenant": "<redacted>",
"tokenType": "Bearer"
}
(venv) $ export TOKEN=<redacted>
Add profiles¶
RAUC signing is using a Certificate authority which is used as a trustpoint in the devices and a Code signing End-Entity issued under that CA to signing the RAUC bundles.
The example profiles were taken as base and modified for this example
(venv) $ ./signing-tool.py -c -t $TOKEN \
-a https://app.laavat.io/<CustomerName>/api/v1/ profile add \
-F rootca.yaml -N "Customer Root CA" -T ROOT
{
"id": "321c7960-ec34-459d-bc5c-ee2399633922",
"profile_name": "Customer Root C",
"profile_type": 3,
"profile_yaml": "IyBDb25maWcgZmlsZSBmb3IgdGhlIFJvb3QgcHJvZmlsZS4gRG8gbm90IHVzZSBUQUJTCi0tLQpOYW1lOiBHZW5lcmljIFJvb3QgQ0EKIyBEaXN0aW5ndWlzaGVkIG5hbWUgb2YgdGhlIENBCkROOgogICMgT3JnYW5pemF0aW9uOiAKICAjIE9yZ2FuaXphdGlvbmFsVW5pdDogCiAgQ291bnRyeTogRkkKICAjIFByb3ZpbmNlOgogICMgTG9jYWxpdHk6CiAgIyBTdHJlZXRBZGRyZXNzOgogICMgUG9zdGFsQ29kZToKICAjIFNlcmlhbE51bWJlcgogICMgQ29tbW9uTmFtZTogR2VuZXJpYyBSb290IENBCiMgRW5kRW50aXR5IGlzIDEsIFN1YiBDQSBwcm9maWxlIDIgLCBSb290IHByb2ZpbGUgMwpQcm9maWxlVHlwZTogMwojIFNpZ25hdHVyZUFsZ29yaXRobXMKIyAgU0hBMVdpdGhSU0EgPSAzCiMgIFNIQTI1NldpdGhSU0EgPSA0CiMgIFNIQTM4NFdpdGhSU0EgPSA1CiMgIFNIQTUxMldpdGhSU0EgPSA2CiMgIERTQVdpdGhTSEExID0gNwojICBEU0FXaXRoU0hBMjU2ID0gOAojICBFQ0RTQVdpdGhTSEExID0gOQojICBFQ0RTQVdpdGhTSEEyNTYgPSAxMAojICBFQ0RTQVdpdGhTSEEzODQgPSAxMQojICBFQ0RTQVdpdGhTSEE1MTIgPSAxMgojICBTSEEyNTZXaXRoUlNBUFNTID0gMTMKIyAgU0hBMzg0V2l0aFJTQVBTUyA9IDE0CiMgIFNIQTUxMldpdGhSU0FQU1MgPSAxNQpTaWduYXR1cmVBbGdvcml0aG06IDQKIyBLZXlBbGdvcml0aG1zCiMgICBSU0FBbGdvcml0aG0gPSAxCiMgICBFQ0RTQUFsZ29yaXRobSA9IDIKS2V5QWxnb3JpdGhtOiAxCiMgVmFsaWRpdHkgb2YgdGhlIGNlcnRpZmljYXRlIGluIGR1cmF0aW9uIChtYXggMjkwIHllYXJzKSBvciB3aXRoIGFic29sdXRlIGRhdGUgaW4gUkZDMzMzOSBlLmcuIDk5OTktMTItMzFUMjM6NTk6NTlaLgojIEV4YW1wbGUgaW4gYWJzb2x1dGUgZGF0ZSAiOTk5OS0xMi0zMVQyMzo1OTo1OVoiLgojIEV4YW1wbGUgaW4gZHVyYXRpb24gIjFoMTBtMTBzIi4gT25seSBoLCBtIGFuZC9vciBzIGFyZSBhY2NlcHRlZC4KVmFsaWRpdHlQZXJpb2Q6ICIxNzUyMDAwaCIgIyAyMDAgWWVhcnMKQmFzaWNDb25zdHJhaW50czoKICBCYXNpY0NvbnN0cmFpbnRzVmFsaWQ6IHRydWUKICBJc0NBOiB0cnVlCiAgTWF4UGF0aExlbjogMgogICMgTWF4UGF0aExlblplcm8gaW5kaWNhdGVzIHRoYXQgQmFzaWNDb25zdHJhaW50c1ZhbGlkPT10cnVlCiAgIyBhbmQgTWF4UGF0aExlbj09MCBzaG91bGQgYmUgaW50ZXJwcmV0ZWQgYXMgYW4gYWN0dWFsCiAgIyBtYXhpbXVtIHBhdGggbGVuZ3RoIG9mIHplcm8uIE90aGVyd2lzZSwgdGhhdCBjb21iaW5hdGlvbiBpcwogICMgaW50ZXJwcmV0ZWQgYXMgTWF4UGF0aExlbiBub3QgYmVpbmcgc2V0LgogIE1heFBhdGhMZW5aZXJvOiBmYWxzZQpBZGRTS0k6IHRydWUKQWRkQUtJOiB0cnVlCiMgS2V5VXNhZ2VzCiMgIEtleVVzYWdlRGlnaXRhbFNpZ25hdHVyZSA9IDEKIyAgS2V5VXNhZ2VDb250ZW50Q29tbWl0bWVudCA9IDIKIyAgS2V5VXNhZ2VLZXlFbmNpcGhlcm1lbnQgPSA0CiMgIEtleVVzYWdlRGF0YUVuY2lwaGVybWVudCA9IDgKIyAgS2V5VXNhZ2VLZXlBZ3JlZW1lbnQgPSAxNgojICBLZXlVc2FnZUNlcnRTaWduID0gMzIgCiMgIEtleVVzYWdlQ1JMU2lnbiA9IDY0CiMgIEtleVVzYWdlRW5jaXBoZXJPbmx5ID0gMTI4CiMgIEtleVVzYWdlRGVjaXBoZXJPbmx5ID0gMjU2CktleVVzYWdlOgogIC0gMQogIC0gMzIKICAtIDY0CkV4dGVuZGVkS2V5VXNhZ2U6CiAgIyBFeHRlbmRlZEtleVVzYWdlcwogICMgIEV4dEtleVVzYWdlQW55ID0gMAogICMgIEV4dEtleVVzYWdlU2VydmVyQXV0aCA9IDEKICAjICBFeHRLZXlVc2FnZUNsaWVudEF1dGggPSAyCiAgIyAgRXh0S2V5VXNhZ2VDb2RlU2lnbmluZyA9IDMKICAjICBFeHRLZXlVc2FnZUVtYWlsUHJvdGVjdGlvbiA9IDQKICAjICBFeHRLZXlVc2FnZUlQU0VDRW5kU3lzdGVtID0gNQogICMgIEV4dEtleVVzYWdlSVBTRUNUdW5uZWwgPSA2CiAgIyAgRXh0S2V5VXNhZ2VJUFNFQ1VzZXIgPSA3CiAgIyAgRXh0S2V5VXNhZ2VUaW1lU3RhbXBpbmcgPSA4CiAgIyAgRXh0S2V5VXNhZ2VPQ1NQU2lnbmluZyA9IDkKICAjICBFeHRLZXlVc2FnZU1pY3Jvc29mdFNlcnZlckdhdGVkQ3J5cHRvID0gMTAKICAjICBFeHRLZXlVc2FnZU5ldHNjYXBlU2VydmVyR2F0ZWRDcnlwdG8gPSAxMQogICMgIEV4dEtleVVzYWdlTWljcm9zb2Z0Q29tbWVyY2lhbENvZGVTaWduaW5nID0gMTIKICAjICBFeHRLZXlVc2FnZU1pY3Jvc29mdEtlcm5lbENvZGVTaWduaW5nID0gMTMKIyBFeHRyYUV4dGVuc2lvbnM6IHRydWUKIyBTQU5Vc2FnZTogdHJ1ZQojIENSTERpc3RyaWJ1dGlvblBvaW50cy4gTGlzdCBvZiBVUkkgc3RyaW5ncy4KI0NSTERpc3RyaWJ1dGlvblBvaW50czoKCiMgUG9saWN5SWRlbnRpZmllcnMuIExpc3Qgb2YgQVNOMSBwb2xpY3kgT0lEUwojUG9saWN5SWRlbnRpZmllcnM6CiMgIC0gMS4xMC4xMjMuNDMyLjQuNQojICAtIDIuMTAuMTIzLjQzMi40LjY1Cg=="
}
Profile added. Profile ID: 321c7960-ec34-459d-bc5c-ee2399633922
(venv) $ ./signing-tool.py -c -t $TOKEN \
-a https://app.laavat.io/<CustomerName>/api/v1/ profile add \
-F endentity.yaml -N "Customer signing cert" -T END
{
"id": "f30679fb-00cb-4630-b550-1d026d4d63b6",
"profile_name": "Customer signing cert",
"profile_type": 1,
"profile_yaml": "IyBDb25maWcgZmlsZSBmb3IgdGhlIEVuZC1FbnRpdHkgcHJvZmlsZS4gRG8gbm90IHVzZSBUQUJTCi0tLQpOYW1lOiBHZW5lcmljIGNvZGUgc2lnbmluZyBFbmRFbnRpdHkgUHJvZmlsZQpETjoKICBPcmdhbml6YXRpb246IFRlc3QgQ29tcAogICMgT3JnYW5pemF0aW9uYWxVbml0OiBSJkQKICBDb3VudHJ5OiBGSQogICMgUHJvdmluY2U6CiAgIy0gU29tZXRoaW5nCiAgIyBMb2NhbGl0eToKICAjIFN0cmVldEFkZHJlc3M6CiAgIyBQb3N0YWxDb2RlOgogICMgU2VyaWFsTnVtYmVyCiAgIyBDb21tb25OYW1lOiBJTUcKIyBFbmRFbnRpdHkgaXMgMSwgU3ViIENBIHByb2ZpbGUgMiAsIFJvb3QgcHJvZmlsZSAzClByb2ZpbGVUeXBlOiAxCiMgU2lnbmF0dXJlQWxnb3JpdGhtcwojICBTSEExV2l0aFJTQSA9IDMKIyAgU0hBMjU2V2l0aFJTQSA9IDQKIyAgU0hBMzg0V2l0aFJTQSA9IDUKIyAgU0hBNTEyV2l0aFJTQSA9IDYKIyAgRFNBV2l0aFNIQTEgPSA3CiMgIERTQVdpdGhTSEEyNTYgPSA4CiMgIEVDRFNBV2l0aFNIQTEgPSA5CiMgIEVDRFNBV2l0aFNIQTI1NiA9IDEwCiMgIEVDRFNBV2l0aFNIQTM4NCA9IDExCiMgIEVDRFNBV2l0aFNIQTUxMiA9IDEyCiMgIFNIQTI1NldpdGhSU0FQU1MgPSAxMwojICBTSEEzODRXaXRoUlNBUFNTID0gMTQKIyAgU0hBNTEyV2l0aFJTQVBTUyA9IDE1ClNpZ25hdHVyZUFsZ29yaXRobTogNAojIEtleUFsZ29yaXRobXMKIyAgIFJTQUFsZ29yaXRobSA9IDEKIyAgIEVDRFNBQWxnb3JpdGhtID0gMgpLZXlBbGdvcml0aG06IDEKIyBWYWxpZGl0eSBvZiB0aGUgY2VydGlmaWNhdGUgaW4gZHVyYXRpb24gKG1heCAyOTAgeWVhcnMpIG9yIHdpdGggYWJzb2x1dGUgZGF0ZSBpbiBSRkMzMzM5IGUuZy4gOTk5OS0xMi0zMVQyMzo1OTo1OVouCiMgRXhhbXBsZSBpbiBhYnNvbHV0ZSBkYXRlICI5OTk5LTEyLTMxVDIzOjU5OjU5WiIuCiMgRXhhbXBsZSBpbiBkdXJhdGlvbiAiMWgxMG0xMHMiLiBPbmx5IGgsIG0gYW5kL29yIHMgYXJlIGFjY2VwdGVkLgpWYWxpZGl0eVBlcmlvZDogIjE3NTIwMDBoIiAjIDIwMCBZZWFycwpCYXNpY0NvbnN0cmFpbnRzOgogIFVzZTogdHJ1ZQogIElzQ0E6IGZhbHNlCkFkZFNLSTogdHJ1ZQpBZGRBS0k6IHRydWUKIyBLZXlVc2FnZXMKIyAgS2V5VXNhZ2VEaWdpdGFsU2lnbmF0dXJlID0gMQojICBLZXlVc2FnZUNvbnRlbnRDb21taXRtZW50ID0gMgojICBLZXlVc2FnZUtleUVuY2lwaGVybWVudCA9IDQKIyAgS2V5VXNhZ2VEYXRhRW5jaXBoZXJtZW50ID0gOAojICBLZXlVc2FnZUtleUFncmVlbWVudCA9IDE2CiMgIEtleVVzYWdlQ2VydFNpZ24gPSAzMiAKIyAgS2V5VXNhZ2VDUkxTaWduID0gNjQKIyAgS2V5VXNhZ2VFbmNpcGhlck9ubHkgPSAxMjgKIyAgS2V5VXNhZ2VEZWNpcGhlck9ubHkgPSAyNTYKS2V5VXNhZ2U6CiAgLSAxCiAgLSAyCkV4dGVuZGVkS2V5VXNhZ2U6CiAgLSAzCiAgIyBFeHRlbmRlZEtleVVzYWdlcwogICMgIEV4dEtleVVzYWdlQW55ID0gMAogICMgIEV4dEtleVVzYWdlU2VydmVyQXV0aCA9IDEKICAjICBFeHRLZXlVc2FnZUNsaWVudEF1dGggPSAyCiAgIyAgRXh0S2V5VXNhZ2VDb2RlU2lnbmluZyA9IDMKICAjICBFeHRLZXlVc2FnZUVtYWlsUHJvdGVjdGlvbiA9IDQKICAjICBFeHRLZXlVc2FnZUlQU0VDRW5kU3lzdGVtID0gNQogICMgIEV4dEtleVVzYWdlSVBTRUNUdW5uZWwgPSA2CiAgIyAgRXh0S2V5VXNhZ2VJUFNFQ1VzZXIgPSA3CiAgIyAgRXh0S2V5VXNhZ2VUaW1lU3RhbXBpbmcgPSA4CiAgIyAgRXh0S2V5VXNhZ2VPQ1NQU2lnbmluZyA9IDkKICAjICBFeHRLZXlVc2FnZU1pY3Jvc29mdFNlcnZlckdhdGVkQ3J5cHRvID0gMTAKICAjICBFeHRLZXlVc2FnZU5ldHNjYXBlU2VydmVyR2F0ZWRDcnlwdG8gPSAxMQogICMgIEV4dEtleVVzYWdlTWljcm9zb2Z0Q29tbWVyY2lhbENvZGVTaWduaW5nID0gMTIKICAjICBFeHRLZXlVc2FnZU1pY3Jvc29mdEtlcm5lbENvZGVTaWduaW5nID0gMTMKRXh0cmFFeHRlbnNpb25zOiB0cnVlClNBTlVzYWdlOiB0cnVlCiMgQ1JMRGlzdHJpYnV0aW9uUG9pbnRzLiBMaXN0IG9mIFVSSSBzdHJpbmdzLgojQ1JMRGlzdHJpYnV0aW9uUG9pbnRzOgoKIyBQb2xpY3lJZGVudGlmaWVycy4gTGlzdCBvZiBBU04xIHBvbGljeSBPSURTCiNQb2xpY3lJZGVudGlmaWVyczoKIyAgLSAxLjEwLjEyMy40MzIuNC41CiMgIC0gMi4xMC4xMjMuNDMyLjQuNjUKCiMgRW5mb3JjZVVuaXF1ZUROIGVuYWJsZXMgdGhlIGNoZWNraW5nIGlmIGEgY2VydGlmaWNhdGUgaGFzIGJlZW4gaXNzdWVkIHdpdGggdGhlIHNhbWUgc3ViamVjdCBETiBmcm9tIHRoZSBDQQojIFZhbHVlcyB0cnVlIG9yIGZhbHNlCiNFbmZvcmNlVW5pcXVlRE46IHRydWUK"
}
Profile added. Profile ID: f30679fb-00cb-4630-b550-1d026d4d63b6
(venv) $ ./signing-tool.py -c -t $TOKEN \
-a https://app.laavat.io/<CustomerName>/api/v1/ profile getall
{
"count": 2,
"items": [
{
"id": "321c7960-ec34-459d-bc5c-ee2399633922",
"profile_name": "Customer Root CA",
"profile_type": 3
},
{
"id": "f30679fb-00cb-4630-b550-1d026d4d63b6",
"profile_name": "Customer signing cert",
"profile_type": 1
}
],
"next": "/cas/profiles/?page=1",
"pages": 1,
"prev": "/cas/profiles/?page=1"
}
Create product¶
Here is the used product template. The product template was updated with the profile ids obtained from the previous commands. The values $ROOTPROFILEID, $ENDSIGPROFILEID were changed with their corresponding profile id.
- ROOTPROFILEID=321c7960-ec34-459d-bc5c-ee2399633922
- ENDSIGPROFILEID=f30679fb-00cb-4630-b550-1d026d4d63b6
In the approval rule it was decided that entities in the $WRITERGROUP were able to make RAUC signing requests. And entities in the $APPROVERGROUP group would be able to approve those. Autoapproval was not used.
$WRITERGROUP and $APPROVERGROUP were replaced with the corresponding Group Object ID from Microsoft Entra.
The template was saved as product.json.
More information about rules can be found from approval rules.
Product was created using the python tool
(venv) $ ./signing-tool.py -c -t $TOKEN \
-a https://app.laavat.io/<CustomerName>/api/v1/ product add -T product.json
{
"ca_info": [
{
"cert_override_payload": null,
"certificate_type": "SUBCA",
"cn": "CA for One Time Signing certs",
"crl_distribution_points": null,
"crl_expiry": null,
"crl_issue_interval": null,
"csr": null,
"description": "One Time Signing RAUC code signing certs",
"external_request_id": null,
"external_root": null,
"id": null,
"issuer_ca_id": null,
"key_override_id": null,
"key_type": "RSA2048",
"leafs": [],
"originating_id": null,
"policy_identifiers": null,
"product_id": null,
"profile_id": "321c7960-ec34-459d-bc5c-ee2399633922",
"state": null,
"use_case": "RaucCodeSigning"
}
],
"description": "Product for testing RAUC bundle One Time Signing",
"enabled": true,
"external_request_id": null,
"id": null,
"name": "RAUC onetime",
"product_config_items": [],
"product_operations": [
{
"approval_rule": {
"allowed_groups": [
"b716abb1-2e3b-47a9-bca5-a3669faa50a6"
],
"approval_groups": [
"f65a3ea9-60db-47a4-9ad8-c6915735ec5f"
],
"blanket_groups": [],
"description": "Rule used for testing for RAUC onetime",
"name": "Test rule2"
},
"ca_use_case": null,
"description": "RAUC code signing With end entity cert and key",
"id": null,
"name": "RAUC code signing cert and key",
"operation_type": "RaucBundleSigningWithOneTimeKey",
"profile_id": "f30679fb-00cb-4630-b550-1d026d4d63b6",
"token": {
"description": "One Time Signing key for issuing signing certificates",
"extractable": null,
"key_override_id": null,
"key_type": "RSA2048",
"name": "Token for One Time Signing certificates",
"public_key": null
}
}
],
"product_type": "Production",
"rnd_keys": [],
"state": null
}
Is product ok(Y/N): y
{
"ca_info": [],
"description": "Product for testing RAUC bundle One Time Signing",
"enabled": null,
"external_request_id": null,
"id": "51ec9ce9-3956-4e12-bea3-e994ed6a2395",
"name": "RAUC onetime",
"product_config_items": null,
"product_operations": [],
"product_type": null,
"rnd_keys": [],
"state": 2
}
Product Add request sent. Request ID: 51ec9ce9-3956-4e12-bea3-e994ed6a2395 state: ApprovalRequired
Approve product¶
The product was approved using the GUI.
Then with the python tool the state was checked ( state is 16 for ready product) and the product ID and operation ID was obtained.
- productID = 51ec9ce9-3956-4e12-bea3-e994ed6a2395
- operation ID for RAUC signing = e007176c-6b29-4640-9f6e-7cee6abb6c0a
(venv) $ ./signing-tool.py -c -t $TOKEN \
-a https://app.laavat.io/<CustomerName>/api/v1/ product getall
{
"count": 1,
"items": [
{
"description": "Product for testing RAUC bundle One Time Signing",
"id": "51ec9ce9-3956-4e12-bea3-e994ed6a2395",
"name": "RAUC onetime",
"state": 16
}
],
"next": "/products/?page=1",
"pages": 1,
"prev": "/products/?page=1"
}
(venv) $ ./signing-tool.py -c -t $TOKEN \
-a https://app.laavat.io/<CustomerName>/api/v1/ product \
get -I 51ec9ce9-3956-4e12-bea3-e994ed6a2395
{
"ca_info": [
{
"cert_override_payload": null,
"certificate_type": "SUBCA",
"cn": "CA for One Time Signing certs",
"crl_distribution_points": null,
"crl_expiry": null,
"crl_issue_interval": null,
"csr": null,
"description": "One Time Signing RAUC code signing certs",
"external_request_id": null,
"external_root": null,
"id": "fe6c6a91-a771-4cd4-a00e-363f10f77cc2",
"issuer_ca_id": null,
"key_override_id": null,
"key_type": "RSA2048",
"leafs": [],
"originating_id": null,
"policy_identifiers": null,
"product_id": null,
"profile_id": "321c7960-ec34-459d-bc5c-ee2399633922",
"state": 16,
"use_case": "RaucCodeSigning"
}
],
"description": "Product for testing RAUC bundle One Time Signing",
"enabled": null,
"external_request_id": "a68e9b4e-64d4-cde8-6abc-d88f45d03bb3",
"id": "51ec9ce9-3956-4e12-bea3-e994ed6a2395",
"name": "RAUC onetime",
"product_config_items": [],
"product_operations": [
{
"approval_rule": {
"allowed_groups": [
"b716abb1-2e3b-47a9-bca5-a3669faa50a6"
],
"approval_groups": [
"f65a3ea9-60db-47a4-9ad8-c6915735ec5f"
],
"blanket_groups": [
""
],
"description": "Rule used for testing for RAUC onetime",
"name": "Test rule2"
},
"ca_use_case": null,
"description": "RAUC code signing With end entity cert and key",
"id": "e007176c-6b29-4640-9f6e-7cee6abb6c0a",
"name": "RAUC code signing cert and key",
"operation_type": "RaucBundleSigningWithOneTimeKey",
"profile_id": "f30679fb-00cb-4630-b550-1d026d4d63b6",
"token": {
"description": "One Time Signing key for issuing signing certificates",
"extractable": null,
"key_override_id": null,
"key_type": "RSA2048",
"name": "Token for One Time Signing certificates",
"public_key": null
}
}
],
"product_type": "Production",
"rnd_keys": [],
"state": 16
}
Getting the sensitive items¶
In manufacturing there are some sensitive items which are needed. Here a client is registered which can obtain e.g., certificates.
(venv) $ ./signing-tool.py -c -t $TOKEN \
-a https://app.laavat.io/<CustomerName>/api/v1/ client add -N Manufacturing -D "Get sensitive information" \
-K client.public -U "upn:<redacted>" -T ProductionPC -p 51ec9ce9-3956-4e12-bea3-e994ed6a2395
{
"client_type": "ProductionPC",
"description": "Get sensitive information",
"id": "5235da30-6c2b-493c-bfec-937b70dc6742",
"id_product": "51ec9ce9-3956-4e12-bea3-e994ed6a2395",
"name": "Manufacturing",
"state": 2
}
Client Add request sent. Request ID: 5235da30-6c2b-493c-bfec-937b70dc6742 state: ApprovalRequired
Approve the client from UI
Now the product sensitive items can be fetched.
(venv) $ ./signing-tool.py -c -t $TOKEN \
-a https://app.laavat.io/<CustomerName>/api/v1/ secrets get \
-P 51ec9ce9-3956-4e12-bea3-e994ed6a2395 -C client.private -O /tmp/prod.json
SRKHASH written to: /tmp/prod.jsonSRKHASH
SRKTABLE written to: /tmp/prod.jsonSRKTABLE
KEKIV written to: /tmp/prod.jsonKEKIV
Full secret payload written to: /tmp/prod.json
The /tmp/prod.json contains all the items in one file. All the Certificates can be seen in that file.
More info can be found from client usage.
RAUC signing¶
See more information about RAUC packages.
The rauc-verity.tar.gz was used for signing. request.json was same as in documentation
$ tar -tvf rauc-verity.tar.gz
drwxrwxr-x user/user 0 2025-03-27 14:34 data/
-rw-rw-r-- user/user 65536 2025-03-27 14:10 data/rootfs.img
-rw-rw-r-- user/user 32768 2025-03-27 14:10 data/appfs.img
-rw-rw-r-- user/user 8192 2025-03-27 14:10 data/space-dummy
-rw-rw-r-- user/user 144 2025-03-27 15:39 data/manifest.raucm
-rw-rw-r-- user/user 52 2025-03-27 14:15 request.json
(venv) $ ./signing-tool.py -c -t $TOKEN \
-a https://app.laavat.io/<CustomerName>/api/v1/ imagesigning add RaucBundleSigning \
-P 51ec9ce9-3956-4e12-bea3-e994ed6a2395 \
--operid e007176c-6b29-4640-9f6e-7cee6abb6c0a \
-N TEST -D TEST -F rauc-verity.tar.gz
{
"call_back_url": null,
"description": "TEST",
"id": "8a0bcafc-df97-48c9-a60a-b06e5f0b169d",
"id_product": "51ec9ce9-3956-4e12-bea3-e994ed6a2395",
"id_product_operation": "e007176c-6b29-4640-9f6e-7cee6abb6c0a",
"name": "TEST",
"payload": {
"id": null,
"metadata": [
{
"name": "first",
"value": "val"
}
],
"modified_sha256": null,
"name": "rauc-verity.tar.gz",
"original_sha256": null,
"s3_url": null,
"service_provided_parameters": null
},
"state": 1
}
Request sent. Request ID: 8a0bcafc-df97-48c9-a60a-b06e5f0b169d, state: Created
The operation created ID "8a0bcafc-df97-48c9-a60a-b06e5f0b169d" which is then used when querying/downloading the signed content.
Approve signing request¶
Request was approved from the GUI.
Download signed content¶
After approval the request is processed and it can be queried. If the state is 16 then the signing is complete and the content is downloaded.
(venv) $ ./signing-tool.py -c -t $TOKEN \
-a https://app.laavat.io/<CustomerName>/api/v1/ imagesigning get \
-I 8a0bcafc-df97-48c9-a60a-b06e5f0b169d -O /tmp/test.bin --skipBase64
{
"call_back_url": null,
"description": "TEST",
"id": "8a0bcafc-df97-48c9-a60a-b06e5f0b169d",
"id_product": "51ec9ce9-3956-4e12-bea3-e994ed6a2395",
"id_product_operation": "e007176c-6b29-4640-9f6e-7cee6abb6c0a",
"name": "TEST",
"payload": {
"id": "750b4ae9-a324-487f-9109-8bbfe408ba3e",
"metadata": [
{
"name": "first",
"value": "val"
}
],
"modified_sha256": null,
"name": "rauc-verity.tar.gz",
"original_sha256": null,
"s3_url": "<redacted>ss>",
"service_provided_parameters": []
},
"state": 16
}
Downloading signed binary to: /tmp/test.bin
File Downloaded
Verify the bundle¶
In this example the trustpoint for the device is the CA certificate with CN "CA for issuing RAUC code signing certs". In this example the certificate was copied from the UI and the obtained PKCS7 content was stored to a file(input.pkcs7).
14:18:53 user$ cat input.pkcs7 | openssl pkcs7 -print_certs > certs.pem
See example response with validation
In production scenarios the trustpoint is downloaded securely using a registered client.