A read-only clone of the dehub project, for until dehub.dev can be brought back online.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
dehub/docs/tut2.md

263 lines
7.8 KiB

# 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.