summaryrefslogtreecommitdiff
path: root/000.yarn
blob: 7f72fc90019c002ca506c9f48a27157cbb854527 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
---
title: "A Gitano ruleset: tests"
author: Lars Wirzenius (liw@liw.fi)
date: 2017-02-04
...

[Gitano][] is the server software I use for my personal git server,
and also for work. One of Gitano's primary features is a strong
language for defining access control, called [Lace][]. However, with
great power comes long shoelaces to tie together. This document
explains what my rules set does, and why. It is also a test suite for
the ruleset, to make sure it does what it's supposed to, but avoids
some of the more obvious pitfalls.

[Gitano]: https://www.gitano.org.uk/
[Lace]: https://www.gitano.org.uk/lace/


Personas for use cases
-----------------------------------------------------------------------------

* **Ian Inhouse Developer** is a staff member and works on a free software
  project with the random silly name Qvarn.

* **Olive Opshead** is a sysadmin and needs to maintain ops related
  repositories, some of which are sensitive.

* **Steven Sect** is the company secretary and needs to access some
  private respositories with internal company data.

* **Gabriella Guest** is an outside developer, collaborating on Qvarn
  with Ian. Gabriella has been granted restricted commit access to the
  Qvarn repository.

* **Tina Thirdparty** is an outside developer working on Qvarn as a
  full member, and needs full write access to the repository.

* **J. R. Hacker** is an outsider who contributes to the projects, but
  has no need to commit to any the repositories. Instead, they
  maintain their own repository elsewhere, and Ian or Tina access that.

* **CI** is an automated system that monitors some repositories to
  build, test, and deliver software.


Use cases
-----------------------------------------------------------------------------

* Ian fixes a bug in Qvarn. (Or adds a feature: same process.)

    * Ian clones Qvarn to his laptop, or updates his existing clone.
    * Ian creates a branch in the local clone and makes changes.
    * Ian pushes the branch to the git server.
    * After others have reviewed his changes, Ian merges them to
      master, and pushes master to the git server.
    * CI notices the change, runs tests, and builds and publishes a CI
      build of Qvarn.

* Ian makes a release.

    * Ian clones Qvarn.
    * Ian tags the right commit with a release tag.
    * Ian pushes the tag to the git server.
    * CI updates its own git clone; new release tag triggers a release
      build.

* Olive provisions a new Qvarn instance.

    * Olive clones a repository with Ansible playbooks.
    * Olive clones a repository with encrypted passowords.
    * Olive creates a local branch in the Ansible playbooks.
    * Olive makes and commits any necessary changes to the playbooks.
    * Olive creates a new VM and runs Ansible.
    * Olive pushes her new local branch to the server for review.
    * After revies feedback, Olive merges her changes to master.
    * Olive pushes master changes to server.

* Steven updates internal wiki.

    * Steven clones intrawiki.git.
    * Steven makes changes.
    * Steven commits changes to local master branch.
    * Steven pushes master changes to git server.
    * CI notices changes and updated intrawiki website.

* Gabriella makes a bug fix.

    * Gabriella clones qvarn.git.
    * Gabriella creates a new branch.
    * Gabriella changes new branch to fix bug.
    * Gabriella pushes new branch to git server.
    * Gabriella notifies others of new branch.
    * Ian reviews branch and finds it good.
    * Ian merges branch to master.
    * CI notices change in master and runs a CI pipeline.

* JR makes a bug fix.

    * JR clones qvarn.git.
    * JR creates a new local branch.
    * JR fixes bug in local branch.
    * JR pushes local branch to his own git server.
    * JR notifies others of changes on his git server.
    * Ian reviews changes from JR'r server, merges them to master from
      git.qvarnlabs.net, and pushes new master to git.q.n.
    * CI notices changes to master and runs CI pipeline.

* Anyone but Olive tries to clone the secrets repository

    * Gabriella attempts to clone the secrets repository.
    * The attempt fails.

* Tina adds a feature to another project, matching unreleased changes
  to Qvarn.

    * Tina clones qvarn.git.
    * Tina clones other-project.git.
    * Tina makes a change in other-project.git.
    * Tina pushes change in master to tina-project.git.

Discussion
-----------------------------------------------------------------------------

* There's going to be repositories that are public to the world (in a
  read-only manner) and those that are meant to be private at some
  level. Private may mean private to all staff or private to only
  specific people (e.g., ops secrets).

* Some people will have write access to some repositories, whereas
  everyone else (even with Gitano accounts) have only read access to
  those respositories. Example, Steven doesn't need write access to
  the Qvarn repository, but there's no point in restricting read
  access, since it's a public repository.

