mirror of
https://github.com/block/buzz.git
synced 2026-11-07 09:52:03 +00:00
Rename NIP-FI policy mutation gate
Co-authored-by: Honor <e0bf479eeebe47dde1e35705212a4df70616a7bc834d907ddfb18cf0405f8b1b@seiler-test.communities.public.builderlabstaging.xyz> Signed-off-by: Brad Seiler <seiler@squareup.com>
This commit is contained in:
@@ -472,7 +472,7 @@ RUST_LOG=buzz_relay=debug,buzz_datastore=info,buzz_db=debug,buzz_auth=debug,buzz
|
||||
|
||||
# Permit community FI policy enables and disables only after the whole fleet
|
||||
# supports policy management. A closed gate preserves receipt recovery/status.
|
||||
BUZZ_NIP_FI_UPGRADES_ENABLED=false
|
||||
BUZZ_NIP_FI_CHANGES=false
|
||||
|
||||
# NIP-CL compact membership discovery. Deploy fleet-wide dark before enabling.
|
||||
BUZZ_MEMBERSHIP_SNAPSHOT_ENABLED=false
|
||||
|
||||
@@ -1284,7 +1284,7 @@ pub async fn enable_community_nip_fi(
|
||||
let host = normalize_candidate_host(&request.expected_host).map_err(|_| invalid())?;
|
||||
let actor = validate_pubkey_hex(&request.actor_pubkey).ok_or_else(invalid)?;
|
||||
let owner = validate_pubkey_hex(&request.expected_owner_pubkey).ok_or_else(invalid)?;
|
||||
let trust = if state.config.nip_fi_upgrades_enabled {
|
||||
let trust = if state.config.nip_fi_changes {
|
||||
upgrade_configured_trust(&state, &host, &request.expected_issuer)
|
||||
} else {
|
||||
Err("upgrades_disabled")
|
||||
@@ -3164,9 +3164,8 @@ mod postgres_tests {
|
||||
.nip_fi
|
||||
.registry
|
||||
.insert(issuer_policy);
|
||||
Arc::make_mut(&mut Arc::get_mut(&mut state).unwrap().config).nip_fi_upgrades_enabled =
|
||||
false;
|
||||
assert!(!state.config.nip_fi_upgrades_enabled);
|
||||
Arc::make_mut(&mut Arc::get_mut(&mut state).unwrap().config).nip_fi_changes = false;
|
||||
assert!(!state.config.nip_fi_changes);
|
||||
|
||||
assert_eq!(
|
||||
provision_community(state.clone(), &operator, &host, &owner)
|
||||
@@ -3237,7 +3236,7 @@ mod postgres_tests {
|
||||
.await
|
||||
.unwrap()
|
||||
.is_none());
|
||||
Arc::make_mut(&mut Arc::get_mut(&mut state).unwrap().config).nip_fi_upgrades_enabled = true;
|
||||
Arc::make_mut(&mut Arc::get_mut(&mut state).unwrap().config).nip_fi_changes = true;
|
||||
let response =
|
||||
fresh_upgrade_request(state.clone(), &operator, "POST", path, Some(body.clone())).await;
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
@@ -3313,8 +3312,7 @@ mod postgres_tests {
|
||||
.policy_generation,
|
||||
1
|
||||
);
|
||||
Arc::make_mut(&mut Arc::get_mut(&mut state).unwrap().config).nip_fi_upgrades_enabled =
|
||||
false;
|
||||
Arc::make_mut(&mut Arc::get_mut(&mut state).unwrap().config).nip_fi_changes = false;
|
||||
let while_off =
|
||||
fresh_upgrade_request(state.clone(), &operator, "POST", path, Some(body.clone())).await;
|
||||
assert_eq!(while_off.status(), StatusCode::OK);
|
||||
@@ -3358,7 +3356,7 @@ mod postgres_tests {
|
||||
.await
|
||||
.unwrap()
|
||||
.is_none());
|
||||
Arc::make_mut(&mut Arc::get_mut(&mut state).unwrap().config).nip_fi_upgrades_enabled = true;
|
||||
Arc::make_mut(&mut Arc::get_mut(&mut state).unwrap().config).nip_fi_changes = true;
|
||||
|
||||
// Exercise the real HTTP-to-config-to-transaction seam: no raw trust
|
||||
// precondition can bypass the deployment's configured issuer selection.
|
||||
|
||||
@@ -112,7 +112,7 @@ pub async fn set_community_nip_fi_policy(
|
||||
expected_issuer: request.expected_issuer.unwrap_or_default(),
|
||||
operator_pubkey: operator.to_hex(),
|
||||
};
|
||||
let preflight = if !state.config.nip_fi_upgrades_enabled {
|
||||
let preflight = if !state.config.nip_fi_changes {
|
||||
Err("upgrades_disabled")
|
||||
} else if request.requires_nip_fi {
|
||||
upgrade_configured_trust(&state, &tuple.expected_host, &tuple.expected_issuer)
|
||||
|
||||
@@ -29,7 +29,7 @@ mod postgres_tests {
|
||||
let config = Arc::make_mut(&mut Arc::get_mut(&mut state).unwrap().config);
|
||||
config.nip_fi.registry.insert(issuer_policy);
|
||||
config.nip_fi.mode = buzz_auth::NipFiMode::Shadow;
|
||||
config.nip_fi_upgrades_enabled = false;
|
||||
config.nip_fi_changes = false;
|
||||
assert_eq!(
|
||||
provision_community(state.clone(), &operator, &host, &owner)
|
||||
.await
|
||||
@@ -66,7 +66,7 @@ mod postgres_tests {
|
||||
.await;
|
||||
assert_eq!(disabled.status(), StatusCode::SERVICE_UNAVAILABLE);
|
||||
assert_eq!(read_json(disabled).await["code"], "upgrades_disabled");
|
||||
Arc::make_mut(&mut Arc::get_mut(&mut state).unwrap().config).nip_fi_upgrades_enabled = true;
|
||||
Arc::make_mut(&mut Arc::get_mut(&mut state).unwrap().config).nip_fi_changes = true;
|
||||
let mut history = Vec::new();
|
||||
for (generation, desired) in [(1, true), (2, false), (3, true)] {
|
||||
body["operation_id"] = Uuid::new_v4().to_string().into();
|
||||
@@ -175,8 +175,7 @@ mod postgres_tests {
|
||||
)
|
||||
.await;
|
||||
assert_eq!(read_json(response).await["code"], "idempotency_conflict");
|
||||
Arc::make_mut(&mut Arc::get_mut(&mut state).unwrap().config).nip_fi_upgrades_enabled =
|
||||
false;
|
||||
Arc::make_mut(&mut Arc::get_mut(&mut state).unwrap().config).nip_fi_changes = false;
|
||||
let response = fresh_upgrade_request(
|
||||
state.clone(),
|
||||
&operator,
|
||||
@@ -197,7 +196,7 @@ mod postgres_tests {
|
||||
assert_eq!(current["effective_required"], mode.restricts());
|
||||
}
|
||||
// Enforce remains a global floor even after a stored disable.
|
||||
Arc::make_mut(&mut Arc::get_mut(&mut state).unwrap().config).nip_fi_upgrades_enabled = true;
|
||||
Arc::make_mut(&mut Arc::get_mut(&mut state).unwrap().config).nip_fi_changes = true;
|
||||
body["operation_id"] = Uuid::new_v4().to_string().into();
|
||||
body["requires_nip_fi"] = false.into();
|
||||
body["expected_policy_generation"] = 3.into();
|
||||
|
||||
@@ -409,8 +409,8 @@ pub struct Config {
|
||||
pub nip_fi_provision_binding: Option<buzz_auth::ProvisionBindingPolicy>,
|
||||
|
||||
/// Permit new community FI policy enables and disables. Default off; receipt
|
||||
/// recovery/status remain available (`BUZZ_NIP_FI_UPGRADES_ENABLED`).
|
||||
pub nip_fi_upgrades_enabled: bool,
|
||||
/// recovery/status remain available (`BUZZ_NIP_FI_CHANGES`).
|
||||
pub nip_fi_changes: bool,
|
||||
|
||||
/// Database resolver bounds (`BUZZ_NIP_FI_RESOLVER_*`,
|
||||
/// `BUZZ_NIP_FI_SNAPSHOT_*`). Validated in every mode, so a bad value
|
||||
@@ -1508,7 +1508,7 @@ impl Config {
|
||||
web_dir,
|
||||
serve_git_web_gui,
|
||||
nip_fi_provision_binding,
|
||||
nip_fi_upgrades_enabled: parse_bool("BUZZ_NIP_FI_UPGRADES_ENABLED", false)?,
|
||||
nip_fi_changes: parse_bool("BUZZ_NIP_FI_CHANGES", false)?,
|
||||
nip_fi_resolver_bounds,
|
||||
nip_fi,
|
||||
})
|
||||
@@ -1582,33 +1582,27 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nip_fi_upgrade_acceptance_is_explicitly_default_off() {
|
||||
fn nip_fi_changes_are_explicitly_default_off() {
|
||||
let (_fi, _cfg) = env_guards();
|
||||
let before = std::env::var("BUZZ_NIP_FI_UPGRADES_ENABLED").ok();
|
||||
std::env::remove_var("BUZZ_NIP_FI_UPGRADES_ENABLED");
|
||||
assert!(!Config::from_env().unwrap().nip_fi_upgrades_enabled);
|
||||
let before = std::env::var("BUZZ_NIP_FI_CHANGES").ok();
|
||||
std::env::remove_var("BUZZ_NIP_FI_CHANGES");
|
||||
assert!(!Config::from_env().unwrap().nip_fi_changes);
|
||||
for value in ["true", "TRUE", "1", "on", " On "] {
|
||||
std::env::set_var("BUZZ_NIP_FI_UPGRADES_ENABLED", value);
|
||||
assert!(
|
||||
Config::from_env().unwrap().nip_fi_upgrades_enabled,
|
||||
"{value}"
|
||||
);
|
||||
std::env::set_var("BUZZ_NIP_FI_CHANGES", value);
|
||||
assert!(Config::from_env().unwrap().nip_fi_changes, "{value}");
|
||||
}
|
||||
for value in ["false", "FALSE", "0", "off", "", " Off "] {
|
||||
std::env::set_var("BUZZ_NIP_FI_UPGRADES_ENABLED", value);
|
||||
assert!(
|
||||
!Config::from_env().unwrap().nip_fi_upgrades_enabled,
|
||||
"{value}"
|
||||
);
|
||||
std::env::set_var("BUZZ_NIP_FI_CHANGES", value);
|
||||
assert!(!Config::from_env().unwrap().nip_fi_changes, "{value}");
|
||||
}
|
||||
std::env::set_var("BUZZ_NIP_FI_UPGRADES_ENABLED", "treu");
|
||||
std::env::set_var("BUZZ_NIP_FI_CHANGES", "treu");
|
||||
assert!(
|
||||
matches!(Config::from_env(), Err(ConfigError::InvalidValue(message))
|
||||
if message.contains("BUZZ_NIP_FI_UPGRADES_ENABLED must be true or false"))
|
||||
if message.contains("BUZZ_NIP_FI_CHANGES must be true or false"))
|
||||
);
|
||||
match before {
|
||||
Some(value) => std::env::set_var("BUZZ_NIP_FI_UPGRADES_ENABLED", value),
|
||||
None => std::env::remove_var("BUZZ_NIP_FI_UPGRADES_ENABLED"),
|
||||
Some(value) => std::env::set_var("BUZZ_NIP_FI_CHANGES", value),
|
||||
None => std::env::remove_var("BUZZ_NIP_FI_CHANGES"),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ mod postgres_tests {
|
||||
let mut configured = (*base).clone();
|
||||
let config = Arc::make_mut(&mut configured.config);
|
||||
config.nip_fi.mode = buzz_auth::NipFiMode::Shadow;
|
||||
config.nip_fi_upgrades_enabled = false;
|
||||
config.nip_fi_changes = false;
|
||||
config.nip_fi.max_connection_lifetime_secs = 3600;
|
||||
config.nip_fi.communities = crate::nip_fi_config::NipFiCommunities::for_test_any_host(
|
||||
TEST_COMMUNITY_URI,
|
||||
|
||||
@@ -86,7 +86,7 @@ Migration 0084 adds desired action and nullable CAS preconditions to existing
|
||||
receipts. True/default and null preconditions preserve old receipt meaning and
|
||||
old INSERT compatibility. No data backfill, trigger, function or foreign key is
|
||||
added. Apply schema first, then compatible management writers across the **whole
|
||||
fleet** with `BUZZ_NIP_FI_UPGRADES_ENABLED=false`, then explicitly enable mutations.
|
||||
fleet** with `BUZZ_NIP_FI_CHANGES=false`, then explicitly enable mutations.
|
||||
The gate controls both directions; reads and committed replay remain available.
|
||||
Do not roll back to an unfenced management writer after the first general operation.
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ configured `RELAY_OPERATOR_API_ORIGIN` and an allowlisted operator signing key
|
||||
in a protected file. It sends one signed request and never retries automatically.
|
||||
|
||||
Before changing policy, apply the schema and roll compatible management writers
|
||||
across the whole fleet with `BUZZ_NIP_FI_UPGRADES_ENABLED=false`. Then explicitly
|
||||
across the whole fleet with `BUZZ_NIP_FI_CHANGES=false`. Then explicitly
|
||||
enable that gate, which controls both enable and disable. Enable additionally
|
||||
requires the deployment-selected issuer to be trusted and already bound to the
|
||||
community. The active community must have exactly one owner; the authenticated
|
||||
|
||||
Reference in New Issue
Block a user