Skip to content
Alpha: Odal Node is in active development. APIs, schemas and docs will change before 1.0.

Upgrading

  1. Back up first: the database and the key store. Migrations run forward only, so this backup is your rollback. See Backup, restore and key custody.
  2. Upgrade a staging node first: check out the new release tag in its clone, set ODAL_VERSION to match (the release number without its leading v), then run odal update, which rebuilds the node from that source and restarts it.
  3. Check it: odal status, the trust posture on /vault/api/v1/node/state, and publish, resolve and verify a test passport.
  4. Upgrade production the same way, and record the version and date.

Migrations apply automatically at start-up when DATABASE_MIGRATE_URL is set. A published passport is never rewritten by an upgrade: passports issued under an older schema version keep resolving exactly as they were issued.

These are not in a release yet and ship with the next one. The rest of this documentation already describes them.

  • Retire replaces archive. POST /dpp/{dppId}/archive is now POST /dpp/{dppId}/retire, the status it sets is "retired" and the event is dpp.passport.retired. odal passport archive is now odal passport retire, and trustMode.archive on /vault/api/v1/node/state is trustMode.backup. "archived" is refused, not aliased: update clients, and resubscribe webhooks and NATS consumers that filter on dpp.passport.archived. A migration rewrites stored statuses on upgrade.
  • Rename ARCHIVE_S3_* to BACKUP_S3_*. The variables are otherwise unchanged; see Configuration reference.
  • Product group data carries a productIdentifier, not a gtin. "gtin": "09506000134352" becomes "productIdentifier": { "scheme": "gs1", "gtin": "09506000134352" }, and an identification link or a DID is accepted where a GTIN was required. GET /vault/api/v1/dpp/by-identity takes identifier instead of gtin. Stored passports are not rewritten.
  • The printed carrier follows the passport’s stated level. A model-level passport prints /01/{gtin}, a batch-level one /01/{gtin}/10/{batch}, and an item-level one, or one that states no level, /01/{gtin}/21/{serial}. Anything that parses qrCodeUrl should expect all three.
  • A production or sandbox node refuses ALLOW_UNSIGNED_PLUGINS=true. Remove the variable and set PLUGIN_SIGNING_KEY to the plugin publisher’s Ed25519 public key.
  • RESOLVER_BASE_URL is required by the node and the resolver, with no default. Set it to your resolver’s public address before starting the new version.
  • Second-life lineage is derivedFrom, an array of { reference, operation }. Clients that sent parentPassportRef must send derivedFrom instead.
  • A component reference is an object, not a bare passport reference. Clients building componentRefs must send the new shape.
  • SEAL_CONFORMANCE_LEVEL defaults to LTA, the sealer’s own level. Nothing to do unless you pinned a lower level on purpose.
  • The release’s container images now carry a software bill of materials and build provenance.

Every change, with its reasoning, is in the engine’s changelog.