App Permissions
Every application has an associated set of permissions, ranging from system-related permissions such as the ability to modify system configuration or being able to request user PIN verification, to hardware wallet functionalities like the ability to derive specific keys only accesible to one particular app.
The following sections details how those permissions are granted. It is crucial to uphold the principle of least priviledge: each application must use permissions only absolutely necessary to its execution.
Application flags
Priviledges or permissions of an application are defined within its Makefile through the --appFlags
parameter.
This bitfield is documented here.
Most notable flags are:
APPLICATION_FLAG_BOLOS_SETTINGS (0x200)
: the application can read and modify system parameters such as the device’s name.APPLICATION_FLAG_GLOBAL_PIN (0x40)
: the application can request a user PIN verification or query the number of tries left before the device erases its own memory.APPLICATION_FLAG_LIBRARY (0x800)
: the application behaves (or rather can also behave) as a library and exports functions that can be reached from other applications.
A common use of the APPLICATION_FLAG_BOLOS_SETTINGS is for using BLE channel on Nano X. The Nano S and Nano S Plus do not have such a channel however. Which means the Makefile has to treat the --appFlags
separately for each device type, like so:
ifeq ($(TARGET_NAME), TARGET_NANOX)
APP_LOAD_PARAMS=--appFlags 0x200 # APPLICATION_FLAG_BOLOS_SETTINGS
else
APP_LOAD_PARAMS=--appFlags 0x000
endif
Other flags are in general not used at all.
Any use of a flag other than APPLICATION_FLAG_BOLOS_SETTINGS must be justified in the Makefile otherwise Ledger will not sign the application.
Restrict Apps to Coin-Specific BIP32 Prefix
Ledger devices are Hierarchical Deterministic wallets, which means they can derive as many keys as necessary from a single seed as defined in BIP-0032. The seed is similar to the master node of a tree of subkeys. The way those trees are constructed can be arbitrary but it is recommended it follows a few standards. First, we recommended the first level in this hierarchy of subkeys be always tied to a “purpose” as described in BIP-0043.
Next, all coins must follow the logic defined in BIP-0044. If a coin is already registered in SLIP-0044 then its associated application must derive keys in the registered subtree only. If it is not already registered then a subtree or “path” must be chosen and not be in conflict with any other application that might be using this subtree already.
Ledger will not sign apps whose BIP32 prefixes have not been properly set.
Restricting the derivation path can be done by setting the --path
property in the app Makefile.
For example, if your application derives keys on the hardened path 44’/60’, specify in your Makefile:
APP_LOAD_PARAMS += --path "44'/60'"
Derivation can also be restricted to a specific curve using the --curve
property. Supported curves are secp256k1
, secp256r1
, ed25519
and bls12381g1
.
Several curves and paths can be configured at the same time. For example, if your app must derive keys on paths 44’/535348’, 13’ and 17’, on curves Ed25519 and prime256r1, the Makefile should contain:
APP_LOAD_PARAMS=--curve ed25519 --curve prime256r1 --path "44'/535348'" --path "13'" --path "17'"
Rationale: Setting prefixes is crucial, as it limits the amount of damage an attacker can cause if they manage to compromise an application. If a vulnerability is exploited on a poorly written or backdoored application, an attacker should not be able to exploit it to extract private keys from other apps, such as Bitcoin or Ethereum keys.