Permissions
Access & Tags decides which apps a person can open. Permissions go a level deeper: they decide who can see and change individual records — so you can share one recipe with a housemate, keep a person's medical notes to themselves, or let only the adults edit the finances.
A fresh household starts closed: a new account can see nothing until you give it an access level. You do that when you create the person — the create-user form asks for one and defaults to Member, which is read and write across the household — so in practice setup is one dropdown, not a chore. Nothing is shared by accident, and there is no hidden rule to remember to delete later.
This page covers
- The three building blocks
- Where access comes from
- Restrict one person
- Share one record with one person
- Give a group access
- Block someone
- What to expect
- Reference notes
The three building blocks
- Grant — one rule: who can do what to which data. "Bob can read gift-card #42." Everything below is built from grants.
- Group — a named set of people, like
ParentsorGuests. Grant access to a group and it applies to everyone in it. - Role — a named bundle of abilities you hand to a group, like
member(read and write everything) orguest(nothing until you share it). Three roles come built in:admin,member, andguest.
A rule grants one of three abilities, each including the ones before it:
| Ability | Lets you… |
|---|---|
| read | view a record |
| write | create, edit, and delete |
| manage | everything, plus share it with others |
Where access comes from (this is the important part)
Nothing is granted by default. A household is seeded with roles and the groups that confer them (Admins / Members / Guests) — but with no grants at all. In plain terms:
A person can do nothing until you give them a role. Their access is then exactly what that role allows, and nothing more.
A role reaches a person through a group: joining a group confers that group's role. So:
- Someone with no group → no access. They can sign in, and see nothing.
- Someone in a role-group → exactly what the role grants.
Membersis read and write across the household,Adminsadds the ability to grant others access,Guestsgrants nothing until you share something specific. - Their own records → always theirs. Whoever creates a record can always read and change it, no grant required.
- Superusers → everything, always (break-glass) — you can't lock yourself out.
This is what lets one household have full-access adults and a limited guest at the same time: the adults are Members or Admins, the guest is defined by their group's role or by the individual records you share with them.
Earlier versions seeded an open-household grant (everyone can read and write everything) so that upgrading changed nothing. That grant is gone. On upgrade, a one-shot migration moves everyone who was relying on it into the
Membersgroup first, so nobody loses access — what changes is that the next account you create starts with nothing instead of everything.
Restrict one person (the common case)
Say the household is mostly Members, but you want mom limited to Pictionary. You give mom a role of her own, via a group:
# A role that grants just the Pictionary app…
homestead resources role create --name "Pictionary" \
--grants '[{"target_scope":"app","target_app":"pictionary","capability":"write"}]'
# …a group that confers it, with mom in it.
homestead resources group create --name "Pictionary" --role <pictionary-role-id>
homestead resources group-membership create --group <group-id> --user <mom-id>That's it — mom now sees only Pictionary, and everyone else is unaffected. Open Superuser → Users → Edit on mom to confirm: her access summary will read "Can open 1 app: Pictionary." If mom was already in another role-group, remove her from it — access is the union of every role she holds.
Share one record with one person
Rules live in the access-grant collection. You manage them from the command line with homestead resources (a management UI is on the way).
To let Bob read gift-card gc_42:
homestead resources access-grant create \
--subject_type user --subject_id bob \
--target_scope record --resource_type gift-card --resource_id gc_42 \
--capability readBob can now open that one gift card — and only that one. To stop sharing, delete the rule:
homestead resources access-grant list # find the rule's id
homestead resources access-grant delete <id>You can share a record you own or manage even without being an admin — that's how sharing your own things works.
Give a group access
Groups save you from repeating yourself. Make a group, add people, then grant the group access once.
# 1. Make the group
homestead resources group create --name Parents --id parents
# 2. Add people (optionally handing them a role while they're in it)
homestead resources group-membership create --group parents \
--user alice --role member
homestead resources group-membership create --group parents --user bob
# 3. Grant the group access — here, read + write to all recipes
homestead resources access-grant create \
--subject_type group --subject_id parents \
--target_scope collection --resource_type recipe \
--capability writeUse --target_scope app with --target_app <app> to cover a whole app at once, or --target_scope all for everything.
Block someone
A deny rule removes access, and a deny always wins — it beats every grant, including someone's ownership of their own record. This is how you carve one exception out of an otherwise-open household.
To keep a teen out of the finances app while everyone else keeps it:
homestead resources access-grant create \
--subject_type user --subject_id teen \
--target_scope app --target_app credit-cards \
--capability read --effect denyWhat to expect
A few rules of thumb make the whole system predictable:
- Owners keep their own. Whoever creates a record can always read, edit, and share it — unless a deny rule names them.
- Superusers see everything. The main account is never locked out, so you always have a way back in. (Regular admins — people with the
adminrole — can be blocked by a deny.) - A deny always wins. If any rule denies access, access is denied, no matter how many grants say otherwise.
- Nothing is shared until you say so. A new account has no access; you grant it by giving them a role, and widen from there.
- Rules apply everywhere. Enforcement is on the server, so it covers the API, the AI assistant, and the CLI — not only the web UI.
Reference notes
- Roles ride on groups. In this version you give someone a role by adding them to a group with that role, not by assigning it to them directly.
- The rules themselves are visible to the household. Anyone signed in can read the grants, groups, and roles (only superusers and a record's owner can change them). This is intentional — it keeps the household transparent about who can do what, and the apps need it to show you the right screens. One consequence: a deny rule is discoverable, so "who is blocked from the finances app" isn't a secret. Permissions control access to your data, not knowledge of the rules — if you need someone's very existence in a rule kept private, this isn't the tool for that.
- Changes are near-instant. New rules take effect within a few seconds (there's a short cache), no restart needed.
- Private collections. A few collections are covered by the household roles only for your own records — the Documents app, whose point is per-folder sharing. Nothing is marked on the resource itself: the roles simply don't hand out everyone else's rows. You can still add records there, and you always see what you created.
- What shows in the sidebar. An app appears when you can reach any of its records. For a private collection that means you actually have one — upload your first document and Documents appears; delete your last and it goes.
- Apps with nothing to store. A few apps (like Chat) hold no records of their own, so there is nothing to check. Those are granted per app, and the built-in roles include them — which is why a Guest, granted nothing, doesn't see Chat. Settings is the exception: it manages your own preferences, so everyone signed in can reach it.
- Filters. A rule can target records by a condition instead of a fixed id — for example "recipes you created" (
created_by == subject.id). Same expression language as list filters. - Permissions vs. tags. Tags decide which apps a person can open; permissions decide who can see and change the records inside them. Use tags for whole apps, permissions for specific data.