# Tutorial 2: Access Controls Access controls, in the context of a dehub project, refer to configuration defining who is allowed to do what. These controls are defined within the dehub project itself, within the `.dehub/config.yml` file. This tutorial will guide you through the basics of how access controls work, how to define them, and some examples of what can be done with them. This tutorial assumes you have already completed [Tutorial 1](tut1.html), and builds on top of the project which was started there. ## Step 0: Create a Restricted Account Inside the project you started in [Tutorial 1](tut1.html) you're going to add another account to the project, called `tot`. Initially, `tot` will have all the same permissions as `tut`, except being allowed to modify the project configuration. First, export your gpg key into the project for `tot` to use, the same key used for `tut`: ``` gpg -a --export KEY_ID > .dehub/tot.asc ``` (For the purposes of a tutorial it's fine for two accounts to share a key, but it's not something which generally makes sense to do.) Now, modify the `.dehub/config.yml` to have the following contents: ```yaml # contents of .dehub/config.yml --- accounts: - id: tut signifiers: - type: pgp_public_key_file path: ".dehub/tut.asc" - id: tot signifiers: - type: pgp_public_key_file path: ".dehub/tot.asc" access_controls: - action: allow filters: - type: signature account_ids: - tut - type: files_changed pattern: .dehub/* - action: deny filters: - type: files_changed pattern: .dehub/* ``` The `accounts` section has been modified to add the `tot` account, but the primary change here has been to add the `access_controls` section. The next sub-sections will explain what exactly is being done here, but for now go ahead and commit these changes: ``` git add --all dehub commit --as tut change --descr 'add new restricted tot account' ``` ### Access Controls Each access control is an action+filters pair. For any commit being verified, the access controls defined in its parent commit are iterated through, in order, until one is found whose filters all match the commit being verified. The action for that access control, either `allow` or `deny`, is then taken. If no access controls are defined, or none match, then the default access controls are used. These are explicitly defined in the [SPEC](SPEC.html#default-access-controls), but the general effect of them is to require that all commits have one signature from any of the project's accounts. ### Access Control Filters There are many different filter types, so only the ones used in the tutorial will be explained. An exhaustive listing can be found in the [SPEC](SPEC.html#filter). The `signature` filter matches commits which have a signature credential created by any one of the specified accounts. The `files_changed` filter matches commits which have changed files whose paths match the specified patterns (relative to the project's root). ### Putting it Together The first of the new actions controls you've defined is: ``` - action: allow filters: - type: signature account_ids: - tut - type: files_changed pattern: .dehub/* ``` This allows any commits which have been signed by `tut` and which modify any of the files in `.dehub/*`. The second access control is: ``` - action: deny filters: - type: files_changed pattern: .dehub/* ``` This denies any commits which modify any of the files in `.dehub/*`. If a commit does not match the first access control, but does match this second access control, it can be assumed that the commit does _not_ have a signature from `tut` (because that's the only difference between them). Therefore, the effect of these two controls put together is to only allow `tut` to make changes to the `.dehub` directory's files. ## Step 1: Test the Restrictions Let's say that your new user `tot` is having a bit of rebellious phase, and wants to kick `tut` out of the project. Change `.dehub/config.yml` to have the following contents (note that `accounts` has been left the same and so is mostly elided): ``` # abbreviated contents of .dehub/config.yml --- accounts: ... access_controls: - action: deny filters: - type: signature account_ids: - tut ``` So edgy. Make the commit for `tot`, being sure that the value for the `--as` flag indicates you're committing _as_ `tot`: ``` git add --all dehub commit --as tot change --descr 'tut is a butt' ``` Somewhat unexpectedly, the commit has been created! You can see it by doing `git show`. This shouldn't be possible though, because the previous commit disallowed anyone but `tut` from changing files within the `.dehub/` directory. Is dehub broken? The fact is that, regardless of whether or not the `dehub` tool allows one to create this commit, `tot` can create this commit. The important thing is that `tut` is able to notice that it's been created and do something about it. In a real-world situation, both `tot` and `tut` would be using different computers, and when `tut` (or anyone else) receives the commit from `tot` they will try to verify it, fail to do so, and ignore it. If you perform `dehub verify` you will be greeted with the following error: ``` exiting: blah blah blah: commit matched and denied by this access control: action: deny filters: - type: files_changed pattern: .dehub/* ``` Because the parent of this commit's config disallows this commit (via the given access control) it is not verifiable. Go ahead and delete the commit by doing: ``` git reset --hard "$(git rev-list HEAD | tail -3 | head -n1)" ``` ## Step 2: Different Restrictions In light of `tot`'s recent actions it might be prudent to pull back their permissions a bit. Go ahead and change the `.dehub/config.yml` to: ``` # abbreviated contents of .dehub/config.yml --- accounts: ... access_controls: - action: allow filters: - type: signature account_ids: - tot - type: branch pattern: tot/* - action: deny filters: - type: signature account_ids: - tot ``` and commit the change: ``` git add --all dehub commit --as tut change --descr 'restrict tot to non-main branches' ``` After this, `tot` will still be able to interact with the project, but only within branches whose names have the prefix `tot/`; the `main` branch remains open to other accounts, such as `tut`, due to the default access controls. ### Check the New Restrictions `tot` has decided to do something constructive and wants to make a shell script which wraps the `echo` command. So helpful. Make a new branch for `tot` to use, and create a commit on it: ``` git checkout -b tot/echo-script echo 'echo "$@"' > echo.sh git add echo.sh dehub commit --as tot change --descr "added echo.sh script" ``` Check that the commit verifies (it should, since it's on a branch with the prefix `tot/`): ``` dehub verify ``` Now, as a final sanity check, you'll cherry-pick the commit onto `main` and ensure that it does _not_ verify there. ``` git checkout main git cherry-pick tot/echo-script ``` Running `dehub verify` now should fail, even though the commit remains the same. The only difference is the branch name; the commit is allowed in branches with the prefix `tot/`, and disallowed otherwise. Finally, reverse that cherry-pick to make `main` verifiable again: ``` git reset --hard "$(git rev-list HEAD | tail -4 | head -n1)" ``` You now have an understanding of how dehub's access controls work. Access controls are extremely flexible and can be formulated to fit a wide-variety of use-cases. In [Tutorial 3](tut3.html) we'll see how access controls can be formulated to allow for commit sign-offs, where multiple accounts must accredit a commit before it can be verified, and how such a commit can be created.