Permissions & consent
The tier model — baseline, consent, admin, admin-HIGH — and how each is granted.
files.read notifications data.storefiles.read.all network.fetchworker.executenetwork.fetch.broadNew to coding? Start here. This page explains why HanabiMatsuri modules ask for permissions, what each kind means in everyday terms, and why one module can never quietly read another module's files — or your whole Desktop — without you saying yes.
You don't need to know how any of it is implemented to read this. If you later want the exact, complete list, two pages have it: capability-api.md (every capability + the official tier table) and manifest-reference.md (the manifest fields).
What is a "module"? #
A module is a tiny app that runs inside HanabiMatsuri, in its own window. It could be a file converter, a note-taker, a calendar — anything. Because modules can come from other people, the platform treats every one of them as a polite guest, not a trusted roommate: a guest can do useful things, but only the things you've agreed to.
Why permissions exist at all #
Think of your HanabiMatsuri account as your house. A module is a guest you've let in to do one job. You'd happily let a guest tidy the desk you pointed them at. You would not hand every guest a master key to every room, your filing cabinet, and the phone to call anyone they like.
Permissions are how a module says, up front, exactly what it needs — and how you stay in control of granting it. A module has to declare what it wants in a small text file (its manifest). Nothing it didn't ask for is even possible.
So permissions are good news for you:
- You can see what a module wants before it can do anything.
- A module that only needs to read the files you hand it can't suddenly start reaching across your whole computer.
- If a module misbehaves, the damage is fenced in to what you allowed.
The four permission tiers (with everyday examples) #
Every capability a module can ask for sits in one of four tiers. The tier decides how hard it is to get — from "on automatically" to "an administrator has to sign off and set a budget." Here they are, simplest to strictest.
1. baseline — "your own notebook"
On the moment you install the module. No prompt.
These are the harmless, self-contained things a module needs to be useful inside its own space. Like giving a guest their own blank notebook: they can scribble in it all they like, and it never touches anything of yours.
Baseline covers things like: read and write files in the module's own folders, run a quick background job, remember its own settings, show you a notification, and check how much storage you have left.
2. consent — "asking to look in a drawer"
Off until you say yes once. The platform shows you a prompt.
Sometimes a module needs a bit more than its own desk — for example, the ability to open a file from anywhere in your workspace (your Documents, your Downloads), because that's the whole point of, say, a "universal file viewer." That's bigger than baseline, so the module can't just take it. It has to ask you, and you either allow it or you don't.
3. admin — "a manager signs off"
Off until an administrator reviews and approves the module when it's published.
A few capabilities are powerful enough that one regular user shouldn't be the only gate — like letting the module reach out to the internet, or run code on the server. For these, an administrator reviews the module before it's allowed into the Module Store. If the module later changes that powerful part, it gets reviewed again.
4. admin-HIGH — "the manager signs off AND sets a budget"
*Off by default for every module. An admin must enable it for that one module and set a quota (a limit/budget).*
The heaviest capabilities — running native tools on the server, a long-lived background service, downloading from any site on the internet — need the most care. It's not enough for an admin to say "approved." The admin has to switch the capability on for that specific module and set a budget (how much it may use). Off unless both happen.
Tiers at a glance
| Tier | Who grants it | When | Everyday picture |
|---|---|---|---|
| baseline | nobody — it's automatic | the moment you install | your own notebook & desk |
| consentA one-time prompt the user approves to allow an elevated permission like files.read.all. | you | a one-time prompt | "may I look in that drawer?" |
| admin | an administrator | when the module is published | a manager signs off |
| admin-HIGH | an administrator | published + turned on per-module + given a budget | the manager signs off and sets a budget |
The official, authoritative tier list lives in the platform's capability registry; the human-readable copy is the table in capability-api.md.
The three-check model: declared → granted → scoped #
Here's the part that makes the whole thing trustworthy. Before a module is allowed to do anything, three separate things must all be true. Miss any one and the action is refused.
- Declared — the module wrote down that it wants this, in its manifest. If it's not on the list, the answer is always no. (You can read the list before installing.)
- Granted — somebody actually said yes: it was automatic (baseline), you consented, or an admin approved it. Declaring a wish isn't the same as getting it.
- ScopedClamped to your own Modules/<Name>/ folders for the current user — never another module or user. — even once granted, a file action is clamped to the module's own folders (
Modules/<That Module's Name>/…). It can't name a file that belongs to a different module, or to a different user. "Broad" access outside its own folders is itself a separate, consent-gated permission — and even that never reaches another module's private folders.
What the module What a person What it's wrote down agreed to allowed to touch ────────────── ────────────── ──────────────── 1. DECLARED ─────▶ 2. GRANTED ─────▶ 3. SCOPED "I want files.read" install / consent / only THIS module's in the manifest admin approval own folders All three must hold. Drop any one ✗ → the request is refused.
You'll feel this model the first time something is denied: the platform replies with a short, stable error code instead of a vague failure — for example HANABI-P001 ("permission not declared"), HANABI-P003 ("user consent required"), or HANABI-F002 ("file outside module scope"). Each code is listed with a plain-English fix in error-codes.md, and the developer debugger shows it to you. A denial is the system working, not a bug.
"Why can't my module see another module's files — or my Desktop?" #
This is the question every beginner asks, and the answer is the whole point of the design.
- Another module's files — Every module gets its own folders, under
Modules/<Its Name>/. The third check above (scopedClamped to your own Modules/<Name>/ folders for the current user — never another module or user.) means a file request is only ever honored for the module's own folders. A note-taking module literally cannot name a file that lives in the photo-editor's folder. There's no permission that hands one module another module's private space — not even the broad ones. - Your Desktop / Documents / Downloads — A module starts out able to touch only its own folders, never your wider workspace. Reaching out to the rest of your files is the consentA one-time prompt the user approves to allow an elevated permission like files.read.all.-tier
files.read.all— so the module has to ask, and you have to say yes, before it can open anything out there. And even with that yes, it still can't cross into another module's folders.
In short: a module is sandboxed to its own corner by default. Getting out of that corner always requires an explicit yes (consent), and some corners — other modules' folders — are simply never shared.
Which everyday task needs which permission? #
A quick lookup. "Tier" tells you who has to say yes (see the four tiers above). The permission name is what a developer writes in the manifest's permissions list.
| If a module wants to… | It needs | Tier |
|---|---|---|
| Read a file you picked from its own Imports folder | files.read | baseline |
| Save a result into its own Exports folder | files.write | baseline |
| Organize its own folders — make subfolders, rename/move/delete its files | files.manage | baseline |
| Remember its own settings (your theme, last choice) | settings.self | baseline |
| Pop up a notification or set a badge on its icon | notifications | baseline |
| See how much storage you have left | storage.read | baseline |
| Keep its own little database of notes/records | data.store | baseline |
| Run a quick background job / queue a longer one | jobs.create / jobs.queue | baseline |
| Discover & hand a file to another installed module | modules.use (+ files.read) | baseline |
| Open a file from anywhere in your workspace | files.read.all | consentA one-time prompt the user approves to allow an elevated permission like files.read.all. |
| Look at what's on your Desktop | desktop.read | consentA one-time prompt the user approves to allow an elevated permission like files.read.all. |
| Put its files/folders onto your Desktop | desktop.workspace | consentA one-time prompt the user approves to allow an elevated permission like files.read.all. |
| Pin a launcher/shortcut on your Desktop | desktop.shortcuts | consentA one-time prompt the user approves to allow an elevated permission like files.read.all. |
| Change your wallpaper / accent / light-dark theme | desktop.personalize | consentA one-time prompt the user approves to allow an elevated permission like files.read.all. |
| Use richer browser features (WebGL, fullscreen, gamepad…) | client.webgl / client.fullscreen / … | consentA one-time prompt the user approves to allow an elevated permission like files.read.all. |
| Reach out to the internet (specific, declared sites) | network.fetch | admin |
| Run its server-side code to do heavy work | worker.execute | admin |
| Run on a schedule even while its window is closed | jobs.schedule | admin |
| Use native power tools (video/image processing) on the server | worker.native | admin-HIGH |
| Download from any site on the internet | network.fetch.broad | admin-HIGH |
| Run a always-on background service | worker.service | admin-HIGH |
This is a friendly subset. The complete list — every permission, exactly what it grants, and its tier — is in capability-api.md, and the manifest field that carries them is documented in manifest-reference.md.
The one-paragraph version #
A module can only do what it declared it wants, only after someone granted it (you, automatically, or an admin — depending on the tier), and file actions are always scopedClamped to your own Modules/<Name>/ folders for the current user — never another module or user. to the module's own folders. Baseline is automatic and harmless; consent asks you once; admin needs a reviewer; admin-HIGH needs a reviewer who also sets a budget. That's why a module can't read another module's files or your Desktop without an explicit yes — and why, when something is refused, you get a clear error code instead of a surprise.
Where to go next #
hello-module-tutorial.md— build your first module in about 15 minutes and seefiles.readin action.capability-api.md— the full capability list, the tier table, and how a module actually talks to the platform.manifest-reference.md— every field ofhanabi.module.json, includingpermissions.error-codes.md— what eachHANABI-…code means and how to fix it.