diff options
| author | tv <tv@krebsco.de> | 2026-11-08 18:11:13 +0000 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-11-08 19:28:38 +0100 |
| commit | 5bcf27ca2a10f16befb96c70bf04ae8a5c04ceaa (patch) | |
| tree | 9f2ea97e3482a388aa3959f46b4c91f77a20c440 /src | |
| parent | 857771cc05c73fb91477d7afcf91f10e25aaa0ab (diff) | |
rules: under strict, a user's own entry is its own to sign
Review 2, N5: under a strict policy a user's signed PUT of its own
entry, keys changed (continuum-signed key-add), passed the API and
envelope::check's own_keys_only, and was then refused by the rules'
path check: _continuum/users/<name> wanted write on the registry, so the
node judged it as every node would and answered 403. 1168 worked only
without strict.
Under a strict policy the rules now take a write of a user's own entry
from that user, leaving what it may be to signed_values, which runs
envelope::check: an envelope by the user, with only its keys changed,
one left at least. Strict only: under another policy the entry isn't an
envelope, and the user would rewrite its own capabilities.
Diffstat (limited to 'src')
| -rw-r--r-- | src/access/rules.rs | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/src/access/rules.rs b/src/access/rules.rs index 4e4e6e9..b5dcf3a 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])) } + // Under a strict policy, a user's own entry, as an envelope: signed by the user + // with only its keys changed (`envelope::check`, run by `signed_values`). + (Some(meta::USERS), Some(owner)) + if path.len() == 3 && change.user == Some(owner) && policy.strict() => + { + true + } // A user's own keys (`/auth/keys`), whatever else it may do, one left at // least. (Some(meta::USERS), Some(owner)) @@ -885,6 +892,27 @@ mod tests { ))); } + /// Under a strict policy, a user's own entry is its own to write (what it may sign + /// there, `envelope::check` says); not another's; without strict, not its own either. + #[test] + fn users_write_their_own_entry_under_strict() { + let mut doc = swarm(true); + let own = "_continuum/users/bob"; + assert!(refused(judged(&doc, "a", Some("bob"), &[own]))); + write( + &mut doc, + "_continuum/access/policy", + json!({"version": 1, "values": "signed"}), + ); + assert!(judged(&doc, "a", Some("bob"), &[own]).is_ok()); + assert!(refused(judged( + &doc, + "a", + Some("bob"), + &["_continuum/users/alice"] + ))); + } + /// A node that isn't a member may only register itself. #[test] fn strangers_register_themselves_only() { |
