# 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:** 7\
**Page:** 2

<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 16, 2023, 7:15am UTC](https://forum.flow.com/t/super-user-account/4088/21 "2023-02-16T07:15:40Z")

</div>

I was assuming ‘auth &Account’ would be old AuthAccount, ‘&Account’ would be old PublicAccount.

---

<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 16, 2023, 2:35pm UTC](https://forum.flow.com/t/super-user-account/4088/22 "2023-02-16T14:35:53Z")

</div>

Yeah if someone actually possesses the concrete value (as opposed to a reference to it) they would have “owned access”, as you put it, allowing them to access anything and everything on the composite that isn’t private. It’s a little weird to think about this in the case of a `struct` because I guess more than one person could have “owned access” to that struct at a time though.

---

<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 18, 2023, 12:22am UTC](https://forum.flow.com/t/super-user-account/4088/23 "2023-02-18T00:22:58Z")

</div>

How do we feel about the proposed idea in [Super User Account - #15 by bastian](http://forum.flow.com/t/super-user-account/4088/15)?

In the example I’m using an interface for `ContractAdmin`, but as discussed in [https://github.com/onflow/flips/pull/54](https://github.com/onflow/flips/pull/54), this would now be an `entitlement` declaration.

If we feel like this is a good start I could write up a full definition for `Account` and open a FLIP.

---

<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 18, 2023, 8:44am UTC](https://forum.flow.com/t/super-user-account/4088/24 "2023-02-18T08:44:00Z")

</div>

I think it is great @bastian

---

<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 24, 2023, 11:33pm UTC](https://forum.flow.com/t/super-user-account/4088/25 "2023-02-24T23:33:25Z")

</div>

While trying to continue with writing entitlements for the account type, as started in [Super User Account - #15 by bastian](http://forum.flow.com/t/super-user-account/4088/15), I realized that the problem mentioned above becomes increasingly prevalent when trying to encourage

- Composition, i.e. breaking functionality into smaller pieces, e.g. separate key from contract management
- Fine-grained permissions, e.g. having separate entitlements for contract addition and contract update

Basically, for each nested function with an entitlement, the outer container needs a separate member to expose it.

For example, to keep contract management separate, by having the functionality in a separate nested type instead of directly on the container type (`Account`), and to have separate entitlements for contract additions and updates:

```auto
entitlement ContractDeployment {
    fun add(
        name: String,
        code: [UInt8],
        ... contractInitializerArguments
    ): DeployedContract
}

entitlement ContractsDeployment {
    let contractsDeployment: auth(ContractDeployment) &Account.Contracts
}

entitlement ContractUpdate {
    fun update__experimental(
        name: String,
        code: [UInt8]
    ): DeployedContract
}

entitlement ContractsUpdate {
    let contractsUpdate: auth(ContractUpdate) &Account.Contracts
}

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

struct Account {

    let address: Address

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

    // expose "read-only" contract operations (e.g. Account.Contracts.get)
    let contracts: &Account.Contracts

    // expose contract deployment operation
    access(ContractsDeployment) let contractsDeployment: auth(ContractDeployment) &Account.Contracts

    // expose contract update operation
    access(ContractsUpdate) let contractsUpdate: auth(ContractUpdate) &Account.Contracts

    struct Contracts {

        fun get(name: String): DeployedContract?

        access(ContractDeployment) fun add(
            name: String,
            code: [UInt8],
            ... contractInitializerArguments
        ): DeployedContract

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

        // ... other fields and functions
    }
}

```

This would allow for example a type like `auth(ContractsDeployment) &Account`, which only authorizes access to the contract deployment operation, but not the contract update operation.

Alternatives:

- Flatten the types and functions, have all operations on `Account`. This seems counter to the composition principle, so I’d like to avoid that
- Less fine grained entitlements
- Polymorphic access: It would be nice to express that having access to a type translates to access to a nested object (e.g. authorizations for the `Account` type translate to authorizations on the `Account.Contracts` type)
- ?

---

<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 25, 2023, 6:08pm UTC](https://forum.flow.com/t/super-user-account/4088/26 "2023-02-25T18:08:26Z")

</div>

> [@bastian](#):
>
> - Polymorphic access: It would be nice to express that having access to a type translates to access to a nested object (e.g. authorizations for the `Account` type translate to authorizations on the `Account.Contracts` type)

My vote is on this, Maybe something like:

```swift
struct Account {

    let address: Address

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

    let contracts: auth(self) &Account.Contracts

    struct Contracts {

        fun get(name: String): DeployedContract?

        access(ContractDeployment) fun add(
            name: String,
            code: [UInt8],
            ... contractInitializerArguments
        ): DeployedContract

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

        // ... other fields and functions
    }
}

```

so auth(self) can inherit the entitlements.

---

<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:** [May 26, 2023, 10:41pm UTC](https://forum.flow.com/t/super-user-account/4088/27 "2023-05-26T22:41:08Z")

</div>

Now that the entitlements FLIP has been approved, I have opened a FLIP for refactoring the `AuthAccount` and `PublicAccount` types into a single `Account` type:

> <https://github.com/onflow/flips/pull/92>
>
> The goal of this proposal is to improve how Cadence provides access to accounts.…
> 
> The proposed API aims to make account access simpler and safer, by enabling and encouraging the principle of least authority (PoLA) for account access.
> 
> This FLIP is based on previous discussion in https://forum.onflow.org/t/super-user-account/4088

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