Guides / Historical migration

Historical migration

Use oro:migration to import allowlisted historical Android protected data and retain published receiver, service, job, or Activity alias names. Common mechanics use bundled policy and generated adapters; they do not require application Kotlin, C++, or JNI. The high-level executor is Android-only.

import migration from 'oro:migration'

const support = await migration.getSupport()
console.log(support.available, support.protectedImport, support.retainedComponents)
console.log(support.reason)

Check for protected-import-v1 and retained-components-v1 before offering actions. The compatibility probe requires authentication's historical migration protocol 1; older native binaries cannot acquire it through new JavaScript alone. Missing backends reject with ENOSYS; permission, missing-key, corrupt-data, stale-state, and cancellation failures retain their distinct errors.

Declare exact historical identities#

Add a project-root definition file and opt into the native permission flow:

[migration]
enabled = true
definitions = "migration.json"

[permissions]
allow_biometrics = true

For example, migration.json can allow one known AES-GCM source:

{
  "schema": 1,
  "protected": [{
    "id": "saved-sign-in",
    "preferences": "application.history",
    "key": "protected-sign-in",
    "alias": "application.historical.sign-in",
    "aad": "{package}:saved-sign-in",
    "encoding": "base64",
    "ciphertextField": "ciphertext",
    "authentication": "biometric-or-device",
    "policy": "biometric-or-device"
  }],
  "components": []
}

Replace these example names with the exact identifiers from the released historical app before building. Definitions allow at most 16 protected sources and 16 retained components in 64 KiB. JavaScript selects a definition ID and bounded opaque sourceRef; it cannot supply arbitrary filesystem paths, key aliases, AAD, codecs, or component classes. Original saved data and keys must remain available.

The CLI validates policy, generates retained Kotlin adapters and manifest entries, and binds oro-migration.json to native/asset build evidence. Do not declare duplicate application classes or manifest entries for those generated adapters.

Inspect before importing#

Call this helper from the user's explicit import action after resolving the intended current identity:

import migration from 'oro:migration'

export async function importSavedSignIn({ sourceRef, authorityRef, accountRef, targetRef, signal }) {
  const source = { profile: 'saved-sign-in', sourceRef }
  const { sourceSha256 } = await migration.inspectProtected(source)
  return migration.importProtected({
    ...source, sourceSha256, authorityRef, accountRef, targetRef, userInitiated: true
  }, { signal })
}

sourceSha256 binds the import to the inspected source version. Cancellation, missing keys, malformed envelopes, and changed source data must not trigger plaintext fallback or silent replacement. Decrypted application fields still require schema validation and server authorization; importing a historical session does not authenticate the current account.

Retain components without replaying mutations#

Retained component policy preserves exact published Android names. Inspect and prepare the handover, activate only its approved generation, and read retained receipts/status before deciding what completed. Unknown outcomes are preserved; an old callback or local receipt does not establish a successful remote transfer. Reconcile before resolving or releasing receipts.

Historical source selection distinguishes allowlisted AES envelopes from native-record histories using provenance. If the source is ambiguous or provenance does not match, preserve it and report the conflict rather than selecting whichever input is easiest to read.

Generated-adapter adoption may require an explicit bridge build first. Keep the original classes and data through the staged upgrade path; do not remove them before the target published identities and outcomes have been qualified. Shared C++ v2 native records are separate from Android Kotlin v1 and are not an automatic replacement for previously qualified Android stores.

The historical migration reference covers retained-component schemas, source selection, provenance, bridge builds, exact-name requirements, and public fixture acceptance. Public fixtures do not qualify an application's private historical data, signing lineage, OEM behavior, or production upgrade path.

Source repository · Edit this page · View Markdown

Quick links

Type to search across the site. Use the up and down arrow keys to choose a result, Enter to open it, and Escape to close.