--- type: change description: Re-organize and flesh-out documentation, including writing the tutorials fingerprint: AP5oeODaJO4eq84LRE3rlFgEVGyPa3OywpyftSgsrx13 credentials: - type: pgp_signature pub_key_id: 95C46FA6A41148AC body: iQIzBAABAgAdFiEEJ6tQKp6olvZKJ0lwlcRvpqQRSKwFAl7VRQ8ACgkQlcRvpqQRSKwgPg//R95XdGAKyC5Db0n94rHGW9LY9bcnmIe3WEQlQu2UFLJWzwGk0xJNPHugBz7tKqzEMQ+dQJ6Dl1/UjoCzMfr70Bwv26hAJa+CYLwq0qOoAqmCNZkxBREvlQfGV6E82P3iXZVOsFyNyUUTJEsM9ZdOUQB7+wnBHqw67gsTqOkS/6xXr5EPvUZeyASdG2epgHIh+DciDo6O9h6rBjMtyTgOFkCOCHKsZN8a5elAl+LaRaNWh05DJSh3y0VwPlEqfuR+zph8r5Q64aIJEY2ZA8a91T2SJQhBnUVjZ6H9nEqdhuq3bVbxgGdcZoX07pJIFIaqwIICkzEuxGtuRT0PZUC4yz2fjoiI7ykVTEN5urVOXL+vfZbgbklyST+BAUg5Qlac7fD9CP7nlGQ+alcXwL2cHBkXfRZedzw+MCyn/Qph0cNPE10uzwgR3pSWx2Sr6FOaBW/CXSH9y9rhcSF38jgXA6XirSOy3GpqfwHQaC9ol5Vm2R948XS2u0qJV3RZlcuylE62ST4K8pOiHn97HrGZnfG7TyyiYNvWjAq9avYwNhd3klWpgLs+OrgFN+f08xQxqnVbVEpwKLCwXmhRMyW7UVDRgoGTcfB7MVvWVxqbE3/f9VawF/baX4q324f+cMVkchyk0UeGnV30pJrWoDSw3UN3FAQoS/PYWNW3dZgp5F0= account: mediocregophermain
parent
a1579dcc96
commit
a709a43696
@ -0,0 +1,128 @@ |
||||
# Tutorial 0: Say Hello! |
||||
|
||||
This tutorial will guide you through cloning a dehub project locally, creating a |
||||
comment, and pushing that comment back up to the remote. The project in |
||||
question: dehub itself! |
||||
|
||||
This tutorial assumes you have [dehub installed](/index.html#getting-started), |
||||
you have git and gpg installed, and you have a gpg key already created. |
||||
|
||||
## Step 0: Clone the Project |
||||
|
||||
Cloning the dehub project is as simple as cloning its git repo: |
||||
|
||||
``` |
||||
git clone https://dehub.dev/src/dehub.git |
||||
cd dehub |
||||
``` |
||||
|
||||
Once cloned, feel free to look around the project. You should initially find |
||||
yourself on the `main` branch, the primary branch of most dehub projects |
||||
(analogous to the `master` branch of most git repos). |
||||
|
||||
Calling `git log` will show the commits messages for all commits in the branch. |
||||
You will notice the commit messages aren't formatted in the familiar way, for |
||||
example: |
||||
|
||||
``` |
||||
commit 351048e9aabef7dc0f99b00f02547e409859a33f |
||||
Author: mediocregopher <> |
||||
Date: Sat Apr 25 15:17:21 2020 -0600 |
||||
|
||||
Completely rewrite SPEC |
||||
|
||||
--- |
||||
type: change |
||||
description: |- |
||||
Completely rewrite SPEC |
||||
|
||||
It's good this time, and complete. After this rewrite it will be necessary to |
||||
update a lot of the code, since quite a few things got renamed. |
||||
fingerprint: AG0s3yILU+0uIZltVY7A9/cgxr/pXk2MzGwExsY/hbIc |
||||
credentials: |
||||
- type: pgp_signature |
||||
pub_key_id: 95C46FA6A41148AC |
||||
body: BIG LONG STRING |
||||
account: mediocregopher |
||||
``` |
||||
|
||||
Instead of just being a human-readable description they are YAML encoded payload |
||||
objects. We will dive into these payload objects more throughout this tutorial |
||||
series. |
||||
|
||||
## Step 1: Checkout the Welcome Branch |
||||
|
||||
Next you're going to checkout the public welcome branch. This is done through a |
||||
normal git checkout command: |
||||
|
||||
``` |
||||
git checkout public/welcome |
||||
``` |
||||
|
||||
You can do `git log` to see all the comments people have been leaving in this |
||||
branch. The `public/welcome` branch is differentiated from the `main` branch in |
||||
two ways: |
||||
|
||||
* It has been configured to allow comment commits from anonymous users to be |
||||
pushed to it. Project configuration is covered in a future tutorial. |
||||
|
||||
* It has no code files tracked, its only purpose is for comments. |
||||
|
||||
## Step 2: Create Your Comment |
||||
|
||||
Now that you've poked around the welcome branch a bit, it's time to leave a |
||||
comment of your own! This is as easy as doing: |
||||
|
||||
``` |
||||
dehub commit --anon-pgp-key=KEY_NAME comment |
||||
``` |
||||
|
||||
(`KEY_NAME` should be replaced with any selector which will match your pgp key, |
||||
such as the key ID, the name on the key, or the email.) |
||||
|
||||
Your default text editor (defined by the EDITOR environment variable) will pop |
||||
up and you can then write down your comment. When you save and close your editor |
||||
dehub will sign the comment with your pgp key and create a commit with it. |
||||
|
||||
If you're having trouble thinking of something to say, here's some prompts to |
||||
get you going: |
||||
|
||||
* Introduce yourself; say where you're from and what your interests are. |
||||
|
||||
* How did you find dehub? Why is it interesting to you? |
||||
|
||||
* If you're using dehub for a project, shill your project! |
||||
|
||||
* If you'd like to get involved in dehub's development, let us know what your |
||||
skills are and how you can help. Remember, it takes more than expert |
||||
programmers to make a project successful. |
||||
|
||||
Once you've created your commit you can call `git log` to verify that it's been |
||||
created to your liking. If there's anything about the comment you'd like to |
||||
change you can amend the commit like so: |
||||
|
||||
``` |
||||
dehub commit --anon-pgp-key=KEY_NAME comment --amend |
||||
``` |
||||
|
||||
## Step 3: Push Your Commit |
||||
|
||||
As of now your comment commit only exists on your local machine. For everyone |
||||
else to see it you'll need to push it to the dehub server, exactly like with a |
||||
normal git commit. Pushing is done in the same way as a normal git commit as |
||||
well: `git push`. |
||||
|
||||
If you receive an error that's like `Updates were rejected because the tip of |
||||
your current branch is behind` then someone else has pushed to the branch in |
||||
between the last time you pulled and now. Do a `git pull --rebase` to pull in |
||||
those new changes, and try pushing again. |
||||
|
||||
## Step 4: Follow the Conversation |
||||
|
||||
In order to see other people's responses to your comment, and all other parts of |
||||
the conversation, all you need to do is call `git pull` with the |
||||
`public/welcome` branch checked out. |
||||
|
||||
You now have all the tools needed to participate in a dehub discussion thread! |
||||
Continue on to [Tutorial 1](tut1.html) to set up your own dehub project and |
||||
learn about credentials and their verification. |
@ -0,0 +1,178 @@ |
||||
# Tutorial 1: Create Your Own Project |
||||
|
||||
This tutorial will guide you through starting a dehub project of your own, as |
||||
well as introducing some basic concepts regarding how commit payloads work. You |
||||
will use an example hello world project to do this. |
||||
|
||||
This tutorial assumes you have already completed [Tutorial 0](tut0.html). |
||||
|
||||
## Step 0: Init the Project |
||||
|
||||
A dehub project is initialized in the same way as a git project. An empty |
||||
directory is created, and `dehub init` is run within that directory. |
||||
|
||||
``` |
||||
mkdir hello-world |
||||
cd hello-world |
||||
dehub init |
||||
``` |
||||
|
||||
`dehub init` does nearly exactly the same thing as `git init`, with the primary |
||||
difference being that it sets the initial branch to be `main` instead of |
||||
`master`. dehub makes a distinction between `main` and `master` in order to help |
||||
prevent confusion between dehub and vanilla git projects, as well as to avoid |
||||
conflicts when migrating vanilla git projects to dehub. |
||||
|
||||
## Step 1: Add the First Account |
||||
|
||||
A dehub project is not fully initialized until it has an account defined for it. |
||||
dehub accounts refer to a specific user who has some kind of access to the |
||||
project. Each account can have specific permissions for it, as well as multiple |
||||
ways of signifying itself. |
||||
|
||||
For now, you'll add a basic account `tut` with a pgp key signifier. First, |
||||
create the `.dehub` directory, which is where all dehub project configuration |
||||
goes, and put your pgp key there: |
||||
|
||||
``` |
||||
mkdir .dehub |
||||
gpg -a --export KEY_ID > .dehub/tut.asc |
||||
``` |
||||
|
||||
Next you'll create the `.dehub/config.yml` file, which is where accounts are |
||||
actually defined (amongst many other things). The file should have the following |
||||
contents: |
||||
|
||||
```yaml |
||||
# contents of .dehub/config.yml |
||||
--- |
||||
accounts: |
||||
- id: tut |
||||
signifiers: |
||||
- type: pgp_public_key_file |
||||
path: ".dehub/tut.asc" |
||||
``` |
||||
|
||||
Finally, you'll commit these changes and the project will have its first commit! |
||||
Committing changes works very similarly to committing comments (as you did in |
||||
[Tutorial 0](tut0.html)). Where a comment commit merely carries a user's |
||||
comment, a change commit describes a set of changes to the tracked files in the |
||||
git repo. |
||||
|
||||
``` |
||||
git add --all |
||||
dehub commit --as tut change |
||||
``` |
||||
|
||||
Like when you made a comment commit this will pop up with your editor asking for |
||||
a description of the changes. Fill it in with something like `Initialize the |
||||
project` and save/close the editor. Depending on your pgp key settings you'll |
||||
likely be prompted for your pgp key password at this point. After that the |
||||
commit has been created! |
||||
|
||||
## Step 2: Inspect the Payload |
||||
|
||||
In this step you're going to look at the commit you just created and learn about |
||||
the contents of the payload. To view the commit do `git show`. Something similar |
||||
to the following should be output as the commit message: |
||||
|
||||
``` |
||||
commit 3cdcbc19546d4e6d817ebfba3e18afbc23283ec0 |
||||
Author: username <> |
||||
Date: Sat Apr 25 15:17:21 2020 -0600 |
||||
|
||||
Initialize the project |
||||
|
||||
--- |
||||
type: change |
||||
description: Initialize the project |
||||
fingerprint: AG0s3yILU+0uIZltVY7A9/cgxr/pXk2MzGwExsY/hbIc |
||||
credentials: |
||||
- type: pgp_signature |
||||
pub_key_id: 95C46FA6A41148AC |
||||
body: BIG LONG STRING |
||||
account: tut |
||||
``` |
||||
|
||||
All commits in a dehub project will contain a similar looking message. The first |
||||
line (the head) is always a human readable description of the commit. In this |
||||
case our commit description itself, `Initialize the project`, was used. |
||||
|
||||
After the head comes the payload, which is always a YAML encoded object. All |
||||
payloads have a `type` field indicating what type of payload they are. That type |
||||
will determine what other fields the payload is expected to have. The other |
||||
fields in this payload object are: |
||||
|
||||
* `description`: This is the description which was input into the editor when |
||||
creating the change commit. |
||||
|
||||
* `fingerprint`: A unique descriptor for this set of changes. It is computed |
||||
using both `description` and the files changed. |
||||
|
||||
* `credentials`: A set of credentials for this commit, each one declaring |
||||
that this commit has been given approval by a user. This commit has one |
||||
`pgp_signature` credential, created by the `tut` account. The `body` is a |
||||
signature of the `fingerprint` created by the `tut`'s pgp key. |
||||
|
||||
## Step 3: Create Another Commit |
||||
|
||||
Now that the initial commit is created, and configuration has been added to the |
||||
dehub project, you can continue on to use the project for what it was intended |
||||
for: greeting the world! |
||||
|
||||
Add a simple "hello world" script to the project by doing: |
||||
|
||||
``` |
||||
echo 'echo "hello world"' > hello.sh |
||||
git add hello.sh |
||||
dehub commit --as tut change --descr 'add hello.sh' |
||||
``` |
||||
|
||||
You'll notice that this time around you used the `--descr` flag to declare the |
||||
change's description, rather than opening up the editor |
||||
|
||||
Once again you can inspect the payload you just created using `git show`, if |
||||
you'd like, or continue on to the next step to learn about commit verification. |
||||
|
||||
## Step 4: Verify Your Commits |
||||
|
||||
All this work to create YAML encoded payloads has been done for one primary |
||||
purpose: to make commits verifiable. A verifiable commit is one which follows |
||||
the access controls defined by its parent. |
||||
|
||||
Your dehub project doesn't have any explicitly defined access controls (that |
||||
will be covered in a future tutorial), and so the defaults are used. By default, |
||||
dehub requires that all commits in `main` are change commits which have been |
||||
signed by at least one account. |
||||
|
||||
In order to verify the HEAD commit you can do: |
||||
|
||||
``` |
||||
dehub verify |
||||
``` |
||||
|
||||
This command looks at the project configuration defined in the parent of HEAD |
||||
and verifies that HEAD conforms to it. The HEAD of your project is a change |
||||
commit signed by the account `tut`, and so should be verifiable. |
||||
|
||||
Arbitrary commits can be verified using the `--rev` flag. This command will |
||||
verify the parent of HEAD, i.e. the initial commit: |
||||
|
||||
``` |
||||
dehub verify --rev HEAD^ |
||||
``` |
||||
|
||||
The initial commit doesn't have a parent, and so is a special case for |
||||
verification. The initial commit uses the configuration defined within itself in |
||||
order to verify itself. This creates an exploit opportunity: if you clone a |
||||
remote dehub project and an attacker intercepts that request they will be able |
||||
to send you back a project with a different initial commit than what you |
||||
expected. The whole project will still be verifiable, even though it's been |
||||
compromised. For this reason it's important to manually verify that the initial |
||||
commit of projects you clone are configured correctly, using the expected |
||||
signifiers for the expected accounts. |
||||
|
||||
You are now able to initialize a project, configure accounts within it, commit |
||||
changes to its files, and verify those commits. Well done! Continue on to |
||||
[Tutorial 2](tut2.html), where you will learn how to configure dehub's access |
||||
controls. |
@ -0,0 +1,259 @@ |
||||
# 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), 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). |
||||
|
||||
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`. Is dehub broken? |
||||
|
||||
The fact is that, regardless of whether or not the `dehub` tool allows one to |
||||
create this commit, `tut` can create this commit. The important thing is that |
||||
`tot` 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 `tot` (or anyone else) receives the commit from `tut` 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. |
@ -0,0 +1,247 @@ |
||||
# Tutorial 3: Commit Sign-Off |
||||
|
||||
Commit sign-off is a common pattern in vanilla git projects, where a commit must |
||||
be approved by one or more people (besides the commit author themselves) in |
||||
order to be allowed into the primary branch. |
||||
|
||||
dehub is able to accomplish this same pattern using only the access controls |
||||
which have already been covered in this tutorial series and a command which has |
||||
not: `dehub combine`. This tutorial will guide you through using `dehub combine` |
||||
to facilitate commit sign-off. |
||||
|
||||
This tutorial assumes you have already completed [Tutorial 2](tut2.html), and |
||||
builds on top of the project which was started there. |
||||
|
||||
## Step 0: Loosen the Previous Restrictions |
||||
|
||||
In the [previous tutorial](tut2.html) you took an existing project, added a new |
||||
user `tot` to it, and then restricted `tot` to only be allowed to make commits |
||||
in a certain subset of branches which excluded the `main` branch. |
||||
|
||||
As seen in that tutorial, `tot` is not able to create commits for the `main` |
||||
branch _at all_. In this tutorial we're going to open `main` back up to `tot`, |
||||
but only with a very important caveat: `tot`'s commits must be approved by |
||||
someone else. |
||||
|
||||
In the `hello-world` project which was used for previous tutorials, with the |
||||
`main` branch checked out, go ahead and modify `.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: |
||||
- tot |
||||
- type: branch |
||||
pattern: tot/* |
||||
|
||||
- action: deny |
||||
filters: |
||||
- type: branch |
||||
pattern: main |
||||
- type: not |
||||
filter: |
||||
type: signature |
||||
any_account: true |
||||
count: 2 |
||||
``` |
||||
|
||||
and commit the changes: |
||||
|
||||
``` |
||||
git add .dehub/config.yml |
||||
dehub commit --as tut change --descr 'require commit sign-offs in main' |
||||
``` |
||||
|
||||
The primary change was to replace the old access control denying `tot` the |
||||
ability to commit to anything (outside of `tot/*` branches) with this one: |
||||
|
||||
``` |
||||
- action: deny |
||||
filters: |
||||
- type: branch |
||||
pattern: main |
||||
- type: not |
||||
filter: |
||||
type: signature |
||||
any_account: true |
||||
count: 2 |
||||
``` |
||||
|
||||
There are two new things here. The first is the new fields on the `signature` |
||||
filter: `any_account` replaces the `account_ids` field, and refers to any |
||||
account which is defined in the `accounts` section; `count` declares how many |
||||
accounts must have a signature on the commit for the filter to match (if not |
||||
specified it defaults to 1). |
||||
|
||||
The second new thing is the `not` filter: `not` wraps any other filter, and |
||||
reverses whether or not it matches. In this case, it's wrapping our `signature` |
||||
filter, such that this access control will match only if the commit _does not_ |
||||
have signature credentials from 2 different accounts. |
||||
|
||||
The total effect of this access control is to deny any commits to `main` which |
||||
do not have signature credentials from 2 different accounts. In effect, commit |
||||
sign-off. |
||||
|
||||
## Step 1: Some Changes to Merge |
||||
|
||||
In the previous tutorial `tot` created a new script, `echo.sh`, in a new branch |
||||
called `tot/echo-script`. Check that branch out, rebase it on `main` (this will |
||||
help in later steps), and add another script to it: |
||||
|
||||
``` |
||||
git checkout tot/echo-script |
||||
git rebase main |
||||
echo 'echo "$@" | awk "{ print toupper(\$0) }"' > echo-upper.sh |
||||
git add echo-upper.sh |
||||
dehub commit --as tot change --descr 'echo-upper.sh' |
||||
``` |
||||
|
||||
Now the `tot/echo-script` branch contains two commits which aren't on `main`, |
||||
both of them signed by `tot`. What will happen next is that the branch's commits |
||||
will be combined into a single commit, be given accreditation by both `tut` and |
||||
`tot`, and added to the `main` branch. |
||||
|
||||
## Step 2: Accreditation |
||||
|
||||
First, `tot` will accredit both commits, and unify the two descriptions in the |
||||
process. To do this, you will create your first `credential` commit: |
||||
|
||||
``` |
||||
dehub commit --as tot credential --start HEAD^^ --descr 'add echo.sh and echo-upper.sh' |
||||
``` |
||||
|
||||
A `credential` commit, at its core, contains nothing except credentials for any |
||||
arbitrary fingerprint. To view the credential commit you just made |
||||
do: `git show`. You should see a commit message like: |
||||
|
||||
``` |
||||
Credential of AO3dn4Se61hq6OWy4Lm6m3MxdT2ru6TrIobuHaWJJidt |
||||
|
||||
--- |
||||
type: credential |
||||
commits: |
||||
- f085f13fa839ece122476601d970460ac249dc69 # these will be different |
||||
- 40a81ffb4f52dc4149570672f7f7fc053f12226a |
||||
change_description: add echo.sh and echo-upper.sh |
||||
fingerprint: AO3dn4Se61hq6OWy4Lm6m3MxdT2ru6TrIobuHaWJJidt |
||||
credentials: |
||||
- type: pgp_signature |
||||
pub_key_id: XXX |
||||
body: BIG LONG STRING |
||||
account: tot |
||||
``` |
||||
|
||||
You'll notice that the credential commit's fingerprint is different than either |
||||
of the two commits it accredits. This is the fingerprint is based on the |
||||
_combination_ of the two commits; it is based on the total of the file changes |
||||
and the description provided by the user. The two commits are enumerated in the |
||||
`commits` field of the payload, and the description provided by the user is |
||||
stored in the `change_description` field. |
||||
|
||||
The combined commits have now been accredited by `tot`, but not `tut`, and so |
||||
they still lack a necessary credential. Have `tut` make a credential now: |
||||
|
||||
``` |
||||
dehub commit --as tut credential --rev HEAD |
||||
``` |
||||
|
||||
This form of the `credential` sub-command only accredits a single commit. When a |
||||
single commit is accredited and it itself is a credential commit then the new |
||||
commit which is created is merely a copy of the specified credential commit with |
||||
the caller's own credential appended to the `credentials` list. You can see this |
||||
with `git show`, which should look like: |
||||
|
||||
``` |
||||
Credential of AO3dn4Se61hq6OWy4Lm6m3MxdT2ru6TrIobuHaWJJidt |
||||
|
||||
--- |
||||
type: credential |
||||
commits: |
||||
- f085f13fa839ece122476601d970460ac249dc69 # these will be different |
||||
- 40a81ffb4f52dc4149570672f7f7fc053f12226a |
||||
change_description: add echo.sh and echo-upper.sh |
||||
fingerprint: AO3dn4Se61hq6OWy4Lm6m3MxdT2ru6TrIobuHaWJJidt |
||||
credentials: |
||||
- type: pgp_signature |
||||
pub_key_id: XXX |
||||
body: BIG LONG STRING |
||||
account: tot |
||||
- type: pgp_signature |
||||
pub_key_id: XXX |
||||
body: BIG LONG STRING |
||||
account: tut |
||||
``` |
||||
|
||||
There is now enough credentials to combine both commits in the `tot/echo-script` |
||||
branch into a single commit on the `main` branch. |
||||
|
||||
## Step 3: Combination |
||||
|
||||
At this point the `tot/echo-script` branch has the following elements in place: |
||||
|
||||
* Two change commits, which we want to combine and bring over to `main`. |
||||
* A credential commit made by `tot` for the combined changes. |
||||
* A credential commit made by `tut` for the combined changes, which includes |
||||
`tot`'s credentials. |
||||
|
||||
Combining the commits and placing them on `main` is done with a single command: |
||||
|
||||
``` |
||||
dehub combine --start HEAD^^^^ --end HEAD --onto main |
||||
``` |
||||
|
||||
This `combine` command combines all changes made within the given commit range, |
||||
the last change description found in that range (in this case it will be from |
||||
`tut`'s credential commit), and all credentials for that set of changes. The |
||||
command combines them into a single commit which it places on the `main` branch. |
||||
You can see the commit you've just created by doing: |
||||
|
||||
``` |
||||
git checkout main |
||||
git show |
||||
``` |
||||
|
||||
The commit should contain both of the new files, and the message should look |
||||
something like: |
||||
|
||||
``` |
||||
add echo.sh and echo-upper.sh |
||||
|
||||
--- |
||||
type: change |
||||
description: add echo.sh and echo-upper.sh |
||||
fingerprint: ALOcEuKJkgIdz27z0fjF1NEbK6Y9cEh2RH4/sL3uf3oa |
||||
credentials: |
||||
- type: pgp_signature |
||||
pub_key_id: XXX |
||||
body: BIG LONG BODY |
||||
account: tot |
||||
- type: pgp_signature |
||||
pub_key_id: XXX |
||||
body: BIG LONG BODY |
||||
account: tut |
||||
``` |
||||
|
||||
The commit is accredited by two different accounts, and so is allowed to be on |
||||
the `main` branch. This can be verified by doing `dehub verify`. |
||||
|
||||
You now are able to require commit sign-off and create signed-off commits! The |
||||
access control settings surrounding commit sign-offs are entirely up to you and |
||||
your project's needs. You can require sign-off from specific accounts, any |
||||
accounts, only on specific files, only in certain branches, etc... all using the |
||||
same basic access control building blocks. |
Loading…
Reference in new issue