Files
loader/_docs/02_document/deployment/provisioning_runbook.md
T
Oleksandr Bezdieniezhnykh d244799f02 [AZ-182][AZ-184][AZ-187] Batch 1
Made-with: Cursor
2026-04-15 07:23:47 +03:00

5.5 KiB

Jetson device provisioning runbook

This runbook describes the end-to-end flow to fuse, flash, provision a device identity, and reach a state where the Azaion Loader can authenticate against the admin/resource APIs. It targets a Jetson Orin Nano class device; adapt paths and NVIDIA bundle versions to your manufacturing image.

Prerequisites

  • Provisioning workstation with bash, curl, openssl, python3, and USB/network access to the Jetson in recovery or mass-storage mode as required by your flash tools.
  • Admin API reachable from the workstation (base URL, for example https://admin.internal.example.com).
  • NVIDIA Jetson Linux Driver Package (L4T) and flash scripts for your SKU (for example odmfuse.sh, flash.sh from the board support package).
  • Root filesystem staging directory on the workstation that will be merged into the image before flash.sh (often a Linux_for_Tegra/rootfs/ tree or an extracted sample rootfs overlay).

Admin API contract (provisioning)

The scripts/provision_device.sh script expects:

  1. POST {admin_base}/users with JSON body {"email":"<string>","password":"<string>","role":"CompanionPC"}

    • 201 or 200: user created.
    • 409: user with this email already exists (idempotent re-run).
  2. PATCH {admin_base}/users/password with JSON body {"email":"<string>","password":"<string>"}

    • Used when POST returns 409 so the password in device.conf matches the account after re-provisioning.
    • 200 or 204: password updated.

Adjust URL paths or JSON field names in the script if your deployment uses a different but equivalent contract.

Device identity and device.conf

For serial AZJN-0042, the script creates email azaion-jetson-0042@azaion.com (suffix is the segment after the last hyphen in the serial, lowercased). The password is 32 hexadecimal characters from openssl rand -hex 16.

The script writes:

{rootfs_staging}/etc/azaion/device.conf

On the flashed device this becomes /etc/azaion/device.conf with:

  • AZAION_DEVICE_EMAIL=...
  • AZAION_DEVICE_PASSWORD=...

File permissions on the staging file are set to 600. Ensure your image build preserves ownership and permissions appropriate for the service user that runs the Loader.

Step-by-step flow

1. Unbox and record the serial

Read the manufacturing label or use your factory barcode process. Example serial: AZJN-0042.

2. Fuse (if your product requires it)

Run your approved fuse workflow (for example NVIDIA odmfuse.sh or internal wrapper). This task does not replace secure boot or fTPM scripts; complete them per your security phase checklist before or after provisioning, according to your process.

3. Prepare the rootfs staging tree

Extract or sync the rootfs you will flash into a directory on the workstation, for example:

/work/images/orin-nano/rootfs-staging/

Ensure etc/ exists or can be created under this tree.

4. Provision the CompanionPC user and embed credentials

From the Loader repository root (or using an absolute path to the script):

./scripts/provision_device.sh \
  --serial AZJN-0042 \
  --api-url "https://admin.internal.example.com" \
  --rootfs-dir "/work/images/orin-nano/rootfs-staging"

Confirm the script prints success and that rootfs-staging/etc/azaion/device.conf exists.

Re-running the same command for the same serial must not create a duplicate user; the script updates the password via PATCH when POST returns 409.

If the admin API requires authentication (Bearer token, mTLS), extend the script or shell wrapper to pass the required curl headers or use a local proxy; the stock script assumes network-restricted admin access without extra headers.

5. Flash the device

Run your normal flash procedure (for example flash.sh or SDK Manager) so the staged rootfs—including etc/azaion/device.conf—is written to the device storage.

6. First boot

Power the Jetson, complete first-boot configuration if any, and verify the Loader service starts. The Loader should read AZAION_DEVICE_EMAIL and AZAION_DEVICE_PASSWORD from /etc/azaion/device.conf, then use them when calling POST /login on the Loader HTTP API (which forwards credentials to the configured resource API per your deployment). After a successful login path, the device can request resources and unlock flows as designed.

7. Smoke verification

  • From another host: Loader GET /health returns healthy.
  • POST /login on the Loader with the same email and password as in device.conf returns success (for example {"status":"ok"} in the reference implementation).
  • Optional: trigger your normal resource or unlock smoke test against a staging API.

Troubleshooting

Symptom Check
curl fails to reach admin API DNS, VPN, firewall, and API_URL trailing slash (script strips one trailing slash).
HTTP 4xx/5xx from POST /users Admin logs; confirm role value CompanionPC and email uniqueness rules.
409 then failure on PATCH Implement or enable PATCH /users/password (or change script to match your upsert API).
Loader cannot log in device.conf path, permissions, and that the password in the file matches the account after the last successful provision.

Security notes

  • Treat device.conf as a secret at rest; restrict file permissions and disk encryption per your product policy.
  • Prefer short-lived credentials or key rotation if the admin API supports it; this runbook describes the baseline manufacturing flow.