Platform access for tool servers
How a tool server reads and writes platform files, and the boundaries that contain it
Overview
Tools need platform data. An email tool has to read the attachment your workflow passed it. A document tool has to save the file it produced so the next node can use it.
A tool server never connects to the platform database or object storage. It asks the platform over an internal API, authenticated with its own service token.
This page explains what a tool server can reach, so you can reason about what a tool you connect is able to see.
This is a security and architecture topic rather than a configuration one. There is nothing to set up here. Read it when you are evaluating a tool, writing a security review, or debugging why a tool cannot see a file.
Why it works this way
Before these internal routes existed, every tool server that touched files held the platform's database URL and object-storage credentials directly.
Compromising one tool server therefore exposed every tenant's data. Now a compromised server can reach only what the internal routes allow it, which is the subject of the rest of this page.
What a tool server can do
| Capability | Boundary |
|---|---|
| Read a platform file by its ID | Only in the project the platform named for the call |
| Register a file it produced | Same project, and the file type must be one MagOneAI accepts |
| Write back a rotated credential | Only for the connection the call belongs to |
| Sync a knowledge base | Only in the named project |
The project is named by the platform, not the tool
This is the most important rule.
The project comes from a header the platform sets on the tool call. It never comes from a tool argument, so a model cannot talk a tool into naming a different project.
MagOneAI then validates that claim:
- The project must exist and be active. A deleted project is not found.
- An organization-scoped token reaches only projects in its own organization.
- A file must belong to the named project.
Anything inaccessible returns not found rather than forbidden, so a tool server cannot probe for which projects or files exist.
The project is claimed and validated, not proven. The platform names the project and the server echoes it back, so a server holding the global service token could name a project it was not called for. The validation closes the case where a model or tool argument controls the ID; it cannot stop a compromised server that lies.
An organization-scoped token narrows this to a single organization. Treat the global service token as a high-trust credential.
Private agent files need a grant
Some files are private to the person whose agent produced them, rather than visible across the project. A tool server carries no user identity, so it cannot be trusted to decide whether it may read one.
MagOneAI issues a short-lived grant instead.
The platform scans the tool call for file IDs
Every file ID anywhere in the validated arguments: at any depth, inside strings, and in keys. A workflow Tool node can pass a list as JSON text, so the scan cannot take shortcuts. An ID it missed would be an ID the refusal below also missed.
It works out which of those are private
For files private to the caller, a grant is created for the duration of the call.
A file private to someone else refuses the call
The message says a file named in the call is not accessible. It does not name the file.
Without this refusal, another project member could name someone's private file while its owner's call was running and read it through the grant.
The grant is released when the call ends
On success, on failure, and on cancellation.
Parallel calls on the same file share one grant and each holds a reference, so a call that finishes first never pulls the file out from under one still running.
If MagOneAI cannot check whether a file is private, the tool call is refused rather than allowed. An unchecked call could otherwise ride another user's grant.
The opposite is true for the grant store itself: a failure there never fails a tool call and never turns a read into an error. It simply means no grant, so a private file reads as not found.
Files a tool registers
A file a tool produces goes through the same type check as a file a person uploads.
This matters because a registered file is served inline from MagOneAI's own origin. An HTML or SVG file registered through this route would be a script running on that origin, which is why the check is not optional here.
Size is capped by the platform's per-file limit. A content type MagOneAI does not recognise as a plain type is stored and served as a generic binary rather than being trusted.
Document exports are deliberately not type-gated the same way, because HTML is a documented output format for rendering a document, and an export is not a file row in the first place.
What this means when you connect a tool
Connecting a tool in one project does not give it visibility into another.
It reads a private file only for the duration of a call made by that file's owner.
An organization-scoped token cannot reach outside its organization at all. Prefer it where the tool does not need to be platform-wide.
It has no database credentials and no object-storage credentials. Every request goes through the internal API, which applies the rules above.
Troubleshooting
Cause: The call named a file that is private to another person.
Fix: Have the file's owner run the workflow, or produce a project-visible file instead of a private one. The message deliberately does not name the file.
Cause: MagOneAI could not determine which files in the call are private, so it refused rather than risking a call riding someone else's grant.
Fix: This is usually transient. Retry, and report it if it persists.
Causes to check, in order:
- The file belongs to a different project from the one the workflow is in.
- The file is private to someone else, so it reads as not found.
- The file was deleted. Inactive rows never resolve.
- The connection is organization-scoped and the project is in another organization.
Causes to check: the file type is not one MagOneAI accepts for upload, or the file is over the platform's size limit.
Cause: The tool server image is newer than the platform and is calling a route this platform does not serve yet.
Fix: Update the platform first. This is the intended deploy order, and the clear error exists so the mismatch is obvious.