Skip to content

End-to-end quickstart

This page walks the whole path for an embedded Linux (Yocto) device: create your keys, bake them into an image, get the device online, and ship a first signed update. Later sections add Remote SSH, crash reporting and monitoring. It is the shortest route through the pages under Getting started and Device integration.

  • An OTA-Pulse account whose organization role is OWNER (or ADMIN), with MFA enrolled. MFA is mandatory for OWNER (and, where your organization enforces it, ADMIN), so you cannot sign in to the console without it. Console sessions use a JWT that lasts 60 minutes.
  • Access to the OTA-Pulse Yocto layer (meta-otapulse) and a Yocto build host.
  • A plan that covers what you use. Free-tier organizations cannot open Remote SSH sessions (the server answers HTTP 402). See Pricing and limits.
  • The otapulse-artifact CLI and openssl on your build host.

OTA-Pulse uses several credentials that look alike but do different jobs. Most first-day problems come from using the wrong one.

I want to… Use this credential Sign an update artifact sign with Your own openssl key pair private: build host · public: image + server Let one device call the API authenticate as Device API key smk_… console: API Keys · device: SoCAPIKey Let many new devices register self-register with Provisioning token spt_… console: Provisioning · device: provision.env Open a Remote SSH tunnel receive Tunnel token sotc_… minted at first provision · nothing to create
Each goal has exactly one credential. Dashed means you do not create it: the server issues the tunnel token when a device first provisions.
CredentialPrefixCreated byWhere it goesUsed for
Console login + MFA(JWT)You, at sign-inBrowser, or Authorization: Bearer for the management APIOperating the console. The access token lasts 60 minutes.
Artifact signing keynoneYou, with opensslPrivate key stays on your build host. The public key is baked into the image and imported into the console (Signing Keys).Proving an .otapulse artifact is yours.
Device API keysmk_Sidebar API KeysSoCAPIKey in the agent config (written for you by first-boot provisioning). Yocto images ignore OTAPULSE_TENANT_TOKEN; Buildroot images use BR2_PACKAGE_OTAPULSE_TENANT_TOKENOne device (or one fleet you choose to share it across) calling the API.
Fleet provisioning tokenspt_Sidebar ProvisioningOTAPULSE_PROVISIONING_TOKEN (see below)Letting new devices register themselves. Has a max_devices limit.
Tunnel tokensotc_Minted automatically at provision/data/frp/credential on the deviceRemote SSH tunnel. You never create it in the console.

Details that matter:

  • Artifact signing is on by default. The server setting ARTIFACT_SIGNATURE_REQUIRED defaults to true, so an unsigned or badly signed artifact is rejected at upload with HTTP 422.
  • The console Signing Keys page verifies uploads; it does not put keys on devices. Import your public key there (Import Public Key) so the server accepts artifacts you sign. A device trusts only the public keys baked into its image; the server cannot push a key to a device. Sign with your own openssl key as described in Step 1.
  • API keys and provisioning tokens are shown once. Copy the value when it is created. Both can be rotated or revoked from their pages.
  • Yocto images authenticate with SoCAPIKey, not TenantToken. The image sets UseSoCMonitoring: true, and under that setting the agent ignores TenantToken (and so OTAPULSE_TENANT_TOKEN). The normal path is OTAPULSE_PROVISIONING_TOKEN: first-boot provisioning registers the device and writes its own SoCAPIKey and SoCDeviceID. To pre-seed an existing smk_ key instead, set SoCAPIKey and SoCDeviceID in the agent config yourself. Buildroot images do not set UseSoCMonitoring, so there BR2_PACKAGE_OTAPULSE_TENANT_TOKEN is the token the agent uses.
  • The sotc_ tunnel token comes from provisioning. It is returned on its first provision by the same call that returns the device’s API key (a re-provision returns no new tunnel token), so a device that has not provisioned has no tunnel credential.
