fix(egress): a backend is defined in two maps, and the canary only had one
First canary run failed: phase failed, nothing delivered, and the streamed log said exactly why — "Failed to authenticate. API Error: 403 api.anthropic.com is not on the egress allow-list". Not a 2.1.226 regression. `canary-claude` was added to the server's credential map and not to the node's `provider_hosts`, so the VM booted with a valid subscription token and a door that only opened onto the forge. The fail-closed branch was working correctly: a backend nobody taught that function about reaches no model API, deliberately, so it cannot silently borrow another provider's door. Both maps now name it, each pointing at the other, with a test asserting the canary reaches the same provider as `claude` AND that unknown backends still resolve to nothing. Worth noting what made this a five-second diagnosis instead of an afternoon: the live log streaming built earlier today. The failure was a 403 inside a microVM that no longer exists, and its reason was sitting in the run's checkpoint.
This commit is contained in:
@@ -62,7 +62,15 @@ const COMMON_ALLOW: &[&str] = &["git.redclaw.dev"];
|
||||
/// proxy's log of which host it dialled does.
|
||||
fn provider_hosts(backend: Option<&str>) -> &'static [&'static str] {
|
||||
match backend {
|
||||
None | Some("") | Some("default") | Some("claude") => {
|
||||
// `canary-claude` is the same provider, from a candidate CLI image —
|
||||
// see `mission_runtime::microvm_credential_for`, which must grant it the
|
||||
// same credential. A backend is defined in TWO maps: the credential one
|
||||
// on the server and this one on the node. Adding it to only the first is
|
||||
// exactly what happened here: the mission launched, the VM booted, the
|
||||
// agent ran, and the turn died on
|
||||
// "403 api.anthropic.com is not on the egress allow-list" — which is the
|
||||
// fail-closed branch below working correctly.
|
||||
None | Some("") | Some("default") | Some("claude") | Some("canary-claude") => {
|
||||
&["api.anthropic.com", ".anthropic.com"]
|
||||
}
|
||||
Some("glm") => &["api.z.ai"],
|
||||
@@ -348,6 +356,26 @@ pub fn start(
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
/// A backend is defined in TWO places — the server's credential map and this
|
||||
/// egress map — and granting it one without the other produces a mission
|
||||
/// that launches, boots, runs, and dies on a 403 from our own proxy.
|
||||
///
|
||||
/// Measured exactly that way: `canary-claude` was credentialed on the server
|
||||
/// and unknown here, and the turn failed with
|
||||
/// "api.anthropic.com is not on the egress allow-list".
|
||||
#[test]
|
||||
fn the_canary_backend_reaches_the_same_provider_as_claude() {
|
||||
assert_eq!(
|
||||
provider_hosts(Some("canary-claude")),
|
||||
provider_hosts(Some("claude")),
|
||||
"a canary of the Claude image must reach Anthropic, or it tests nothing"
|
||||
);
|
||||
// And the fail-closed branch must still hold for anything unknown: this
|
||||
// is what stops a new backend silently borrowing another provider's door.
|
||||
assert!(provider_hosts(Some("canary-something-else")).is_empty());
|
||||
assert!(provider_hosts(Some("definitely-not-built")).is_empty());
|
||||
}
|
||||
|
||||
use super::*;
|
||||
|
||||
fn allow() -> Vec<String> {
|
||||
|
||||
Reference in New Issue
Block a user