feat(#2482): bootstrap cross-signing so agent matrix devices show verified
This commit is contained in:
parent
1961afd9cc
commit
0d40583991
2 changed files with 57 additions and 4 deletions
|
|
@ -12,10 +12,15 @@
|
|||
//!
|
||||
//! E2EE is enabled via `with_encryption_settings(EncryptionSettings::default())`.
|
||||
//! Crypto keys are persisted in the sqlite store under `state_dir`
|
||||
//! (survives container restarts, lost on `--purge`). Cross-signing and
|
||||
//! automatic key backup are deliberately left at their defaults (disabled)
|
||||
//! for the first pass: bot accounts authenticated with a static bearer token
|
||||
//! can't bootstrap cross-signing without MSC3967 on the server side.
|
||||
//! (survives container restarts, lost on `--purge`).
|
||||
//!
|
||||
//! Cross-signing is bootstrapped best-effort after session restore
|
||||
//! (`ensure_cross_signing`) so the agent's device stops showing as
|
||||
//! "unverified" in other users' Matrix clients: the in-hive tuwunel accepts
|
||||
//! the initial device-signing-key upload on the bearer token alone (no UIAA
|
||||
//! re-auth). A homeserver that DID require UIAA just fails the call, which is
|
||||
//! swallowed — the session stays exactly as unverified as before. Automatic
|
||||
//! key backup is still left at its default (disabled).
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
|
|
@ -204,6 +209,50 @@ async fn whoami(homeserver: &str, token: &str) -> Result<(OwnedUserId, OwnedDevi
|
|||
Ok((user_id, device_id))
|
||||
}
|
||||
|
||||
/// Best-effort: bootstrap this account's cross-signing identity so its
|
||||
/// device stops showing as "unverified" in other users' Matrix clients.
|
||||
///
|
||||
/// `bootstrap_cross_signing_if_needed(None)` is idempotent — it queries the
|
||||
/// account's existing keys and only uploads the master / self-signing /
|
||||
/// user-signing key set when no cross-signing identity exists yet. That
|
||||
/// upload also self-signs the current device, which is what actually clears
|
||||
/// the unverified warning. On a restart with the identity already present
|
||||
/// it's a no-op.
|
||||
///
|
||||
/// The `None` is the UIAA auth: the in-hive tuwunel accepts the initial
|
||||
/// `device_signing/upload` on the bearer token alone (no interactive
|
||||
/// re-auth). If a homeserver required UIAA the call returns a `UiaaResponse`
|
||||
/// error we can't satisfy with a bare bearer token — so this is best-effort:
|
||||
/// the failure is logged and swallowed, leaving the session no worse off than
|
||||
/// before. Never breaks account bring-up.
|
||||
///
|
||||
/// Known gap (self-verify only): this signs the *current* device against a
|
||||
/// freshly-bootstrapped identity. A device re-provisioned under an already
|
||||
/// existing identity (new `device_id`, e.g. after a token reissue) would need
|
||||
/// the cross-signing secret keys via secret storage to re-sign itself —
|
||||
/// tracked as the longer-term mutual-verification follow-up.
|
||||
pub async fn ensure_cross_signing(client: &Client, account: &str) {
|
||||
match client
|
||||
.encryption()
|
||||
.bootstrap_cross_signing_if_needed(None)
|
||||
.await
|
||||
{
|
||||
Ok(()) => {
|
||||
tracing::info!(
|
||||
account,
|
||||
"matrix cross-signing ensured (device self-verified)"
|
||||
);
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::warn!(
|
||||
account,
|
||||
error = %format!("{e:#}"),
|
||||
"matrix cross-signing bootstrap failed; session stays unverified (non-fatal)"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Best-effort: set this account's matrix avatar from the rasterized icon
|
||||
/// PNG. The path comes from `HIVE_ICON_PNG` (a nix-built derivation the
|
||||
/// harness forwards into the daemon env; absent when no icon resolves).
|
||||
|
|
|
|||
|
|
@ -286,6 +286,10 @@ async fn bring_up_account(
|
|||
// the live (authenticated, correct-homeserver) Client. Replaces the old
|
||||
// curl oneshot; failures are swallowed inside sync_avatar.
|
||||
client::sync_avatar(&client, &cfg.state_dir, &cfg.name).await;
|
||||
// Best-effort: bootstrap cross-signing so the account's device isn't
|
||||
// flagged "unverified" in other users' clients. Idempotent + swallows
|
||||
// failures (a UIAA-requiring homeserver) inside ensure_cross_signing.
|
||||
client::ensure_cross_signing(&client, &cfg.name).await;
|
||||
timeline::install_message_handler(&client, hyperhive_socket.to_path_buf(), tag.clone());
|
||||
|
||||
let sync_client = client.clone();
|
||||
|
|
|
|||
Loading…
Reference in a new issue