Skip to main content
By default, arcane_init is the ownership check. Call it once at launch with your portal public key. You do not add a second ownership step unless you need a custom flow. The game does not talk to the network for this: the Arcane desktop launcher refreshes tickets online; the SDK only reads and verifies the local cache.

Portal public key

The string you pass to init is the public key generated for your title in the Arcane portal. In the current crate API the parameter is still named game_id — pass the portal public key there. The same value keys local flag and ticket files, and must match the ticket gid claim.

Default init policy

arcane_init(public_key):
  1. Reads flags/{public_key}.json for drm_enabled
  2. If drm_enabled is false → returns OwnershipStatus::DrmDisabled (no ticket required)
  3. Otherwise (flag true or missing) → runs the offline ownership check
That is the whole default launch path.

Offline check (what init runs when DRM is on)

When DRM is not disabled, init verifies the cached ticket:
  1. Loads a ticket file for the public key (scans tickets/{user_id}/)
  2. Rejects clock rollback vs last_seen_wall_time
  3. If drm_enabled on the ticket file is false → DrmDisabled
  4. Ensures the ticket string is non-empty
  5. Compares cached device_hash to the local fingerprint
  6. Verifies the JWT (ES256, issuer arcane-drm, audience arcane-game-sdk)

Data layout

drm_data_root() resolves {app_data} via the OS application data directory.

Ticket claims

Device fingerprint

machine_id is a UUID written once under the DRM root (mode 0600 on Unix). device_hash is the first 16 bytes of SHA-256(machine_id), hex-encoded. Tickets are bound to that hash so they cannot be copied to another machine.

JWKS

Verification keys come from jwks.json. The JWT kid selects the key when present. If JWKS is missing, the SDK returns ticket_invalid — refresh via the desktop app.

Custom check only

check_ownership_offline always runs the ticket path (useful if you manage DRM policy yourself). Prefer arcane_init for normal launch.