Sync public tree to cab9305

This commit is contained in:
Michel Paulissen 2026-07-04 12:30:17 +02:00
parent fa0b074b05
commit 65ccb17519
3 changed files with 123 additions and 2 deletions

View file

@ -1900,12 +1900,14 @@ fn artifact_download_report(args: ArtifactDownloadArgs) -> Result<Value> {
"now_epoch_seconds": 0,
}))?;
let download_session = artifact_download_session_summary(&response);
let grant_disclosures = artifact_download_grant_disclosures(&response);
return Ok(json!({
"command": "artifact download",
"coordinator": coordinator,
"artifact": args.artifact,
"max_bytes": args.max_bytes,
"download_session": download_session,
"grant_disclosures": grant_disclosures,
"response": response,
"coordinator_session_requests": session.requests(),
}));
@ -1920,6 +1922,7 @@ fn artifact_download_report(args: ArtifactDownloadArgs) -> Result<Value> {
"link_issued": false,
"explicit_user_action_required": true,
},
"grant_disclosures": [],
}))
}
@ -1949,6 +1952,10 @@ fn artifact_export_report(args: ArtifactExportArgs) -> Result<Value> {
})
};
apply_local_export_summary(&mut export_plan, &local_export);
let grant_disclosures = local_export
.get("grant_disclosures")
.cloned()
.unwrap_or_else(|| json!([]));
return Ok(json!({
"command": "artifact export",
"coordinator": coordinator,
@ -1957,6 +1964,7 @@ fn artifact_export_report(args: ArtifactExportArgs) -> Result<Value> {
"receiver_node": args.receiver_node,
"export_plan": export_plan,
"local_export": local_export,
"grant_disclosures": grant_disclosures,
"response": response,
"coordinator_session_requests": session.requests(),
}));
@ -1973,6 +1981,7 @@ fn artifact_export_report(args: ArtifactExportArgs) -> Result<Value> {
"local_bytes_written_by_cli": false,
"default_durable_store_assumed": false,
},
"grant_disclosures": [],
}))
}
@ -2003,10 +2012,14 @@ fn artifact_export_local_write_followup(
"local_path": &args.to,
"local_bytes_written_by_cli": false,
"content_bytes_available": false,
"download_session": artifact_download_session_summary(&link_response),
"grant_disclosures": [],
"link_response": link_response,
}));
}
let download_session = artifact_download_session_summary(&link_response);
let grant_disclosures = artifact_download_grant_disclosures(&link_response);
let token_digest = link_response
.pointer("/link/scoped_token_digest")
.cloned()
@ -2030,6 +2043,8 @@ fn artifact_export_local_write_followup(
"local_path": &args.to,
"local_bytes_written_by_cli": false,
"content_bytes_available": false,
"download_session": download_session,
"grant_disclosures": grant_disclosures,
"stream": artifact_stream_summary(&stream_response),
}));
}
@ -2044,6 +2059,8 @@ fn artifact_export_local_write_followup(
"local_path": &args.to,
"local_bytes_written_by_cli": false,
"content_bytes_available": false,
"download_session": download_session,
"grant_disclosures": grant_disclosures,
"stream": artifact_stream_summary(&stream_response),
}));
};
@ -2065,6 +2082,8 @@ fn artifact_export_local_write_followup(
"bytes_written": bytes.len(),
"content_bytes_available": true,
"content_source": stream_response.get("content_source").cloned().unwrap_or(Value::Null),
"download_session": download_session,
"grant_disclosures": grant_disclosures,
"stream": artifact_stream_summary(&stream_response),
}))
}
@ -4245,11 +4264,47 @@ fn artifact_download_session_summary(response: &Value) -> Value {
"token_material_returned": false,
"scoped_token_digest_present": link.get("scoped_token_digest").is_some(),
"policy_context_digest_present": link.get("policy_context_digest").is_some(),
"authorization_required": true,
"short_lived": link.get("expires_at_epoch_seconds").is_some(),
"guessable_public_url": false,
"cross_tenant_usable": false,
"unauthorized_project_usable": false,
"default_durable_store_assumed": false,
})
}
fn artifact_download_grant_disclosures(response: &Value) -> Value {
if response.get("type").and_then(Value::as_str) != Some("artifact_download_link") {
return json!([]);
}
let link = response.get("link").unwrap_or(&Value::Null);
json!([{
"grant": "artifact_download",
"description": "download scoped artifact bytes to the requesting machine",
"risk": "authorized artifact bytes leave the retaining node or explicit storage through an explicit download/export operation",
"coordinator_policy_limited": true,
"authorization_required": true,
"explicit_user_action_required": true,
"tenant": link.get("tenant").cloned().unwrap_or(Value::Null),
"project": link.get("project").cloned().unwrap_or(Value::Null),
"process": link.get("process").cloned().unwrap_or(Value::Null),
"artifact": link.get("artifact").cloned().unwrap_or(Value::Null),
"actor": link.get("actor").cloned().unwrap_or(Value::Null),
"source": link.get("source").cloned().unwrap_or(Value::Null),
"max_bytes": link.get("max_bytes").cloned().unwrap_or(Value::Null),
"expires_at_epoch_seconds": link.get("expires_at_epoch_seconds").cloned().unwrap_or(Value::Null),
"short_lived": link.get("expires_at_epoch_seconds").is_some(),
"scoped_token_digest_present": link.get("scoped_token_digest").is_some(),
"token_material_returned": false,
"guessable_public_url": false,
"cross_tenant_reuse_allowed": false,
"unauthorized_project_reuse_allowed": false,
"default_durable_store_assumed": false,
"private_website_required": false,
}])
}
fn artifact_export_plan_summary(response: &Value, to: &Path) -> Value {
if response.get("type").and_then(Value::as_str) != Some("artifact_export_plan") {
return json!({
@ -8393,11 +8448,49 @@ mod tests {
download["download_session"]["scoped_token_digest_present"],
true
);
assert_eq!(download["download_session"]["authorization_required"], true);
assert_eq!(download["download_session"]["short_lived"], true);
assert_eq!(download["download_session"]["guessable_public_url"], false);
assert_eq!(download["download_session"]["cross_tenant_usable"], false);
assert_eq!(
download["download_session"]["unauthorized_project_usable"],
false
);
assert_eq!(
download["download_session"]["default_durable_store_assumed"],
false
);
assert_eq!(
download["grant_disclosures"][0]["grant"],
"artifact_download"
);
assert_eq!(
download["grant_disclosures"][0]["coordinator_policy_limited"],
true
);
assert_eq!(
download["grant_disclosures"][0]["scoped_token_digest_present"],
true
);
assert_eq!(
download["grant_disclosures"][0]["token_material_returned"],
false
);
assert_eq!(
download["grant_disclosures"][0]["guessable_public_url"],
false
);
assert_eq!(
download["grant_disclosures"][0]["cross_tenant_reuse_allowed"],
false
);
assert_eq!(
download["grant_disclosures"][0]["unauthorized_project_reuse_allowed"],
false
);
let rendered_download = human_report(&download);
assert!(rendered_download.contains("grant artifact_download"));
assert!(rendered_download.contains("policy-limited"));
assert_eq!(export["export_plan"]["status"], "transfer_plan_created");
assert_eq!(export["export_plan"]["source_node"], "node-a");
@ -8418,6 +8511,19 @@ mod tests {
export["local_export"]["stream"]["content_material_returned_in_report"],
false
);
assert_eq!(
export["local_export"]["download_session"]["scoped_token_digest_present"],
true
);
assert_eq!(
export["local_export"]["download_session"]["guessable_public_url"],
false
);
assert_eq!(export["grant_disclosures"][0]["grant"], "artifact_download");
assert_eq!(
export["grant_disclosures"][0]["cross_tenant_reuse_allowed"],
false
);
assert_eq!(
std::fs::read(&export_path).unwrap().as_slice(),
b"app-bytes"