Skip to content

Latest commit

 

History

History
99 lines (78 loc) · 3.72 KB

kip-0022.md

File metadata and controls

99 lines (78 loc) · 3.72 KB
KIP Title Author Status Type Category Created
0022
Disable guard rotation for coin-contract principal accounts
Greg Hale @imalsogreg
Draft
Standard
Interface
2023-09-28

Motivation

The ability for an account holder to rotate their guard is granted by the rotate function in the coin contract. This is a natural operation to want for a normal username/secret governance model. But it is not safe for use on Principal accounts, because Principal account names are meant to be derivable from the guard that governs them. The guard is the source of truth about the Principal account string. Rotating to a new guard therefore breaks a Pact invariant. A Principal account with a rotated guard would not be recognized by Pact as a Principal account, which would cause it to fail a number of common safety checks in coin contract.

This KIP proposes to add an assertion to the rotate function during the next upgrade of the coin contract, to protect principal account users from the negative effects of rotating their account guard.

Implementation

To diable guard rotations on principal accounts, we will add an assertion to the rotate function:

(defun rotate:string (account:string new-guard:guard)
  (with-capability (ROTATE account)
  
    ; **************************************
    ; *** Add this new enforce statement ***
    ; **************************************
    (enforce (or (not (is-principal account))
                 (validate-principal new-guard account))
      "It is unsafe for principal accounts to rotate their guard")

    (with-read coin-table account
      { "guard" := old-guard }

      (enforce-guard old-guard)

      (update coin-table account
        { "guard" : new-guard }
        )))
  )

The enforce call enforces that either the account is not a principal account, or if the account is a principal then we are rotating to the (original) correct guard for the principal.

This change will roll out with the next deployment of coin contract, which is scheduled for December 2023.

Impact on Users

Non-principal accounts (e.g. vanity accounts) are unaffected by this change. Principal accounts that have already rotated their guards are unaffected by this change.

Principal accounts for whom guard rotation is an important part of their expected workflow need to identify a new workflow. Since most accounts are principal accounts, this means all accounts should expect not to be able to rotate guards under an account. Please see Workarounds for alternative solutions.

Workarounds

Principal account holders (most accounts, including all "k:" accounts, are principal, accounts), may want some way to rotate their guard, analogous to the common security measure of regularly changing your password or rotating certificates or other security credentials. But the invariants that relate Principal account names to their guards explicitly preclude this. How else can credentials be rotated?

The simplest solution is to rotate your principal account, not your guard; namely, create a new account and transfer funds to it.

Another option, "keyset-guards" allows safe credential rotation without using the rotate function, if you create your account as a r: (KeySet Principal) account. Account names are derived from the name of the KeySet that guards them, and you are free to update the keys in that KeySet.

(coin.create-account 
  (create-principal (keyset-ref-guard "<some keyset name>")) 
  (keyset-ref-guard "<some keyset name>"))