* When outsiders have write access, it may need to be restricted, such
  that they can do things, but can't change master or other branches
  themselves, or create release tags. This prevents Gary from making
  releases, or changing master without anyone else knowing about it.

Some principles/suggestions
-----------------------------------------------------------------------------

* There's several groups of people. Each group needs different access.

    - implicitly trusted staff members (those who can do ops)
    - normal staff members (Steven)
    - outsider guest users (Gabriella)
    - automated systems (CI)

* Three types of repositories.

    - completely public (qvarn.git)
    - private, but public to staff (intrawiki.git)
    - accessible to just part of staff (ops secrets)

* Guests should be able to update public repos in restricted ways.

    - they may only create/modify branches that are not used by
      others, e.g., their names are prefixed by their Gitano username
    - they may only create tags not used by others (again, prefixed),
      so that they may not create release tags

* Staff is either developers or otherwise trusted (i.e., can modify
  any branches, can make any tags), or treated the same as guests.

* Even staff may only have full access to some repos (qvarn.git), but
  not all (ops ones). For the latter, treat them similar to guests.

* CI and other automated systems only have read-only access. If an
  automated system needs write access later, consider the implications
  at that time.

Rough outline for ruleset
-----------------------------------------------------------------------------

* All repositories should have three configuration variables,
  `readers`, `writers`, and `guests`. The value of each varibable is
  the name of a Gitano group. Access is granted to users in the named
  group.

* Public repositories are marked by setting the configuration variable
  `public` to `yes`. Anyone can clone public repositories, pull from
  them, and cgit shows them to anyone.


Scenarios
-----------------------------------------------------------------------------

These [yarn][] scenarios need to be run as a Gitano user who is in the
gitano-admins group so that they can create users, and do other
priviledged operations. Further, this should be done against a fresh
Gitano, without the test users etc.

[yarn]: http://liw.fi/cmdtest/

This is going to be a long scenario, but that's just so that we don't
need to re-do the setup. The setup consists of creating test users,
groups, and respositories.

    SCENARIO create users, groups, repositories
    WHEN we run gitano whoami
    THEN we are in group gitano-admin

<!--

    WHEN we create user ian
    AND we create user olive
    AND we create user steven
    AND we create user gabriella
    AND we create user tina
    AND we create user ci

    WHEN we create group qvarndevs
    AND we create group qvarnguests
    AND we create group ops
    AND we create group otherdevs
    AND we create group staff

    WHEN we add ian to qvarndevs
    AND we add tina to qvarndevs
    AND we add gabriells to qvarnguests
    AND we add olive to ops
    AND we add tina to otherdevs
    AND we add steven to staff

    WHEN we create repository qvarn
    AND we create repository ops/secrets
    AND we create repository ops/ansible
    AND we create repository intrawiki
    AND we create repository otherproject

    WHEN we set qvarn config writers to qvarndevs
    AND we set qvarn config guests to qvarnguests
    AND we set qvarn config public to yes
    AND we set ops/secrets config writers to ops
    AND we set ops/ansible config writers to ops
    AND we set intrawiki config writers to staff

Now we can start defining use cases.

Use case: Ian makes a bugfix to Qvarn.

    WHEN ci clonse qvarn
    AND ian clones qvarn
    AND ian creates local qvarn branch ian/bugfix
    AND ian pushes qvarn
    AND ian merges ian/bugfix into master
    AND ian pushes qvarn
    THEN ci sees new commit in qvarn

Use case: Ian makes a release.

    WHEN ian creates tag qvarn-1.0 in qvarn master
    AND ian pushes qvarn
    THEN ci sees tag qvarn-1.0 in qvarn

Use case: Olive provisions a new Qvarn instance.

    WHEN olive clones ops/ansible
    AND olive clones ops/secrets
    AND olive creates local ops/ansible branch newthing
    AND olive pushes ops/ansible
    AND merges ops/ansible branch newthing to master
    AND olive pushes ops/ansible

Use case: Steven updates internal wiki.

    WHEN ci clones intrawiki
    AND steven clones intrawiki
    AND steven makes a change in intrawiki master
    AND steven pushes intrawiki
    THEN ci sees a new commit in intrawiki

-->


# Scenario step implementations

    IMPLEMENTS WHEN we run gitano (.+)
    args = helper.get_next_match()
    whoami_output = helper.gitano(args)
    helper.set_variable('admin_whoami', whoami_output)

    IMPLEMENTS THEN we are in group gitano-admin
    whoami = helper.get_variable('admin_whoami')
    helper.assertIn('gitano-admin', whoami)