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