Console Provisioning page Device /etc/otapulse/ provision.env firstboot provisioning OTA-Pulse server /api/v1/provision ① you copy spt_… into the image (once) ② POST with the token ③ returns new credentials smk_ device API key stored in /data/otapulse/otapulse.conf sotc_ tunnel token (first provision only) stored in /data/frp/credential
You carry one token to the device once. The server then issues the per-device credentials itself, so you never copy an smk_ key or a tunnel token by hand on this path.
  1. Create and distribute your signing key

    Generate an RSA-4096 key pair on your build host. Keep the private key out of the image and out of version control.

    Terminal window
    # RSA-4096 (recommended)
    openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out release-private.pem
    # or ECDSA P-256
    openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out release-private.pem
    # Derive the SPKI public key (the file you import and bake into the image)
    openssl pkey -in release-private.pem -pubout -out production-rsa-public.pem

    RSA-3072 and RSA-2048 keys are accepted as well. Later, sign with otapulse-artifact write rootfs-image ... --key release-private.pem (Step 6). The same commands apply to Artifacts.

    Two places must trust the public key:

    • The device image. In local.conf, point SOC_OTA_VERIFICATION_KEYS at the public key and turn verification on. The file’s basename must match an entry in SOC_OTA_VERIFY_KEY_FILES, whose default is production-rsa-public.pem:

      SOC_OTA_SIGNATURE_VERIFICATION = "1"
      SOC_OTA_VERIFICATION_KEYS = "/path/to/production-rsa-public.pem"

      If you name the file differently, set SOC_OTA_VERIFY_KEY_FILES to that name as well. Otherwise the key is installed but the agent does not trust it. The image build fails if verification is on and SOC_OTA_VERIFICATION_KEYS is empty, so the publicly available example key can never be trusted by accident.

    • The server. The backend verifies the signature embedded in each uploaded artifact against your organization’s signing keys. In the console, open Signing Keys, click Import Public Key, enter a Key Name, paste the contents of production-rsa-public.pem (or load the .pem file), and click Import. Only an organization owner can do this. Deployment-wide keys set by the operator in ARTIFACT_VERIFY_KEY_PATHS are still honoured in addition to your own.

    The public key must be a standard BEGIN PUBLIC KEY (SPKI) PEM: RSA 2048, 3072 or 4096-bit, or ECDSA P-256. ECDSA P-384, Ed25519, PKCS#1 (BEGIN RSA PUBLIC KEY) and private keys are rejected.

    Keep in mind:

    • The server cannot push keys to devices. Importing a key changes what the server accepts at upload, not what a device installs. The same public key must also be baked into the image as shown above (the signing-keys recipe, ArtifactVerifyKeys in the agent config).
    • Replace and revoke. On the Signing Keys page, Replace imports a new public key and revokes the old one in one step; Revoke revokes a key. Both ask you to type delete to confirm. Uploads signed with a revoked or replaced key are rejected; keys already baked into device images are unaffected. Importing a revoked key again reactivates it (also confirmed with delete).
    • Up to 10 active keys per organization.
  2. Create the credentials your devices will use

    In the console, open API Keys in the sidebar to create a device API key, and Provisioning to create a fleet provisioning token. Copy each value immediately. It is not shown again.

    For a fleet, the provisioning token is the better fit: devices register themselves with it, and it carries a max_devices limit. Its default scopes are devices:write, metrics:write, coredumps:write and ota:read.

  3. Add the layer and configure local.conf

    Add meta-otapulse to bblayers.conf, then set at least:

    OTA_SERVER_URL = "https://<your-server>"
    OTAPULSE_PROVISIONING_TOKEN = "<spt_ token>" # socmond first-boot registration

    Do not put an smk_ key in OTAPULSE_TENANT_TOKEN for a Yocto image. The agent ignores TenantToken on these images (see Keys and tokens).

    soc-monitoring-image does not write this value into /etc/socmond/config.json. Set auth.provisioning_token yourself in your image recipe (a ROOTFS_POSTPROCESS_COMMAND editing ${sysconfdir}/socmond/config.json), or place /etc/otapulse/provision.env as in Step 5.

    For a full explanation of A/B partitioning and per-board settings, see Linux and Yocto integration.

  4. Build the image and flash it

    Terminal window
    bitbake soc-monitoring-image

    Flash the resulting WIC image as described in Linux and Yocto integration.

  5. Confirm the device is online

    Boot the board with network access and open Devices in the console. The device should appear with an online status. If it does not, follow Quick troubleshooting.

    On first boot the otapulse-auto-provision service registers the device using the token from /etc/otapulse/provision.env if that file exists:

    Terminal window
    # /etc/otapulse/provision.env (mode 0600)
    OTAPULSE_PROVISIONING_TOKEN=<spt_ token>

    No recipe writes this file for you. If you rely on this path rather than the local.conf variables above, your image or provisioning process must place it on the device.

  6. Build and sign an artifact

    Build your new rootfs image (.ext4), then wrap and sign it. The --device-type value must match the one in /etc/otapulse/device_type on the target (the file contains device_type=<MACHINE>).

    Terminal window
    otapulse-artifact write rootfs-image \
    --file soc-monitoring-image-<machine>.ext4 \
    --output-path firmware-v1.0.1.otapulse \
    --artifact-name release-v1.0.1 \
    --device-type <device-type> \
    --key release-private.pem

    Name the artifact something unique. A signed artifact carries its signature inside the file, so there is nothing further to attach at upload time.

  7. Upload and deploy

    Follow Ship your first update, starting at the upload step: Firmware → Upload Firmware, then the Deployments tab on the same page → New Deployment. The API calls there work the same for a signed artifact.

  8. Verify

    The deployment moves through pending, downloading, installing (this also covers the reboot) and installed. A failed update ends as failed or rolled_back. After the reboot, confirm on the device:

    Terminal window
    sudo journalctl -u soc-ota-agent -n 50

    If the new image fails its health checks, the device boots back into the previous slot and the console shows the deployment as failed. See Ship your first update for how automatic rollback works.

