monotone-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Monotone-devel] Meta-policy proposal


From: Zack Weinberg
Subject: [Monotone-devel] Meta-policy proposal
Date: Sun, 10 Sep 2006 23:53:49 -0700

This is my suggestion for meta-policy: the structure and policy for
processing updates to policy branches.  These rules probably have to
be set in stone, or at least code, so they have to be right up front,
and I don't claim to have gotten 'em right.  I think this handles
every case outlined in my previous message, though.  [Note that I do
not attempt to handle permissions enforced at commit or checkout time,
nor do I have a plan for pathname-based permissions, only branch-based
permissions.]

The basic structure of a policy branch is as Nathaniel proposes it.
Policy branches map a name -- we reserve a chunk of the namespace for
policy branches -- to a set of key IDs.  All branches, content or
policy, have an _associated_ policy branch; the set of keys listed in
branch X's associated policy branch P(X) is the set of keys that's
allowed to present new branch certificates for X.  This is checked at
netsync time; you can do whatever you please in your local repository,
but branch certs that you're not allowed to issue, *and the associated
revisions*, are not transferred to other databases.  [Naturally, it is
the receiving end that has to enforce this, although a polite sender
will not transmit revisions that it knows will be thrown away.
Perhaps we can wire this into merkle refinement somehow, so that it's
impossible for the sender to get it wrong.]

A policy branch's associated policy branch gives, naturally enough, the
set of keys allowed to modify the policy.  It is allowed for a policy
branch to name *itself* as its associated policy branch, and in fact
there must be at least one such policy branch, to cut off the infinite
regression.  (I suppose you could also have P(A) = B, P(B) = A if you
wanted to be strange.)  The branch -> policy relation is declared
explicitly in every branch certificate, which means you can change the
policy branch associated with a branch X -- but only if you're in the
key set for P(P(X)), *not* just P(X).  Otherwise the cert must declare
the same policy branch as its parent revision's branch cert.  (For
merges, it only has to agree with the parent with the same name.)

When you create a new branch from a given revision, the policy for
that branch is normally the policy of the parent rev's branch.
However, if the parent rev's policy doesn't include your key, you have
to specify a policy that does include your key (either on the command
line, or in lua hooks, to save typing).  At that point the *other*
thing in each policy branch kicks in: a restriction of some sort (a
list of globs, perhaps?) on the branch names that are allowed to be
generated using that policy.  These two things together give us a
full-fledged branch-based permissions mechanism.

Now, we also need rules for dealing with conflicting updates to a
given policy branch.  I propose a very simple rule: Netsync refuses to
create divergence in a policy branch, except if being run in
"sink_role" (i.e. "pull").  And if it is run as "pull", and divergence
is generated, you are *immediately* required to merge heads.  This
will never inconvenience a user who doesn't touch policy branches,
unless they try to pull from two databases with conflicting policy
branches with the same name (i.e. both sides of a totally hostile
fork) -- anyone doing that can probaly be assumed to know what they
are doing.  It may be a minor inconvenience for admins -- suppose
Alice adds Carol to the main policy branch, and Bob adds Dave at the
same time; one of them will get their sync rejected and have to pull,
merge, push.  However, this would be a concern no matter what.

So you can't diverge a given policy branch; but you can create all the
new named policy branches you want, either from scratch or by
branching existing policy branches, and have them say whatever you
want.  However, you cannot override the existing policy branch for any
existing content branches (or more precisely, you can, but netsync
will refuse to push them into any database where you're not allowed to
do that) -- so you are forced to create your own content branches at
the same time.  This ensures that a user tracking the primary dev
branch for one side of the fork can just carry on.

What happens if you take yourself out of the set in a policy branch?
Well, first, note that this is only a concern for a policy branch
whose policy branch is itself.  Second, once the revision and its
branch cert are accepted by netsync, they stay accepted.  Third, the
decision to accept the revision is made by the recipient - who doesn't
have that revision yet, so they base their decision on the *previous*
policy, which said you were allowed.  Thus, the oscillating cspec
scenario is not possible.

If Mallory and Nogoodnik kick each other out of the policy branches,
whoever does it first wins (this follows from the above rules).  I
claim that we cannot, programmatically, do any better than that.  If
the consensus of the team is that whoever came second was wrong, well,
hopefully there is also Trent still in the master policy branch to
sort it out.  Or at least, someone who can shell into the netsync
server and replace the database by hand.  If Mallory overrides every
last policy branch in the database with "Mallory and nobody else", and
Mallory also happens to be the sysadmin for the machine hosting the
netsync server, well, the project is just going to have to get a new
hosting provider.  However, note that the Absolute Write disaster
scenario (malicious ISP refuses to give site owners a database dump so
they can set up elsewhere) cannot arise, as everyone already has a
complete copy of the database on their local disk; the devteam-
in-exile can just take one of those, promote it to netsync master, and
go on.

z "Thoughts?" w




reply via email to

[Prev in Thread] Current Thread [Next in Thread]