# protect_file **Protect a file on immut (by bytes)** Protect a file by passing its bytes as base64. This server is remote and cannot read your filesystem, so bytes are the only way in. Do NOT transcribe a large file into base64 here (it is slow and error-prone): for anything substantial, upload it directly with multipart POST /api/v1/documents, or install the immut skill so it can read the file locally. Returns the proof. Set review=true instead if you are NOT sure the file should be protected — that stages it for a person and writes no proof. - Access: write ## Arguments | Name | Type | Required | Description | |---|---|---|---| | `filename` | string | **yes** | Original file name incl. extension | | `contentBase64` | string | **yes** | Base64-encoded file bytes | | `workspace` | string | **yes** | Workspace id | | `folder` | string | no | Destination folder id (omit to file at workspace root) | | `runId` | string | no | Id of the sweep this upload belongs to. Use the SAME value on every file in one sweep and on the matching report_run call — it is what links a run to the files it protected. | | `agentClassification` | string | no | What you judged about this file, recorded against the proof. Every field optional — send only what you actually determined, and never invent a verdict you did not reach. | | `review` | boolean | no | true = do NOT protect it; stage it for a human to decide. No proof is written. Use when you cannot tell whether the file is evidence for the objective. | | `sourcePath` | string | no | Where the file lives on the customer's machine. Only used with review=true, so the human can see what they are deciding about and the file is not staged again next sweep. | ## Tool contract ```json { "name": "protect_file", "title": "Protect a file on immut (by bytes)", "description": "Protect a file by passing its bytes as base64. This server is remote and cannot read your filesystem, so bytes are the only way in. Do NOT transcribe a large file into base64 here (it is slow and error-prone): for anything substantial, upload it directly with multipart POST /api/v1/documents, or install the immut skill so it can read the file locally. Returns the proof. Set review=true instead if you are NOT sure the file should be protected — that stages it for a person and writes no proof.", "access": "write", "destructive": false, "hostedOnProduction": true, "restEndpoint": null, "arguments": { "filename": { "type": "string", "required": true, "description": "Original file name incl. extension" }, "contentBase64": { "type": "string", "required": true, "description": "Base64-encoded file bytes" }, "workspace": { "type": "string", "required": true, "description": "Workspace id" }, "folder": { "type": "string", "required": false, "description": "Destination folder id (omit to file at workspace root)" }, "runId": { "type": "string", "required": false, "description": "Id of the sweep this upload belongs to. Use the SAME value on every file in one sweep and on the matching report_run call — it is what links a run to the files it protected." }, "agentClassification": { "type": "string", "required": false, "description": "What you judged about this file, recorded against the proof. Every field optional — send only what you actually determined, and never invent a verdict you did not reach." }, "review": { "type": "boolean", "required": false, "description": "true = do NOT protect it; stage it for a human to decide. No proof is written. Use when you cannot tell whether the file is evidence for the objective." }, "sourcePath": { "type": "string", "required": false, "description": "Where the file lives on the customer's machine. Only used with review=true, so the human can see what they are deciding about and the file is not staged again next sweep." } } } ```