Remote SSH opens a terminal on a device through an outbound tunnel the device initiates, so it needs no inbound port.

Image. The soc-monitoring-image recipe already includes frp, soc-ota-tunneld, soc-shell-access and soc-shell-access-privileged. In your own image recipe add them to IMAGE_INSTALL, and in local.conf set where the tunnel connects:

TUNNEL_SERVER_ADDR = "<tunnel-gateway-host>"
TUNNEL_SERVER_PORT = "7000"

TUNNEL_SERVER_ADDR has no default and must be set. Port 7000 is the default.

Set OTAPULSE_SSH_PUBKEY in local.conf to a file containing the gateway’s SSH public key; the openssh bbappend installs it to /root/.ssh/authorized_keys. Obtain the key from your OTA-Pulse contact, or from your own gateway deployment if self-hosted.

Verify on the device.

Terminal window
systemctl is-active soc-ota-tunneld
ls /data/frp/credential

The credential file appears once the device has provisioned and received its sotc_ token.

Use it. In the console open Devices, pick the device, and click Terminal. The button is shown only while the device’s tunnel is online. The new-session dialog then asks for a tier.

Who can connect. Session access needs a device.shell.* role plus membership of the Shell Access Group, both managed on the Shell Access Group sidebar page. See the Operator how-to and Admin guide.

Plan limits. Concurrent Remote SSH sessions per organization are 0 on Free (session open returns 402), 1 on Prototype, 2 on Pilot, 5 on Startup and 10 on Business. Opening a session beyond your tier’s cap returns 409.

The socmond-bin package (in soc-monitoring-image) installs the coredump handler socmond-core-handler. For it to capture crashes:

  • The credential socmond uses needs the coredumps:write scope. Provisioning tokens include it by default. An API key you create yourself needs it added.
  • The kernel must have core-dump support (CONFIG_COREDUMP and CONFIG_ELF_CORE). The OTA-Pulse kernel fragment monitoring.cfg enables both.
  • The soc-ota-agent service already sets LimitCORE=infinity. Services you want covered need a non-zero core limit too, because a zero limit stops the kernel invoking the handler at all.

Verify by crashing a throwaway process on the device, then open Coredumps in the console sidebar.

Reboot reasons are recorded too, but only exposed through the API (GET /api/reboot-events). There is no console page for them yet.

socmond collects metrics and sends heartbeats once it has provisioned. A device whose provisioning_token is empty logs that it is skipping provisioning and uploads nothing, so a monitoring gap on a fresh board usually means OTAPULSE_PROVISIONING_TOKEN was not set at build time. If your plan enforces a data-point quota, uploads beyond it are dropped while the device stays visible. See Pricing and limits.

For low-level device diagnostics the image also ships dlt-daemon. See the diag_toolkit documentation in the repository (docs/dlt-diagnostics.md).

SymptomLikely cause
Upload rejected with 422The artifact is unsigned, or signed with a key the server does not trust. Import the matching public key under Signing Keys (or check ARTIFACT_VERIFY_KEY_PATHS for deployment-wide keys). See signature verification failed.
Agent logs signature verification failed with all loaded keysThe image does not carry the matching public key. Check SOC_OTA_VERIFICATION_KEYS and that its basename appears in SOC_OTA_VERIFY_KEY_FILES.
Device never authenticates, TLS or token errorsClock skew. Device clocks that are minutes off break token validation. Make sure time sync is running.
Verification build fails immediatelySOC_OTA_SIGNATURE_VERIFICATION = "1" with no SOC_OTA_VERIFICATION_KEYS. This is intentional.
No metrics from a new boardsocmond has no provisioning token, so it never provisions.
Deployment or upload refused with 402A plan quota or entitlement. See Pricing and limits.