Authority is what you hold now
A governing role in NAOMS is a credential the group can revoke, so a check of that role has to read the credential as it stands now, not only the record of who was once appointed. That answers one question: may this person act? A second question, how many people must agree, turns out to need the opposite care, because taking someone off that count lowers the bar for everyone else.
When a group takes a role away from someone, the natural expectation is that the powers go with it. If a steward (one of the people who govern a group) is stepped down on Tuesday, they should not still be able to use a steward's powers on Wednesday.
That sounds too obvious to need writing down. It became a design rule because there are two ways to answer "is this person a steward?", and only one of them respects a revocation.
How authority is supposed to work
In NAOMS a group's governing role is a credential: a signed statement, issued under the group's own rules, that says this person is a steward here. The group can revoke it the same way it issued it. When someone is stepped down but stays in the group, only the steward credential is withdrawn; their membership credential stays. (The 2 September piece covers why those two are separate.)
Since authority is something the group can take back, the place that decides it is the credential as it stands right now. Is there a steward credential for this person, in this group, that has not been revoked or suspended? If yes, they may act as a steward. If it was revoked yesterday, they may not.
The tempting alternative is the group's history. Every appointment is written down as a signed entry in the group's record, so it is easy to scan that record and ask "was this person ever made a steward?". The problem is in the word ever. The record only grows. An appointment entry from last year is still there after the revocation, and a check that reads appointments without reading revocations will say yes forever.
So the rule is: check the credential, not only the history. History tells you who was appointed. Only the live credential tells you who holds the role now. For the power this post is about, both must agree: the person must appear in the group's record of appointments and hold a live steward credential. Apart from the first edge case below, neither one alone is enough.
There are two defined edge cases, and each gets a deliberate answer:
- Groups older than their credentials. Some groups were founded before stewards were issued credentials at all. For those, and only when no credential exists, the check accepts the group's record of appointments on its own.
- When the credential cannot be read. If the store holding credentials fails to answer, the check does not guess. It refuses. A storage fault must never be the thing that grants someone power.
flowchart TD
Q[May this person act as a steward?] --> R{Appointed steward in the
group's signed record?}
R -- no --> N[No]
R -- yes --> C{Their steward credential now}
C -- valid --> Y[Yes]
C -- none exists: an older group --> Y2[Yes, from the record]
C -- revoked or suspended --> N2[No]
C -- cannot be read --> N3[No, and say why in the log]
Where that rule was not yet applied
Status note. This post is dated 4 September, the day the fix was written on the working branch. It reached the project's main line on 24 September, after a revision on 22 September changed part of it. What follows describes the version on the main line, and says where it differs from the 4 September one.
One of a group's sharper powers is the ability to revoke a developer's package-signing key in an emergency: if a developer's key is compromised, the group that hosts their packages can cut it off. That power belongs to stewards, and in a group with two or more stewards it needs two different stewards to agree.
Before this change, the check behind that power read only the group's history. It scanned the appointment entries and treated anyone ever appointed as a steward for good. A steward who had been stepped down kept the power to pull that emergency brake indefinitely, and still counted as one of the stewards.
What changed
The fix applied the rule above. Before treating someone as a steward for an emergency revocation, the check now asks the credential store, and refuses if the store cannot answer. Two tests were added with the change: one confirms that a person whose steward credential was revoked is no longer treated as a steward, and the other drives the full emergency-revocation call and confirms it rejects such a person even though an old appointment entry still names them.
On 4 September this existed on the working branch for the larger effort to remove the idea that a group has an owner. It reached the project's main line on 24 September.
The 4 September version let a live credential count on its own, even for someone the group's record never appointed. The version that landed closes that too: as the diagram above shows, the appointment and the live credential must both be there.
The second question needs the opposite care
The same change on 4 September did one more thing: when counting how many stewards the group has, it left out anyone whose credential had lapsed. It looked like the same rule applied twice. It was not, and the version that landed on the main line on 24 September does not do it.
Here is the reason. The count decides whether a second signature is needed. Two or more stewards means two must agree; one steward can act alone. Now take a group with two stewards and revoke one of them. If the revoked steward drops out of the count, the count falls to one, the two-signature requirement switches off, and the remaining steward can use the emergency power alone, which is something the group never agreed to.
Refusing someone is safe when you are deciding whether they may act. Removing someone from a denominator works the other way round: it removes a required signer and lowers the bar for everyone else. The same instinct, leave out anything uncertain, is cautious in the first case and permissive in the second.
So the landed version keeps the two questions apart:
- May this person act? Read the live credential. Revoked means no.
- How many must agree? Count everyone the group's record shows was appointed steward, plus any live credential holders the record does not show. Revoking someone takes away their ability to sign, but does not lower the number of signatures required. If the credential store is unreachable, the count falls back to the record of appointments and does not drop below it.
The price of that choice is real, and the code keeps it in plain sight. A group whose second steward has been revoked cannot use this emergency power until there is another live steward to co-sign. How to handle that case more gracefully is recorded in the code as an open decision for the owner.
The group-vote engine being built alongside this work was written on the same principle. When a vote opens, it records who is eligible. From then on, a steward revoked mid-vote loses their vote immediately, but the number of approvals needed does not fall. As its own design notes put it, revoking stewards "can never lower the bar". That rule reached the main line on 16 September.
One more ruling: when the store cannot answer
Before landing, the team debated one case: a steward in the record of appointments asks to act, and the credential store is down. Permitting them would keep the emergency brake usable during an outage. Refusing them means that an outage, or an attacker able to cause one, can block the brake.
The owner chose refusal, knowing that cost: "when the signer is not online, which is an exceptional situation, then nothing should work, nothing must be done, nothing can be done, so that should always fail closed." The refusal is logged in words that separate "denied because we could not check" from "denied because you are not a steward". Someone dealing with a compromised key needs to know which of those they are facing.
The rule, lifted out
Two things carry over to any system with revocable roles:
- Read authority from the thing that can be revoked, not only from the log of when it was granted. An append-only history is excellent evidence of the past and poor evidence of the present.
- "Deny when unsure" means different things in different places. Applied to a request to act, it refuses. Applied to a count that sets a threshold, it lowers the threshold. Before adding a cautious filter, ask which kind of question it sits in.
Related: Nobody owns a group ยท The permission you granted is the one that gets checked
Written by AI agents from real project logs; owned and edited by Mujo.
Written by AI agents from real project logs; owned and edited by Mujo.