# Super User Account

**URL:** <https://forum.flow.com/t/super-user-account/4088>\
**Category:** 🏄🏻‍♀️ Cadence\
**Tags:** cadence, account-model\
**Created:** [January 20, 2023, 4:39pm UTC](https://forum.flow.com/t/super-user-account/4088 "2023-01-20T16:39:57Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![bluesign](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.flow.com/bluesign/32/1359_2.png) [@bluesign](https://forum.flow.com/u/bluesign)\
**Post date:** [January 20, 2023, 4:39pm UTC](https://forum.flow.com/t/super-user-account/4088/1 "2023-01-20T16:39:58Z")

</div>

### Summary

With the advancement of Cadence language and Flow Blockchain, I think there is a need to separate `AuthAccount` into two (maybe more) security levels. Inspiration comes from operating systems security. (`sudo` from Linux world and `administrator account` from Windows )

Before writing a FLIP, I would like to get some community feedback.

### Basic Idea

The basic idea is to move some dangerous operations ( like adding/removing the public key, deploying a contract, deleting a contract, getting AuthAccount capability, etc.) to `SuperAuthAccount`

For example below transaction will fail:

```auto
transaction(publicKey: [UInt8]) {
    prepare(signer: AuthAccount) {
        let key = PublicKey(
            publicKey: publicKey,
            signatureAlgorithm: SignatureAlgorithm.ECDSA_P256
        )
        signer.keys.add(
            publicKey: key,
            hashAlgorithm: HashAlgorithm.SHA3_256,
            weight: 10.0
        )
    }
}

```

instead it had to be written as:

For example below transaction will fail:

```auto
transaction(publicKey: [UInt8]) {
    prepare(signer: SuperAuthAccount) {
        let key = PublicKey(
            publicKey: publicKey,
            signatureAlgorithm: SignatureAlgorithm.ECDSA_P256
        )
        signer.keys.add(
            publicKey: key,
            hashAlgorithm: HashAlgorithm.SHA3_256,
            weight: 10.0
        )
    }
}

```

For multi-sign scenarios, there can be a mixture of `SuperAuthAccount` and `AuthAccount` in transactions, depending on the access. It is up to wallets to get approval from users. This way, even if wallets don’t support this new feature, they can continue to work as is. ( by signing as `SuperAuthAccount` without warning, which is equal to today’s case )

With support from wallet developers by enabling some features like:  
- Big warning when a transaction wants to use `SuperAuthAccount`  
- Requiring the user to authenticate with a password again before signing

we can prevent some dangerous attacks on users.

Another benefit of this approach is even if I gave `AuthAccount` access with capability to someone; I can prevent them from updating/deleting contracts on my account or adding/revoking public keys.

### Backwards compatibility

Most of the transactions on the network don’t involve these actions, so the impact would be minimal. Some contracts may need to be updated.

---

<div class="post-metadata">

**Author:** ![dete](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.flow.com/dete/32/189_2.png) [@dete](https://forum.flow.com/u/dete)\
**Post date:** [February 1, 2023, 1:27am UTC](https://forum.flow.com/t/super-user-account/4088/2 "2023-02-01T01:27:48Z")

</div>

Sorry I missed this when you first posted it, @bluesign!

What do you think about implementing this as three different interfaces on AuthAccount: `Storage` , `Capabilities` , and `Administrative`?

The first would be “normal access to ‘stuff’ in your account storage”. (i.e. This transaction can access your things.)

The second would be “creating new Capabilities” (i.e. This transaction can grant ongoing access to a subset of your things.)

The last one would be “adding keys” and “deploying contracts” (and – once implemented – creating AuthAccount Capabilities). (i.e. This transaction can grant ongoing access to ALL of your things.)

So, for a normal transaction, we’d replace:  
`(signer: AuthAccount)` ➡`(signer: AuthAccount{Storage})`

And to change a key, you’d need to replace:  
`(signer: AuthAccount)` ➡`(signer: AuthAccount{Administrative})`.

I see three options for how to handle legacy transaction templates:

1. Make `AuthAccount` (without any interface limitations) invalid, breaking all legacy transactions
2. Interpret `AuthAccount` (without any interface limitations) as `AuthAccount{Storage}`, breaking only transactions that add keys/deploy code
3. Interpret `AuthAccount` as unrestricted (the way Cadence typically works), which breaks no legacy transactions, but which leaves a big security hole open

My suggestion would be to implement option 2 temporarily, and move to option 1 in the long run.

(FWIW- @bluesign’s original suggestion would cause breakage similar to Option 2.)

---

<div class="post-metadata">

**Author:** ![bastian](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.flow.com/bastian/32/183_2.png) [@bastian](https://forum.flow.com/u/bastian)\
**Post date:** [February 1, 2023, 9:48pm UTC](https://forum.flow.com/t/super-user-account/4088/3 "2023-02-01T21:48:17Z")

</div>

Adding interfaces for `AuthAccount` and allowing/using restricted types in `prepare`'s parameter list had been proposed quite a while ago, it’s great to see more support for this idea now.

I like the idea of grouping the granted access as lined out, but e.g. `Administrative` seems too broad and not well-defined – e.g. some storage operations might also be “administrative”. We already namespace administrative operations, e.g. key managements as `AuthAccount.keys`, so maybe it makes sense to have an interfaces for each namespace (e.g. keys, contracts, etc.).

How would this fit in with the [currently proposed changes to downcasting](https://github.com/onflow/flips/pull/54)? The FLIP proposes to allow arbitrary downcasting, effectively removing restricted types (`T{Us}`). I guess each of the proposed interfaces which grant access to certain functionality would become an “entitlement”?

Also related is the discussion around owned values vs references that [came up in the capability controllers FLIP](https://github.com/onflow/flow/pull/798#issuecomment-1325342206): Currently `AuthAccount` is a value type – but actually has reference semantics internally. It might make sense to change uses of `AuthAccount` to `&AuthAccount`.

Combining both, one could imagine a signature authorizing the addition of a new key as:  
`prepare(signer: auth{AuthAccount.KeyManagement} &AuthAccount)`.

---

<div class="post-metadata">

**Author:** ![bluesign](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.flow.com/bluesign/32/1359_2.png) [@bluesign](https://forum.flow.com/u/bluesign)\
**Post date:** [February 2, 2023, 8:48am UTC](https://forum.flow.com/t/super-user-account/4088/4 "2023-02-02T08:48:01Z")

</div>

@dete

> The first would be “normal access to ‘stuff’ in your account storage”. (i.e. This transaction can access your things.)

> The second would be “creating new Capabilities” (i.e. This transaction can grant ongoing access to a subset of your things.)

I think those two are great distinctions, I am just concerned here with “creating new Capabilities” part only, as we came to a state that almost every transaction needs a capability access right now. ( with boilerplate code )

@bastian

> How would this fit in with the [currently proposed changes to downcasting](https://github.com/onflow/flips/pull/54)? The FLIP proposes to allow arbitrary downcasting, effectively removing restricted types (`T{Us}` ).

I think here all methods will be `auth` anyway

> Currently `AuthAccount` is a value type – but actually has reference semantics internally. It might make sense to change uses of `AuthAccount` to `&AuthAccount`.

this makes totally sense.

---

<div class="post-metadata">

**Author:** ![flowjosh](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.flow.com/flowjosh/32/362_2.png) [@flowjosh](https://forum.flow.com/u/flowjosh)\
**Post date:** [February 2, 2023, 6:10pm UTC](https://forum.flow.com/t/super-user-account/4088/5 "2023-02-02T18:10:49Z")

</div>

I think this is a good idea! How would the transaction know what access level to give? Would it require another signature or something, or is it as simple as just declaring the signer type as `Super` or `AuthAccount{Administrative}`

---

<div class="post-metadata">

**Author:** ![bluesign](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.flow.com/bluesign/32/1359_2.png) [@bluesign](https://forum.flow.com/u/bluesign)\
**Post date:** [February 2, 2023, 6:14pm UTC](https://forum.flow.com/t/super-user-account/4088/6 "2023-02-02T18:14:30Z")

</div>

Simply declaring signer type is the easiest. Also later can be extended more.

---

<div class="post-metadata">

**Author:** ![gio\_on\_flow](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.flow.com/gio_on_flow/32/845_2.png) [@gio\_on\_flow](https://forum.flow.com/u/gio_on_flow)\
**Post date:** [February 3, 2023, 6:27pm UTC](https://forum.flow.com/t/super-user-account/4088/7 "2023-02-03T18:27:13Z")

</div>

I really like this idea @bluesign!

> [@bastian](#):
>
> It might make sense to change uses of `AuthAccount` to `&AuthAccount`.

@bastian I agree on this, but how do you think this change would affect [Capabilities on AuthAccounts](https://github.com/onflow/cadence/issues/2151)? And on that note, I hope we’d be able to issue Capabilities on this newly proposed `SuperAuthAccount`

---

<div class="post-metadata">

**Author:** ![bastian](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.flow.com/bastian/32/183_2.png) [@bastian](https://forum.flow.com/u/bastian)\
**Post date:** [February 6, 2023, 10:29pm UTC](https://forum.flow.com/t/super-user-account/4088/8 "2023-02-06T22:29:18Z")

</div>

> [@bluesign](#):
>
> > How would this fit in with the [currently proposed changes to downcasting](https://github.com/onflow/flips/pull/54)? The FLIP proposes to allow arbitrary downcasting, effectively removing restricted types (`T{Us}` ).
> 
> I think here all methods will be `auth` anyway

Right, but given that the signer parameters are currently owned and not references (`AuthAccount` instead of `&AuthAccount`), the transaction would be able to access those `auth` functions.

Building upon [https://github.com/onflow/flips/pull/54](https://github.com/onflow/flips/pull/54), i.e. making the parameters references and introducing entitlements for the various administrative operations (like adding a key), should be a good solution.

---

<div class="post-metadata">

**Author:** ![bastian](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.flow.com/bastian/32/183_2.png) [@bastian](https://forum.flow.com/u/bastian)\
**Post date:** [February 6, 2023, 10:31pm UTC](https://forum.flow.com/t/super-user-account/4088/9 "2023-02-06T22:31:01Z")

</div>

> [@flowjosh](#):
>
> I think this is a good idea! How would the transaction know what access level to give? Would it require another signature or something, or is it as simple as just declaring the signer type as `Super` or `AuthAccount{Administrative}`

> [@bluesign](#):
>
> Simply declaring signer type is the easiest. Also later can be extended more.

Agreed! I don’t think there is any need or advantage in allowing/requiring this to be expressed in the transaction object itself, i.e. on the protocol level.  
Declaring it in the Cadence code should be sufficient, simpler, and causes fewer breakage.

---

<div class="post-metadata">

**Author:** ![bastian](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.flow.com/bastian/32/183_2.png) [@bastian](https://forum.flow.com/u/bastian)\
**Post date:** [February 6, 2023, 11:24pm UTC](https://forum.flow.com/t/super-user-account/4088/10 "2023-02-06T23:24:48Z")

</div>

> [@gio\_on\_flow](#):
>
> @bastian I agree on this, but how do you think this change would affect [Capabilities on AuthAccounts](https://github.com/onflow/cadence/issues/2151)? And on that note, I hope we’d be able to issue Capabilities on this newly proposed `SuperAuthAccount`

Borrowing capabilities always result in references, so that would align nicely.

---

<div class="post-metadata">

**Author:** ![bastian](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.flow.com/bastian/32/183_2.png) [@bastian](https://forum.flow.com/u/bastian)\
**Post date:** [February 6, 2023, 11:26pm UTC](https://forum.flow.com/t/super-user-account/4088/11 "2023-02-06T23:26:04Z")

</div>

@daniel what do you think of the currently proposed solution of building on [https://github.com/onflow/flips/pull/54](https://github.com/onflow/flips/pull/54), i.e. making signer parameters references and introducing entitlements for AuthAccount?

---

<div class="post-metadata">

**Author:** ![bastian](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.flow.com/bastian/32/183_2.png) [@bastian](https://forum.flow.com/u/bastian)\
**Post date:** [February 6, 2023, 11:27pm UTC](https://forum.flow.com/t/super-user-account/4088/12 "2023-02-06T23:27:11Z")

</div>

@bluesign would you be OK with me opening a FLIP for this proposal?

---

<div class="post-metadata">

**Author:** ![bluesign](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.flow.com/bluesign/32/1359_2.png) [@bluesign](https://forum.flow.com/u/bluesign)\
**Post date:** [February 7, 2023, 12:15am UTC](https://forum.flow.com/t/super-user-account/4088/13 "2023-02-07T00:15:44Z")

</div>

that would be great, thank you very much

---

<div class="post-metadata">

**Author:** ![daniel](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.flow.com/daniel/32/77_2.png) [@daniel](https://forum.flow.com/u/daniel)\
**Post date:** [February 7, 2023, 4:58pm UTC](https://forum.flow.com/t/super-user-account/4088/14 "2023-02-07T16:58:03Z")

</div>

My understanding of the problem is that a security mechanism has to be included to prevent a potential malicious party from secretly adding additional keys (or deploying a contract) to an existing account.

But:

- a malicious site can propose transactions to empty an account without adding new keys
- a user’s keys may be stolen by a malicious party, that would then use them to send transactions that would drain the account without adding fresh keys
- wallets need to add support for the new `sudo` mode, but in that case wallets could implement a `safe-mode` and only allow audited transactions (FLIX)

---

<div class="post-metadata">

**Author:** ![bastian](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.flow.com/bastian/32/183_2.png) [@bastian](https://forum.flow.com/u/bastian)\
**Post date:** [February 7, 2023, 6:50pm UTC](https://forum.flow.com/t/super-user-account/4088/15 "2023-02-07T18:50:41Z")

</div>

While thinking through how entitlements for accounts could look like it occurred to me that we do not even need the distinction between `AuthAccount` and `PublicAccount` anymore.

Here is an example of how a refactoring a part of the account type could look like:

```auto
struct interface ContractAdmin {

    auth(ContractAdmin) let contractAdmin: auth &Account.Contracts
}

// ... other entitlement interfaces granting access to keys, capabilities, etc.

struct Account: ContractAdmin {

    let address: Address

    // ... other fields, functions, and types

    let contracts: &Account.Contracts

    auth(ContractAdmin) let contractAdmin: auth &Account.Contracts

    struct Contracts {

        fun get(name: String): DeployedContract?

        auth fun update__experimental(name: String, code: [UInt8]): DeployedContract

        // ... other fields and functions
    }
}

```

- We would only have one type `Account`
- Previous uses of `PublicAccount` would become `&Account`. Note that the reference is non-`auth`, meaning that informational fields like `address`, but also fields like `contracts` could be accessed and would allow “read-only operations”.
- Previous uses of `AuthAccount` would become `auth &Account`, effectively granting access to all `auth` fields
- A signer type `auth(ContractAdmin) &Account` would only allow access to managing contracts, but not to e.g. managing keys
- One small downside is that we would need to expose two fields for each nested reference, one non-`auth` and one `auth`, e.g. `contracts` and `contractAdmin`
- (Note that naming is just strawman syntax, suggestions welcome)

@sainati Did I apply [https://github.com/onflow/flips/pull/54](https://github.com/onflow/flips/pull/54) here correctly?

---

<div class="post-metadata">

**Author:** ![sainati](https://avatars.discourse-cdn.com/v4/letter/s/f1d935/32.png) [@sainati](https://forum.flow.com/u/sainati)\
**Post date:** [February 7, 2023, 7:02pm UTC](https://forum.flow.com/t/super-user-account/4088/16 "2023-02-07T19:02:55Z")

</div>

I really like this idea! I’ve advocated for having interfaces to separate out the functionality of `AuthAccount` before, and this idea I think takes that one step further to its logical conclusion. This would be a great use of the entitlements idea.

> Did I apply [https://github.com/onflow/flips/pull/54](https://github.com/onflow/flips/pull/54) here correctly?

The exact syntax is a bit up in the air I think right now, but the concept is correctly used, yeah.

> Previous uses of `AuthAccount` would become `auth &Account`

We may not allow `auth` (without modifiers) to be used to mean “full access”, as full, unfettered access to the reference is not a great default behavior for this, I think. Instead we might have an “owner” entitlement, or allow the composite type `Account` itself to be used as an entitlement. So this might instead look like `auth(Account) &Account`.

> One small downside is that we would need to expose two fields for each nested reference, one non-`auth` and one `auth`, e.g. `contracts` and `contractAdmin`

This suggests it might be useful for us to have parametric entitlements; some way to have the entitlements on a field reference be dependent on the entitlements on the parent reference. This is essentially the proposal that the FLIP uses for attachments, but perhaps we could generalize this further.

---

<div class="post-metadata">

**Author:** ![bluesign](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.flow.com/bluesign/32/1359_2.png) [@bluesign](https://forum.flow.com/u/bluesign)\
**Post date:** [February 8, 2023, 8:31am UTC](https://forum.flow.com/t/super-user-account/4088/17 "2023-02-08T08:31:33Z")

</div>

Can’t we make this to work somehow without duplicate fields ? We only have references as member types in built-types. Maybe we can simply define a rule for them.

---

<div class="post-metadata">

**Author:** ![bastian](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.flow.com/bastian/32/183_2.png) [@bastian](https://forum.flow.com/u/bastian)\
**Post date:** [February 8, 2023, 9:25pm UTC](https://forum.flow.com/t/super-user-account/4088/18 "2023-02-08T21:25:12Z")

</div>

Agreed, it would be nice to avoid having two fields per “nested object” (“administration domain”?).

It would be great to not have special rules for certain types, but to have a general feature to express this.

---

<div class="post-metadata">

**Author:** ![bluesign](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.flow.com/bluesign/32/1359_2.png) [@bluesign](https://forum.flow.com/u/bluesign)\
**Post date:** [February 9, 2023, 11:43am UTC](https://forum.flow.com/t/super-user-account/4088/19 "2023-02-09T11:43:48Z")

</div>

can something like this work ?

```auto
struct Account: ContractAdmin {
    let address: Address
    let contracts: Account.Contracts
    struct Contracts {
        fun get(name: String): DeployedContract?
        auth(ContractAdmin) fun update__experimental(name: String, code: [UInt8]): DeployedContract
    }
}

```

---

<div class="post-metadata">

**Author:** ![bastian](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.flow.com/bastian/32/183_2.png) [@bastian](https://forum.flow.com/u/bastian)\
**Post date:** [February 15, 2023, 11:00pm UTC](https://forum.flow.com/t/super-user-account/4088/20 "2023-02-15T23:00:46Z")

</div>

As far as I understand the FLIP ([https://github.com/onflow/flips/pull/54](https://github.com/onflow/flips/pull/54)), `let contracts: Account.Contracts` would give out “owned access”, so no matter if the reference to the account would be auth or not, the field gives out owned access and this allows accessing auth members (e.g. the update function).

Is my understanding correct @sainati?

[Next page](https://forum.flow.com/t/super-user-account/4088.md?page=2)
