Rotation already worked, and that was the problem. A device
re-registering with a different ik_sig simply overwrote the old one.
The call is authorised by the OLD key — the token's cnf must match
what is on file — so the caller had to hold the key being replaced. What
nothing established was that the NEW key's holder had anything to do
with it.
That gap matters because of who can reach it. Anyone able to mint a
token for a device and sign one request with the old key — a stolen
device in the window before revocation, a compromised issuer — could
point the identity at a key they control, and every future correspondent
would fetch the substitute as though it were a rotation the owner
performed.
A rotation may now carry a continuity proof: the old key's signature
over fnrot-v1|<device>|<old>|<new>. Only somebody holding the old key
can produce it, and only for one named successor — the statement carries
both keys and the device id, so a captured proof cannot be replayed onto
a different new key or onto another device of the same account. Both are
tested.
Absent is accepted; wrong is refused. Every client that predates
the field sends nothing, and refusing them would break rotation for
everybody already installed. A present-and-wrong proof is somebody
asking to be believed and failing, which is a different thing entirely.
What changes for the unproven case is the record. A proven
rotation logs as rotate, an unproven one as rotate_unproven — two
kinds, not one kind with a flag, because the key log is what somebody
audits later and the distinction has to survive into it. A monitor, or
the other party's client, can then treat them differently rather than
being told they are the same event.
A refused rotation appends nothing to the log. A key the relay would
not serve must not be committed to.
592 relay tests in 52 suites, green — all seven core paths included.
**Rotation already worked, and that was the problem.** A device
re-registering with a different `ik_sig` simply overwrote the old one.
The call is authorised by the OLD key — the token's `cnf` must match
what is on file — so the caller had to hold the key being replaced. What
nothing established was that the NEW key's holder had anything to do
with it.
That gap matters because of who can reach it. Anyone able to mint a
token for a device and sign one request with the old key — a stolen
device in the window before revocation, a compromised issuer — could
point the identity at a key they control, and every future correspondent
would fetch the substitute as though it were a rotation the owner
performed.
A rotation may now carry a **continuity proof**: the old key's signature
over `fnrot-v1|<device>|<old>|<new>`. Only somebody holding the old key
can produce it, and only for one named successor — the statement carries
both keys and the device id, so a captured proof cannot be replayed onto
a different new key or onto another device of the same account. Both are
tested.
**Absent is accepted; wrong is refused.** Every client that predates
the field sends nothing, and refusing them would break rotation for
everybody already installed. A present-and-wrong proof is somebody
asking to be believed and failing, which is a different thing entirely.
**What changes for the unproven case is the record.** A proven
rotation logs as `rotate`, an unproven one as `rotate_unproven` — two
kinds, not one kind with a flag, because the key log is what somebody
audits later and the distinction has to survive into it. A monitor, or
the other party's client, can then treat them differently rather than
being told they are the same event.
A refused rotation appends nothing to the log. A key the relay would
not serve must not be committed to.
592 relay tests in 52 suites, green — all seven core paths included.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Rotation already worked, and that was the problem. A device
re-registering with a different
ik_sigsimply overwrote the old one.The call is authorised by the OLD key — the token's
cnfmust matchwhat is on file — so the caller had to hold the key being replaced. What
nothing established was that the NEW key's holder had anything to do
with it.
That gap matters because of who can reach it. Anyone able to mint a
token for a device and sign one request with the old key — a stolen
device in the window before revocation, a compromised issuer — could
point the identity at a key they control, and every future correspondent
would fetch the substitute as though it were a rotation the owner
performed.
A rotation may now carry a continuity proof: the old key's signature
over
fnrot-v1|<device>|<old>|<new>. Only somebody holding the old keycan produce it, and only for one named successor — the statement carries
both keys and the device id, so a captured proof cannot be replayed onto
a different new key or onto another device of the same account. Both are
tested.
Absent is accepted; wrong is refused. Every client that predates
the field sends nothing, and refusing them would break rotation for
everybody already installed. A present-and-wrong proof is somebody
asking to be believed and failing, which is a different thing entirely.
What changes for the unproven case is the record. A proven
rotation logs as
rotate, an unproven one asrotate_unproven— twokinds, not one kind with a flag, because the key log is what somebody
audits later and the distinction has to survive into it. A monitor, or
the other party's client, can then treat them differently rather than
being told they are the same event.
A refused rotation appends nothing to the log. A key the relay would
not serve must not be committed to.
592 relay tests in 52 suites, green — all seven core paths included.
assigned to @paulhitt
deleted the
feat/witness-cosigned-headsbranch. This merge request now targets themainbranchchanged the description