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, 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 you're going to add
another account to the project, called
tot will have all the
same permissions as
tut, except being allowed to modify the project
First, export your gpg key into the project for
tot to use, the same key used
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:
# 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/*
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'
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
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, 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.
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
# 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
flag indicates you're committing as
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
tut from changing files within the
.dehub/ directory. Is dehub
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
tut would be using different computers,
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
# 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'
tot will still be able to interact with the project, but only
within branches whose names have the prefix
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
Now, as a final sanity check, you'll cherry-pick the commit onto
ensure that it does not verify there.
git checkout main git cherry-pick tot/echo-script
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
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 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.