Protected Storages
Some data has to be usable by a flow without being readable by the person building that flow. A protected storage keeps working for your users and stops handing its contents to the studio.
Building a flow and reading the data that flow touches used to be the same permission. To check your work you press simulate, and simulating shows you what came back: that is the whole point of it. For a tasks storage that is exactly right. For invoices, salaries or a case file it is not, because the developer wiring the reminder email has no business paging through every invoice in the company to do it.
Protecting a storage separates those two things. The flow keeps working, end to end, for the people it was built for. The contents stop arriving on the developer's screen.
What Protection Actually Does
When a protected storage is read by a developer, the documents still come back, but only as outlines: the identity and the timestamps that make a flow work, and a marker saying the content was withheld. Nothing else. The marker matters more than it sounds: without it, a withheld document and a document that does not exist look identical, and a flow cannot tell "the customer has no invoices" from "you are not allowed to see them".
Totals and groupings return nothing at all. There is no point withholding the amount on every invoice and then answering "what is the sum of the amounts", or hiding the customer name and answering "count these by customer". Anything that summarises a protected storage comes back empty for the same reader the outlines are for.
What still works
Selecting the storage on a block, wiring it, writing to it, reading its field definitions, and running the whole flow. Every document the storage holds is still delivered in full to the user whose flow it is. Protection changes what the builder sees, not what the application does.
What is withheld
Document contents in a studio run, the studio console output of any run that touched the storage, and every total, average or grouping over it. You get the shape of the answer and never the values inside it.
Who Sees the Real Documents
The rule is about who is at the screen, not which blocks are on the canvas. A run started from the studio is a developer looking at output; a run started by a user is an application doing its job.
| Who is running the flow | What they get back |
|---|---|
| A developer pressing simulate | Outlines |
| A developer simulating as another user | Outlines. Simulating as somebody else does not move the screen. |
| A developer starting a production run from the studio | Outlines. Same developer, same screen, same answer. |
| A user calling your endpoint or opening your page | The real documents |
| A scheduled run, a storage event or a queued job | The real documents |
| A cluster admin | The real documents |
| Anyone holding the protected read scope | The real documents |
The last two rows are the deliberate exemptions. A cluster admin already administers the cluster the data sits on, so withholding it from them would be theatre rather than protection. The scope exists so that one person can be given the exemption for an afternoon of debugging without being made an administrator of everything else.
The Protection Follows the Data, Not the Screen
A mask that only covers the obvious read is worth very little, because the developer it excludes is by definition someone who can write blocks. Four things close the routes around it.
| The way around it | What happens instead |
|---|---|
| Read the invoice, then log it to the console | A run that touched a protected storage has its console output withheld for the rest of that run. The flow still runs and still logs; the studio just does not print it. |
| Read the change history instead of the document | Revision history inherits the protection of the storage it is the history of. A protected storage has a protected history, which is the only sensible reading: a revision holds the values before and after, so an unprotected history is the document twice over. |
| Push the documents through the queue and read them out of the job | The mark travels with the job. The flow that read the invoice and the worker that processes it are two separate runs, so the tag is carried across the boundary and re-applied to whatever waits on the result. |
| Refer to the storage by a different spelling of its name | Nothing changes. The flag is attached to the data, not to one way of writing its name, so capitalisation and punctuation in the name make no difference to what is protected. |
One more rule sits underneath all of these: when the platform cannot determine whether a storage is protected, it treats it as protected. A lookup that fails withholds the data. The cost of being wrong in that direction is a developer waiting a few seconds; the cost of being wrong in the other direction is the invoices.
Turning It On
Only a cluster admin can protect a storage or unprotect it, and that is a deliberate narrowing rather than an oversight. The permission that governs the other storage settings is exactly the permission the excluded developers already hold, so it could not be the permission that guards this one: anyone able to turn it on would be able to turn it off again the moment it got in their way.
The switch lives on the storage itself, next to its other options in RUAL Studio, and takes effect within seconds. There is no migration, no reindex and no downtime: the documents do not move, only what is handed back changes. Turning it off again is just as immediate, which makes it safe to try on a copy first.
Building Against a Protected Storage
You are building blind on values, not on structure, so the working method shifts a little.
| Instead of | Do this |
|---|---|
| Reading real rows to learn the document shape | Read the field definitions. They are the schema and they are not the data, so they stay fully visible. |
| Simulating against production data | Keep an unprotected storage of invented rows with the same fields, and point the storage block at it while you build. Switch it over when the flow is right. |
| Checking a value to see whether the read worked | Check the flow. A read that found a document continues down the found path and carries the withheld marker; a read that found nothing does not. |
| Adding a total to the console to sanity check an aggregation | Build the aggregation against the test storage. Over a protected storage it is empty by design, and that is not a bug you can debug your way out of. |
| Asking for the protection to be lifted permanently | Ask a cluster admin to run it once and tell you what came back, or to hand you the exemption scope for the session. Both leave a trail; a permanently unprotected storage does not. |
What It Is Not
Protection is one specific thing, and reading it as more than that is how people end up surprised.
- It is not a permission system for your own application. If you write an endpoint that returns every invoice to anyone who calls it, protection will not stop it: your user's run is exactly the run that gets the real documents. Endpoint access is still yours to control with scopes and rate limits.
- It is not encryption. It governs what the platform hands to a reader. It is a decision about who receives data, not a transformation of the data at rest.
- It is not a hidden storage. Developers still see the storage exists, what fields it has and how many documents it holds. That is what lets them build against it at all.
- It does not stop writes. A flow can still create and update documents in a protected storage. Withholding what an update returns would break the update itself, so what comes back afterwards is masked, not the write.
Which Storages Deserve It
The useful test: would you export this storage to a spreadsheet and email it to the person building the flow? If the answer is no, protect it.
| Storage | Protect | Why |
|---|---|---|
| Invoices, orders, payments | Yes | Commercially sensitive in aggregate even when no single row is dramatic. The totals are usually the part you least want browsed. |
| Salaries, contracts, HR records | Yes | The classic case where a colleague building the flow is specifically the person who should not read it. |
| Medical, case or client notes | Yes | Usually covered by an agreement that names who may see the contents. A build permission is not that name. |
| Identity documents, bank details | Yes | Nothing about developing a flow requires seeing them once. |
| Products, pages, settings, tasks | No | Reading them is how you build against them, and there is nothing to withhold. |
| Anything you are still designing | Not yet | Protect it once the shape is settled. Designing a document you cannot see is unnecessarily hard. |
Next Steps
Storages
The document model this sits on: _meta, mutations, queries and the document lifecycle.
Service Providers
Keys and tokens for external services, held by the cluster instead of by the blueprint.
User Roles Explained
Which role holds which scope, and what a cluster admin may do that a developer may not.
Frequently asked
How do I stop developers reading a storage in RUAL?
Mark the storage as protected against developer read. A cluster admin sets it on the storage itself. After that a run started from the studio gets each document as an outline: its identity, its timestamps and a marker saying the content was withheld. Runs started by your users, by a schedule, by a storage event or by the queue keep receiving the real documents.
Does a protected RUAL storage still work for end users?
Yes. Protection changes what the person building the flow sees, not what the application does. A user opening a page or calling an endpoint receives the full documents, and flows can still create and update documents in a protected storage.
Why does an aggregation over a protected RUAL storage return nothing?
By design. Withholding the amount on every invoice and then answering a question about the sum of the amounts would hand over exactly what the outline withholds, so totals, averages and groupings come back empty for the same reader. Build aggregations against an unprotected test storage.
Who can read a protected storage in RUAL?
The user whose own run it is, any scheduled or queued run, a cluster admin, and anyone holding the protected read scope. That scope exists so one person can be given the exemption for a debugging session without being made an administrator of everything else.
