diff options
| author | tv <tv@krebsco.de> | 2026-11-08 15:43:45 +0000 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-11-08 16:49:56 +0100 |
| commit | ed27acb707d940c5b796b1079d3d74698484aeba (patch) | |
| tree | 2761073c72f91ad8f3f0ed4b38844bb8ab8d14a2 /src/access/rules.rs | |
| parent | 1cdf5ce6e2a935ec17f800706aa8f289036d90f7 (diff) | |
users: a user manages its own keys
Only a user who may manage users could change a user's keys: a user
couldn't add a new laptop's key, or remove a lost one.
A user now manages its own keys, whatever else it may do:
* GET /auth/keys: its keys, its entry, and the envelope holding it
under a strict policy (`signed`), to sign against.
* PUT /auth/keys/{id} with an authorized_keys line, DELETE
/auth/keys/{id}: one change, as the user. The rules take a write of
_continuum/users/<name>/keys/… from the user it names.
* Under a strict policy, the user signs its entry with only its keys
changed, with a key it holds already (envelope::check takes that from
the user itself), PUT to its own entry even without write on the
registry; continuum-signed key-add and key-remove do so.
Diffstat (limited to 'src/access/rules.rs')
| -rw-r--r-- | src/access/rules.rs | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/src/access/rules.rs b/src/access/rules.rs index 3eca1c9..450addb 100644 --- a/src/access/rules.rs +++ b/src/access/rules.rs @@ -193,6 +193,13 @@ pub(crate) fn judge(doc: &Document, epoch: Epoch, change: &Change<'_>) -> Result || user_may(path) || user_may(&meta::path(&[meta::USERS])) } + // A user's own keys (`/auth/keys`), whatever else it may do. + (Some(meta::USERS), Some(owner)) + if path.get(3).map(String::as_str) == Some("keys") + && change.user == Some(owner) => + { + true + } // A node forgotten while alive cancels its own record (`swarm::peer::forget`). (Some(meta::FORGOTTEN), Some(owner)) => owner == node || user_may(path), (Some(meta::REMAKES), Some(id)) => match path.get(3).map(String::as_str) { @@ -788,6 +795,41 @@ mod tests { assert!(decide(Some("carol"), "committed", 0).is_ok()); } + /// A user's own keys: its own to change, whatever else it may do; another's, or the + /// rest of its own entry, not. + #[test] + fn users_change_their_own_keys() { + let doc = swarm(true); + assert!( + judged( + &doc, + "a", + Some("bob"), + &["_continuum/users/bob/keys/laptop"] + ) + .is_ok() + ); + assert!(judged(&doc, "a", Some("bob"), &["_continuum/users/bob/keys"]).is_ok()); + assert!(refused(judged( + &doc, + "a", + Some("bob"), + &["_continuum/users/alice/keys/laptop"] + ))); + assert!(refused(judged( + &doc, + "a", + Some("bob"), + &["_continuum/users/bob/caps"] + ))); + assert!(refused(judged( + &doc, + "a", + None, + &["_continuum/users/bob/keys/laptop"] + ))); + } + /// A node that isn't a member may only register itself. #[test] fn strangers_register_themselves_only() { |
