Reference
Who can do what
The four roles, the exact capability each one has, and the places where people reasonably expect a capability they do not have.
One section of this article carries operator-only instructions. They are published so the whole picture is visible, and nobody outside Vara can act on them. They are marked where they appear: Operator only.
Every signed-in request is resolved to exactly one role before anything else happens. There is no "admin" and no super-user flag on top of a role. A route with no role gate is refused, and the service refuses to start at all if one is added without a gate, so there is no quiet third state where a page is neither public nor protected.
The roles
| Role | Who holds it | Where they work |
|---|---|---|
| Operator | Vara staff running the service | The management console, plus two maintenance endpoints nobody else can reach |
| Manager | The person running the association day to day | The management console. The same pages as the board, with the write controls enabled |
| Board | Elected board members | The management console, read only. Reading tickets, residents, vendors and documents |
| Resident | A verified owner | The resident portal only. Their own tickets and the association’s published documents |
A resident role is created by registering. The three staff roles are created by Vara, in the Vara console, and by nothing a manager, a board member or a resident can reach. A community cannot add its own staff.
Giving somebody a manager, board or operator role
Shipped, not configured- What people expect
- Add a manager or a board member to the association so they can sign in and use the management console.
- Why it does not work today
- A staff role comes from a member document held under the association, and until recently nothing in the service or its scripts ever wrote one: the service only read them, and the tenant seeder wrote the association and its settings documents and no member. That was a deadlock, because the provisioning API itself required an operator session and an operator session required one of those documents. An operator-gated route now writes them (`POST /internal/associations/{slug}/members`), it also accepts a Google-signed token from a service account, and the Vara admin console at `/admin/associations` has a form for it. What is still missing is a screen in the COMMUNITY's own console: a manager cannot add their own staff, so every addition goes through Vara. The console route for that does not exist yet.
- What to do instead
- Ask Vara to add the person; it is a form in the Vara console rather than a database edit. Residents are unaffected either way: registration creates a resident account, so the portal works whether or not a single staff member exists. Note that manager and board contact addresses are a different thing entirely and grant no sign-in access at all.
Checked against the code on 2026-09-09. Next review 2026-11-15.
A contact address is not a role
An association also holds manager and board contact addresses, which are where notifications go. They are not roles and they grant nothing: an address listed there can be emailed and still cannot sign in. Only a member record gives somebody a role, and “I added them as a manager” is the sentence people use for both.
Role is checked before ownership
A manager reaching a resident-only page is refused for being a manager, not for being the wrong resident. This matters when you are testing: signing in as staff and opening /portal will not show you what a resident sees. It will refuse you.
The pattern across the console is consistent: the board reads and the manager writes. Every exception below is a real exception in the code, not a simplification here.
| What | Who can | Route |
|---|---|---|
| Open the console | OperatorManagerBoardResident | GET /manage |
| Read the resident roster and the pending registration queue | OperatorManagerBoard | GET /manage/residents |
| Approve or reject a pending registration The board can see the queue and cannot decide it. | OperatorManagerBoard | POST /manage/residents/{key}/review |
| Read the ticket board and any single ticket | OperatorManagerBoard | GET /manage/tickets, GET /manage/tickets/{id} |
| Read internal notes on a ticket Enforced where the notes are read, not in the template, so there is no view that can accidentally show them to a resident. | OperatorManagerBoardResident | part of GET /manage/tickets/{id} |
| Write an internal note The board reads internal notes and cannot add one. | OperatorManagerBoard | POST /manage/tickets/{id}/notes |
| Comment on a ticket, visible to the resident The one write the board has on a ticket. A board member can reply to a resident. | OperatorManagerBoard | POST /manage/tickets/{id}/comments |
| Move a ticket to another state | OperatorManagerBoard | POST /manage/tickets/{id}/transition |
| Assign a ticket | OperatorManagerBoard | POST /manage/tickets/{id}/assign |
| Record a work order reference on a ticket Records a reference. It does not raise a work order. See the register entry on work orders. | OperatorManagerBoard | POST /manage/tickets/{id}/workorder |
| Read the vendor directory and one vendor record | OperatorManagerBoard | GET /manage/vendors, GET /manage/vendors/{id} |
| Create or edit a vendor, or change its status A vendor record holds where money is remitted, which this service treats as a management action rather than a governance one. | OperatorManagerBoard | POST /manage/vendors, POST /manage/vendors/{id}, POST /manage/vendors/{id}/status |
| Open the governing document library A resident who arrives here is redirected to the portal library rather than refused, because there is somewhere better to send them. | OperatorManagerBoard | GET /manage/settings/documents |
| Upload a governing document The gate admits the board. Whether the upload lands depends on the deployment naming its buckets: see the register entry on document storage. | OperatorManagerBoard | POST /manage/settings/documents |
| Publish a draft document | OperatorManagerBoard | POST /manage/settings/documents/{id}/publish |
| Mark a document superseded Wider than publish, and that asymmetry is in the code rather than in this table. If you expect the board to be refused here, they are not. | OperatorManagerBoard | POST /manage/settings/documents/{id}/supersede |
| Ask for a knowledge base rebuild The button refuses for everyone today: see the register entry on the knowledge base index. | OperatorManagerBoard | POST /manage/settings/kb/reindex |
Two places the board is wider than you would guess
A board member can comment on a ticket where the resident will see it, and can mark a governing document superseded. Both are real, both are checked against the code, and neither follows from "the board is read only". If that is not the policy you want, it is a change to the service and not to this page.
| What | Who can | Route |
|---|---|---|
| Open the portal | ResidentOperatorManagerBoard | GET /portal |
| See your own tickets and file a new one Filing is refused today until the association’s ticket categories are set up. | Resident | GET /portal/tickets, POST /portal/tickets |
| Open one of your tickets and comment on it Another resident’s ticket is a not-found, byte for byte the same as a ticket that does not exist. | Resident | GET /portal/tickets/{id}, POST /portal/tickets/{id}/comments |
| Read the association’s current governing documents Published, current versions only. Drafts and superseded versions cannot appear here. | Resident | GET /portal/documents |
| Download a document Works where the deployment names its document bucket, and refuses where it does not: see the register entry on document storage. | Resident | GET /portal/documents/{id}/download |
| Attach a photo or PDF to a ticket Note the roles: a board member cannot attach anything to a ticket. Whether it lands depends on the deployment naming its attachment bucket: see the register entry on attachments. | OperatorManagerResidentBoard | POST /tickets/{id}/attachments/sign and /complete |
What a resident can never see
Internal notes on a ticket, another resident’s ticket, another resident’s record, any draft or superseded document, and the management console. The first of those is enforced by storing internal notes somewhere the resident-facing code has no way to name, rather than by a filter somebody has to remember to apply.
Operator only
Operator onlyThis section is for Vara operators
These endpoints change or delete stored records. They are named here because the runbook is public, not because a manager, a board member or a resident can run them. If you are not a Vara operator, nothing in this section is available to you and there is no request you can make to reach it.
| What | Who can | Route |
|---|---|---|
| Run one retention enforcement pass Also reachable by the scheduler’s service account with a bearer token. Dry run by default; it reports counts by class and never a list of what it touched. | OperatorManagerBoardResident | POST /internal/enforce-retention |
| Refresh owner records from the county roster Also reachable by the scheduler’s service account. Applies by default, so pass the dry-run flag first if you want to see the shape of a change before making it. | OperatorManagerBoardResident | POST /internal/refresh-owner-records |
Both endpoints take a bearer token from the scheduler’s service account, and a request that carries one is judged on the token alone: it never falls back to a browser session, so a wrong or expired token is a refusal rather than an accidental success on somebody’s cookie.
What the two do with a caller who presents nothing at all is the same, which matters because a scheduler misconfigured to send no credential must fail loudly rather than record a successful run of a job that never happened.
A caller with no token and no session
| Endpoint | Answer | What a scheduler records |
|---|---|---|
| POST /internal/refresh-owner-records | 403, refused outright | A failure, which is what it is. |
| POST /internal/enforce-retention | 403, refused outright | A failure, which is what it is. |
- The association’s landing page.
- The board contact form, which sends a message to the management office.
- The sign-in page and the links that come out of it.
- The owner registration form, because the people who need it do not have accounts yet.
- A health endpoint, which reports configuration state and no association data.
Everything else requires a session, and every page behind a session requires a role. There is no page that is reachable by "anybody signed in".
Still stuck?
That is a fair place to be, and it is usually faster to ask than to keep reading. Your association's management office can tell you whether what you are hitting is a permission, a setup step or a fault. Say what you were trying to do and what the screen said. If it needs changing at the service level, they will bring Vara in.