{"record":{"id":"7a53271ec7a4f5e8","repo":"astrid-runtime/astrid","slug":"winfsp-lease-callback-token-is-invalid","errorCode":null,"errorMessage":"WinFsp lease callback token is invalid","messagePattern":"WinFsp lease callback token is invalid","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-storage-provider-winfsp/src/win.rs","lineNumber":266,"sourceCode":"    }\n    if let Some(identity) = launch.parent.start_identity.as_deref()\n        && (identity.is_empty() || identity.len() > 512 || identity.chars().any(char::is_control))\n    {\n        bail!(\"WinFsp service parent start identity is invalid\");\n    }\n    if launch.parent.start_identity.is_none() {\n        bail!(\"WinFsp service parent start identity is required on Windows\");\n    }\n    let lease = &launch.lease;\n    let now = SystemTime::now()\n        .duration_since(UNIX_EPOCH)\n        .context(\"read system clock\")?\n        .as_secs();\n    if lease.expires_at_epoch_secs < now {\n        bail!(\"WinFsp lease is expired\");\n    }\n    if lease.lease_token.len() < 16 || lease.lease_token.len() > 4096 {\n        bail!(\"WinFsp lease callback token is invalid\");\n    }\n    if !lease.resource_path.is_absolute()\n        || !lease.callback_path.is_absolute()\n        || lease.callback_path != lease.resource_path.join(\"control.endpoint\")\n    {\n        bail!(\"WinFsp lease paths are malformed\");\n    }\n    platform_fs::validate_private_directory(&lease.resource_path)\n        .context(\"validate private WinFsp lease resource\")?;\n    platform_fs::verify_no_redirects(&lease.resource_path)\n        .context(\"reject redirected WinFsp lease resource\")?;\n    let manifest_path = lease.resource_path.join(\"lease.json\");\n    platform_fs::validate_private_file(&manifest_path)\n        .context(\"validate private WinFsp lease manifest\")?;\n    let manifest = std::fs::read(&manifest_path).context(\"read WinFsp lease manifest\")?;\n    if manifest.len() > 64 * 1024 {\n        bail!(\"WinFsp lease manifest exceeds the bounded size\");\n    }","sourceCodeStart":248,"sourceCodeEnd":284,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-storage-provider-winfsp/src/win.rs#L248-L284","documentation":"The lease's callback token is a shared secret used to authenticate control-endpoint callbacks. The validator requires it to be at least 16 and at most 4096 bytes; otherwise the launch is rejected. A token outside this range cannot have been produced by the normal lease issuer, so the library treats the launch descriptor as corrupt or forged.","triggerScenarios":"service_main -> validate_service_launch where lease.lease_token.len() < 16 || > 4096: a launch descriptor carries a missing/placeholder/oversized lease_token field.","commonSituations":"Hand-edited launch/lease JSON with a placeholder like \"token\" or \"<redacted>\"; a secrets-scrubbing CI log sanitizer that replaced the token with a short mask; serializing the token into a system that truncated it (e.g. a 15-char registry value or fixed-width buffer); copying an example from docs with a dummy token.","solutions":["Regenerate the lease so lease_token is a real token from the issuer (typically >=16 bytes of entropy), rather than reusing a hand-made or redacted value.","Inspect the launch descriptor on disk/logging pipeline for redaction or truncation of the token field.","Ensure any intermediary (env var, registry, IPC buffer) carrying the token allows at least 4096 bytes and does not strip or pad it.","If the issuer is your own code, assert token length is within 16..=4096 at issuance time to catch the bug at the source."],"exampleFix":"// before\nlease_token: \"abc\".to_string(),\n// after\nlease_token: base64_encode(rand_bytes(32)), // 16..=4096 bytes","handlingStrategy":"validation","validationCode":"let n = lease.lease_token.len();\nif !(16..=4096).contains(&n) {\n    return Err(anyhow!(\"lease_token length {n} outside 16..=4096 — regenerate the lease\"));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Issue tokens with a CSPRNG at >=16 bytes and assert the range at issuance","Never hand-edit or placeholder lease tokens in JSON files","Check log-redaction/CI sanitizers for patterns that rewrite token fields","Round-trip test: serialize and deserialize a lease and assert the token survives unchanged"],"tags":["winfsp","lease","token","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}