aip | title | author | discussions-to (*optional) | Status | last-call-end-date (*optional) | type | created | updated (*optional) | requires (*optional) |
---|---|---|---|---|---|---|---|---|---|
101 |
Safe onchain key rotation address mapping for standard accounts |
Alex Kahn (43892045+alnoki@users.noreply.github.com) |
Draft |
<mm/dd/yyyy the last date to leave feedbacks and reviews> |
Standard Framework |
09/17/2024 |
<mm/dd/yyyy> |
<AIP number(s)> |
The onchain key rotation address mapping has functional issues which inhibit safe mapping of authentication key to originating address for standard accounts. This proposal resolves these issues by adding assorted checks and extra function logic.
Note that this AIP does not attempt to address multisig v2 effects, because even
without the changes in this AIP, it is already possible for a multisig to
(misleadingly) generate an entry in the OriginatingAddress
table:
- Rotate account
A
to have a new authentication key, thus generating an entry in theOriginatingAddress
table. - Convert account
A
to a multisig viamultisig_account::create_with_existing_account_and_revoke_auth_key
, which will set the account's authentication key to0x0
, but which will not mutate theOriginatingAddress
table, since it makes an inner call toaccount::rotate_authentication_key_internal
. - The
OriginatingAddress
table then (incorrectly) reports that a mapping from the authentication key (from before multisig conversion) to the multisig address.
- Without the changes proposed in this AIP's reference implementation,
unproven authentications (specifically those relying on
rotate_authentication_key_call
) will result in an unidentifiable mapping, such that users will be unable to identify accounts secured by their private key unless they have maintained their own offchain mapping. This applies to exotic wallets like passkeys. - The overwrite behavior (described below) for
update_auth_key_and_originating_address_table
can similarly result in an inability to identify an account based on the private key. - A user who authenticates two accounts with the same private key per the below schema will experience undefined behavior during indexing and OpSec due to the original one-to-one mapping assumption.
One alternative would be a primarily offchain and indexing-based approach to mapping authentication keys.
However, such an approach would require breaking changes and would introduce offchain indexing as an additional dependency in the authentication key mapping paradigm.
The proposed solution offers a purely onchain solution to existing issues and does not require altering the existing design space or introducing an offchain dependency.
Aptos authentication key rotation is accompanied by a global mapping from an
authentication key to the address that it authenticates, the
OriginatingAddress
table. For more background see the key rotation docs and
the Ledger key rotation docs.
There are currently several issues with the OriginatingAddress
table (which is
supposed to be a one-to-one lookup table) that render the mapping unsafe in
practice:
- Per
aptos-core
#13517,rotate_authentication_key_call
does not update theOriginatingAddress
table for an "unproven" key rotation without aRotationProofChallenge
(resolved in this AIP's reference implementation with a newset_originating_address
private entry function). - When a given authentication key already has an entry in the
OriginatingAddress
table (t[ak] = a1
) and a key rotation operation attempts to establish a mapping to a new account address, (t[ak] = a2
), the inner functionupdate_auth_key_and_originating_address_table
silently overwrites the existing mapping rather than aborting, such that the owner of authentication keyak
is unable to identify account addressa1
purely onchain from authentication keyak
. Hence account loss may ensure if someone accidentally maps the same authentication key twice but does not keep an offchain record of all authenticated accounts (resolved in reference implementation withENEW_AUTH_KEY_ALREADY_MAPPED
check). - Standard accounts that have not yet had their key rotated are not registered
in the
OriginatingAddress
table, such that two accounts can be authenticated by the same authentication key: the original account whose address is its authentication key, and another account that has had its authentication key rotated to the authentication key of the original account. (This situation is possible even with proposedENEW_AUTH_KEY_ALREADY_MAPPED
since account initialization logic does not create anOriginatingAddress
entry for a standard account when it is first initialized). Hence sinceOriginatingAddress
is intended to be one-to-one, a dual-account situation can inhibit indexing and OpSec (resolved in reference implementation withset_originating_address
private entry function, which allows setting a mapping for the original account address).
Assorted checks and extra function logic in aptos-core
#14309:
- Function
set_originating_address()
: Private entry function to establish anOriginatingAddress
mapping for account reconciliation after an unproven rotation or for an account that has just beencreated. - Function
originating_address()
: View function to return the address mapped to an authentication key - Abort
ENEW_AUTH_KEY_SAME_AS_CURRENT
to prevent no-op rotations that can introduce indexing issues. - Abort
ENEW_AUTH_KEY_ALREADY_MAPPED
to prevent onchain account loss from silent overwriting of existing mappings.
The reference implementation pairs with a docs site walkthrough that I authored, which demonstrates, documents, and verifies the functionality from the reference implementation.
This proposal enforces a one-to-one mapping of private key to account address in the general case of following best practices, which extreme users (wishing to use one private key to authenticate all their accounts) may find restrictive.
Note that the function account::set_originating_address
proposed in
aptos-core
#14309 must remain a private entry function to prevent unproven
key rotation attacks.
In a separate update, logic to eradicate the existing multisig v2 indexing issues mentioned above (which is outside the scope of what the reference implementation intends to resolve).
Ideally during next release